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_KEYDOWN和WM_KEYUP消息。這兩個消息的附加參數(wParam和lParam)包含的是虛擬鍵代碼和掃描碼等信息,而我們在程序中往往需要得到某個字符的ASCII碼,TranslateMessage這個函數就可以將WM_KEYDOWN和WM_ KEYUP消息的組合轉換爲一條WM_CHAR消息(該消息的wParam附加參數包含了字符的ASCII碼),並將轉換後的新消息投遞到調用線程的消息隊列中。注意,TranslateMessage函數並不會修改原有的消息,它只是產生新的消息並投遞到消息隊列中。
也就是說TranslateMessage會發現消息裏是否有字符鍵的消息,如果有字符鍵的消息,就會產生WM_CHAR消息,如果沒有就會產生什麼消息。
PostQuitMessage:
nExitCode是退出標識碼,它被放到WM_QUIT消息的參數wParam裏。
VOID PostQuitMessage(int nExitCode);
當點擊窗口右上角的關閉時,Windows就會把窗口從系統裏刪除,這時就會發出消息WM_DESTROY給窗口消息處理函數WindowProc,WindowProc收到這條消息後,最需要做的一件事情就是調用PostQuitMessage發出退出消息,讓消息循環結束。