My First Window构造过程,SendMessage同步,PostMessage异步
文章目錄
- 第一步:定義你的窗口是什么樣的?(創(chuàng)建,初始化,注冊窗口類)
- 第二步:創(chuàng)建并顯示窗口
- 第三步:接收消息并處理(處理的話也就是完成回調(diào)函數(shù)初始化)
- 舉例:
- 默認的消息處理函數(shù):
- SendMessage同步
- PostMessage異步
- 窗口完整代碼
- 運行截圖
第一步:定義你的窗口是什么樣的?(創(chuàng)建,初始化,注冊窗口類)
窗口的類名:
PSTR classname = (PSTR)"My First Window";創(chuàng)建窗口類的對象:
WNDCLASS wndclass = { 0 }; //一定要將所有值賦值wndclass.hbrBackground = (HBRUSH)COLOR_MENU;//窗口背景色wndclass.lpfnWndProc = WindowProc;//窗口過程函數(shù)(注冊回調(diào)函數(shù))wndclass.lpszClassName = classname;//窗口類的名字wndclass.hInstance = hInstance;//定義窗口類 的應(yīng)用程序的實例句柄//注冊窗口類 //參見MSDN文檔RegisterClass-->Parameters //You must fill the structure with appropriate class attributes //before passing it to the functionRegisterClass(&wndclass);第二步:創(chuàng)建并顯示窗口
HWND hwnd = CreateWindow(classname,//類名"我的第一個窗口",//窗口標題WS_OVERLAPPEDWINDOW,//窗口外觀樣式10,//相對于父窗口的x坐標10,//相對于父窗口的y坐標800,//窗口的寬度400,//窗口的高度NULL,//父窗口句柄NULL,//菜單句柄hInstance,//當(dāng)前應(yīng)用程序句柄NULL);//附加數(shù)據(jù),一般為MULL//顯示窗口ShowWindow(hwnd, SW_SHOW);第三步:接收消息并處理(處理的話也就是完成回調(diào)函數(shù)初始化)
MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {TranslateMessage(&msg);DispatchMessage(&msg);}回調(diào)函數(shù)初始化:
LRESULT CALLBACK WindowProc(IN HWND hwnd,IN UINT uMsg,IN WPARAM wParan,IN LPARAM lParam ) {//獲取dialog句柄TCHAR szBuff[0x20];GetClassName(hwnd, szBuff, 0x20);WNDCLASS wc;GetClassInfo(hAppInstance, szBuff, &wc);//PDWORD addr=(PDWORD)wc.IpfnWndProc;DWORD addr = GetWindowLong(hwnd, GWL_WNDPROC);DWORD error = GetLastError();//獲取線程IDDWORD dwThreadId = GetCurrentThreadId();switch (uMsg){case WM_DESTROY:{PostQuitMessage(0);return 0;}case 0x401:{strcpy_s(szBuff, "接到其它程序發(fā)送的消息!!!");MessageBox(hwnd, szBuff, "--", MB_OK);return 0;}/*case WM_KEYDOWN:{sprintf_s(szBuff, "你按下了%d鍵", wParan);MessageBox(hwnd, szBuff, "---", 0);return 0;}*/case WM_CHAR:sprintf_s(szBuff, "你按下了%c鍵", wParan);MessageBox(hwnd, szBuff, "---", 0);return 0;default:break;}return DefWindowProc(hwnd, uMsg, wParan, lParam); }前面已經(jīng)解釋過,這個DispatchMessage(&msg);和GetMessage(&msg, NULL, 0, 0),這里就來解釋一下TranslateMessage(&msg);,這個API主要針對WM_CHAR這個鍵盤消息的,
TranslateMessage(&msg);處理鍵盤消息(WM_CHAR),這個消息進行字符轉(zhuǎn)換的,(把鍵盤上的65轉(zhuǎn)換為字符a,僅此而已,也就對鍵盤消息進行鍵盤消息加工作用
舉例:
保留著TranslateMessage(&msg);接收消息用代碼
case WM_CHAR:sprintf_s(szBuff, "你按下了%c鍵", wParan);MessageBox(hwnd, szBuff, "---", 0);return 0;運行截圖如下:
注釋掉TranslateMessage(&msg);接收消息用代碼
運行截圖如下,沒反應(yīng),是因為回調(diào)函數(shù)沒有接收到消息嗎?那接下來我們來驗證一下
注釋掉TranslateMessage(&msg);接收消息用代碼
運行截圖如下:
好了,現(xiàn)在大家心里都清楚了吧
默認的消息處理函數(shù):
DefWindowProc(hwnd, uMsg, wParan, lParam);對其它我們不需要關(guān)注的消息進行處理
SendMessage同步
當(dāng)我們未點擊確定時,發(fā)送消息的程序未退出,需要點擊確定后,發(fā)送消息的程序收到返回消息,它才會自行退出。這也就是SendMessage的同步問題
PostMessage異步
PostMessage發(fā)送完消息后,程序即刻退出,并不會等待處理結(jié)果,這也就是PostMessage發(fā)送消息異步問題
窗口完整代碼
#include "framework.h" #include "窗口過程.h" #include<stdio.h> HINSTANCE hAppInstance; #define MAX_LOADSTRING 100LRESULT CALLBACK WindowProc(IN HWND hwnd,IN UINT uMsg,IN WPARAM wParan,IN LPARAM lParam ); void CreateButton(HWND hwnd);int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR IpCmdLine,int nCmdShow) {//把這個參數(shù)變?yōu)槿值?#xff0c;下面的函數(shù)會用到hAppInstance = hInstance;//窗口的類名PSTR classname = (PSTR)"My First Window";//創(chuàng)建窗口類的對象WNDCLASS wndclass = { 0 }; //一定要將所有值賦值wndclass.hbrBackground = (HBRUSH)COLOR_MENU;//窗口背景色wndclass.hCursor = LoadCursor(NULL, IDC_APPSTARTING);wndclass.lpfnWndProc = WindowProc;//窗口過程函數(shù)wndclass.lpszClassName = classname;//窗口類的名字wndclass.hInstance = hInstance;//定義窗口類的應(yīng)用程序的實例句柄//注冊窗口類//參見MSDN文檔RegisterClass-->Parameters//You must fill the structure with appropriate class attributes//before passing it to the functionRegisterClass(&wndclass);//創(chuàng)建窗口HWND hwnd = CreateWindow(classname,//類名"我的第一個窗口",//窗口標題WS_OVERLAPPEDWINDOW,//窗口外觀樣式10,//相對于父窗口的x坐標10,//相對于父窗口的y坐標800,//窗口的寬度400,//窗口的高度NULL,//父窗口句柄NULL,//菜單句柄hInstance,//當(dāng)前應(yīng)用程序句柄NULL);//附加數(shù)據(jù),一般為MULLif (hwnd == NULL) {OutputDebugString("輸出錯誤");}//顯示窗口ShowWindow(hwnd, SW_SHOW);MSG msg;while (GetMessage(&msg, NULL, 0, 0)) {//TranslateMessage(&msg);//DispatchMessage(&msg);}return 0;} LRESULT CALLBACK WindowProc(IN HWND hwnd,IN UINT uMsg,IN WPARAM wParan,IN LPARAM lParam ) {//獲取dialog句柄TCHAR szBuff[0x20];GetClassName(hwnd, szBuff, 0x20);WNDCLASS wc;GetClassInfo(hAppInstance, szBuff, &wc);//PDWORD addr=(PDWORD)wc.IpfnWndProc;DWORD addr = GetWindowLong(hwnd, GWL_WNDPROC);DWORD error = GetLastError();//獲取線程IDDWORD dwThreadId = GetCurrentThreadId();switch (uMsg){case WM_DESTROY:{PostQuitMessage(0);return 0;}case 0x401:{strcpy_s(szBuff, "接到其它程序發(fā)送的消息!!!");MessageBox(hwnd, szBuff, "--", MB_OK);return 0;}case WM_KEYDOWN:{sprintf_s(szBuff, "你按下了%d,%d鍵", wParan, lParam);MessageBox(hwnd, szBuff, "---", 0);return 0;}/*case WM_CHAR:sprintf_s(szBuff, "你按下了%c鍵", wParan);MessageBox(hwnd, szBuff, "---", 0);return 0;*/default:break;}return DefWindowProc(hwnd, uMsg, wParan, lParam); }運行截圖
總結(jié)
以上是生活随笔為你收集整理的My First Window构造过程,SendMessage同步,PostMessage异步的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从内核层说清GetMessage , D
- 下一篇: 异常记录(CPU产生的异常和软件模拟产生