Windows消息循環

  1 #include <Windows.h>
  2 #include <tchar.h>
  3 #include "resource.h"
  4 
  5 #define MAX_LOADSTRING 100
  6 TCHAR szTitle[MAX_LOADSTRING] = _T("標題欄");     // 標題欄文本
  7 TCHAR szWindowClass[MAX_LOADSTRING] = _T("MyClass");   // 主窗口類名
  8 
  9 
 10 ATOM ToRegisterClass(HINSTANCE hInstance, int nShowCmd);//註冊窗口類
 11 HWND ToCreateWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD dwStyle,int x, int y, int nWidth,int nHeight, HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam);//創建窗口
 12 BOOL ToShowWindow(HWND hWnd, int nCmdShow);//顯示窗口
 13 BOOL ToUpdateWindow(HWND hWnd);//更新窗口
 14 WPARAM ToRecycleMessage(MSG msg);//消息循環
 15 LRESULT CALLBACK ToWndProc(HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam);//窗口過程
 16 
 17  //——————————————————————————進入WinMain函數————————————————————————————
 18 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
 19 {
 20  //————————————————————————————第一步:設計並註冊窗口類————————————————————————————
 21  ToRegisterClass(hInstance, nShowCmd);//當前實例句柄,窗口顯示方式
 22 
 23  //————————————————————————————第二步:創建窗口————————————————————————————
 24  HWND hWnd = ToCreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
 25  
 26  //————————————————————————————第三步:顯示窗口————————————————————————————
 27  ToShowWindow(hWnd, nShowCmd);
 28 
 29  //————————————————————————————第四步:更新窗口————————————————————————————
 30  ToUpdateWindow(hWnd);
 31 
 32  //————————————————————————————第五步:消息循環————————————————————————————
 33  MSG msg;
 34  return ToRecycleMessage(&msg);//MSG結構的wParam成員的值是傳遞給PostQuitMessage函數參數,通常是0。
 35 }
 36 
 37 ATOM ToRegisterClass(HINSTANCE hInstance, int nShowCmd)
 38 {
 39  WNDCLASS lpWndClass;
 40  lpWndClass.cbClsExtra = 0;//窗口類無擴展
 41  lpWndClass.cbWndExtra = 0;//窗口實例無擴展
 42  lpWndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//背景
 43  lpWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);//鼠標
 44  lpWndClass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDB_PNG1));//圖標
 45  lpWndClass.hInstance = hInstance;
 46  lpWndClass.lpfnWndProc = ToWndProc;//窗口函數
 47  lpWndClass.lpszClassName = szWindowClass;//窗口類名
 48  lpWndClass.lpszMenuName = NULL;//菜單名
 49  lpWndClass.style = CS_HREDRAW | CS_VREDRAW;//風格
 50  return RegisterClass(&lpWndClass);
 51 }
 52 
 53 HWND ToCreateWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD dwStyle,int x, int y, int nWidth,int nHeight, HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam)
 54 {
 55  return CreateWindow(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
 56 }
 57 
 58 BOOL ToShowWindow(HWND hWnd, int nCmdShow)
 59 {
 60  return ShowWindow(hWnd, nCmdShow);
 61 }
 62 
 63 BOOL ToUpdateWindow(HWND hWnd)
 64 {
 65  return UpdateWindow(hWnd);//   調用UpdateWindow函數會通過發送給窗口消息處理函數WndProc一個WM_PAINT消息,通過這個消息完成重繪顯示區域的工作。
 66 }
 67 
 68 WPARAM ToRecycleMessage(MSG *msg)
 69 {
 70  int nRet;
 71  while(nRet = GetMessage(msg, NULL, 0, 0) != 0)//收到WM_QUIT消息則跳出消息循環
 72  {
 73   if (nRet == -1)
 74   {
 75    return;
 76   }
 77   TranslateMessage(msg);//翻譯消息
 78   DispatchMessage(msg);//分發消息
 79  }
 80  return msg->wParam;
 81 }
 82 
 83 //窗口過程函數:處理窗口消息
 84 LRESULT CALLBACK ToWndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
 85 {
 86  DWORD dwNum = 0;
 87  wchar_t * pwSrc;
 88  RECT rect;
 89  PAINTSTRUCT ps;//創建繪製對象結構
 90  HDC hdc = NULL;//創建設備描述句柄對象
 91  static HWND hwndButton[3] = {NULL,NULL,NULL};
 92  switch(uMsg)
 93  {
 94  case WM_COMMAND://處理按鈕等發出的消息
 95   break;
 96  case WM_CHAR://處理鍵盤發出的消息
 97   break;
 98  case WM_CLOSE://關閉窗口消息
 99   if (IDYES == MessageBox(hWnd, _T("結束?"), _T("提示"), MB_YESNO))
100   {
101    DestroyWindow(hWnd);
102   }
103   break;
104  case WM_DESTROY://處理WM_DESTROY消息必須調用PostQuitMessage函數,該函數向消息隊列中發送WM_QUIT消息,讓程序退出消息循環。
105   PostQuitMessage(0);
106   break;
107  default:
108   return DefWindowProc(hWnd, uMsg, wParam, lParam);//默認的窗口處理函數
109   break;
110  }
111  return 0;
112 }
113 
114  

 

 1 HWND CreateWindow(      
 2 
 3     LPCTSTR lpClassName,//註冊的窗口類型名稱。
 4     LPCTSTR lpWindowName,//窗口名稱
 5     DWORD dwStyle,//窗口類型
 6     int x,//窗口左上角位置
 7     int y,//窗口左上角位置
 8     int nWidth,//窗口的寬度
 9     int nHeight,//窗口的高度
10     HWND hWndParent,//父窗口
11     HMENU hMenu,//窗口菜單
12     HINSTANCE hInstance,//應用程序實例句柄
13     LPVOID lpParam//傳送給窗口的自定義參數
14 );

 

 1 BOOL GetMessage(         
 2     LPMSG lpMsg,//從線程消息隊列裏獲取到的消息指針
 3     HWND hWnd,//想獲取那個窗口的消息,當設置爲NULL時是獲取所有窗口的消息。
 4     UINT wMsgFilterMin,//獲取消息的ID編號最小值,如果小於這個值就不獲取回來。
 5 
 6     UINT wMsgFilterMax//獲取消息的ID編號最大值,如果大於這個值就不獲取回來。
 7 );
 8 
 9 //一般情況下最後兩個參數都設置爲0,表示所有消息
10 
11      函數返回值可能是0,大於0,或者等於-1。如果成功獲取一條非WM_QUIT消息時,就返回大於0的值;如果獲取WM_QUIT消息時,就返回值0值。如果出錯就返回-1的值。

 

nCmd:窗口顯示方式,參數如下:

 1 SW_FORCEMINIMIZE  是強制窗口最小化,主要使用在非窗口主線程的其它線程來操作。
 2 SW_HIDE  是顯示窗口爲隱藏狀態。
 3 SW_MAXIMIZE  是顯示窗口爲最大化。
 4 SW_MINIMIZE  是顯示窗口爲最小化。
 5 SW_RESTORE  是從任務裏恢復窗口顯示。
 6 SW_SHOW  是激活窗口爲當前窗口,並且顯示爲當前的大小和位置。
 7 SW_SHOWDEFAULT  是創建進程時顯示窗口的值。
 8 SW_SHOWMAXIMIZED  是激活窗口爲當前窗口,並且顯示最大化。
 9 SW_SHOWMINIMIZED  是激活窗口爲當前窗口,並且顯示最小化。
10 SW_SHOWMINNOACTIVE  是顯示窗口爲最小化,但不激活它作爲當前窗口。
11 SW_SHOWNA  是顯示爲當前的大小和位置,但不激活它作爲當前窗口。
12 SW_SHOWNOACTIVATE  是顯示當前窗口,但不激活它作爲當前窗口。
13 SW_SHOWNORMAL  是顯示當前窗口,但窗口是最小化或最大化時會恢復窗口爲原來的大小和位置。

 

 

TranslateMessage:

   用來把虛擬鍵消息轉換爲字符消息。由於Windows對所有鍵盤編碼都是採用虛擬鍵的定義,這樣當按鍵按下時,並不得字符消息,需要鍵盤映射轉換爲字符的消息。
  TranslateMessage函數用於將虛擬鍵消息轉換爲字符消息。字符消息被投遞到調用線程的消息隊列中,當下一次調用GetMessage函數時被取出。當我們敲擊鍵盤上的某個字符鍵時,系統將產生WM_KEYDOWNWM_KEYUP消息。這兩個消息的附加參數(wParamlParam)包含的是虛擬鍵代碼和掃描碼等信息,而我們在程序中往往需要得到某個字符的ASCII碼,TranslateMessage這個函數就可以將WM_KEYDOWNWM_ KEYUP消息的組合轉換爲一條WM_CHAR消息(該消息的wParam附加參數包含了字符的ASCII碼),並將轉換後的新消息投遞到調用線程的消息隊列中。注意,TranslateMessage函數並不會修改原有的消息,它只是產生新的消息並投遞到消息隊列中。
  也就是說TranslateMessage會發現消息裏是否有字符鍵的消息,如果有字符鍵的消息,就會產生WM_CHAR消息,如果沒有就會產生什麼消息。

 

 

PostQuitMessage:

  nExitCode是退出標識碼,它被放到WM_QUIT消息的參數wParam裏。

  VOID  PostQuitMessage(int nExitCode);

  當點擊窗口右上角的關閉時,Windows就會把窗口從系統裏刪除,這時就會發出消息WM_DESTROY給窗口消息處理函數WindowProcWindowProc收到這條消息後,最需要做的一件事情就是調用PostQuitMessage發出退出消息,讓消息循環結束。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章