当Window是向程序发送消息时,它调用程序中的一个函数,这个函数用来描述Windows发送的消息,成为窗口函数或消息处理函数。他是一个自定义的回调函数:
LRESULT CALLBACK WindowProc(HWND hwnd, UNIT uMsg, WPARAM wParam, LPARAM lParam);
- CALLBACK 宏是_stdcall的意思,说明采用WIndows标准方式传递参数。 详见:https://blog.csdn.net/lionghua/article/details/38415655
- uMsg:是一个消息ID号,它指定了所发的消息,当窗口函数接受到消息时,它使用消息ID号来决定如何处理这个消息;后面两个参数wParam和lParam的值也取决于uMsg。
例:关闭一个记事本程序,即向它的主窗口发送WM_CLOSE消息:
int main(int argc,char* argv[]) { //查找标题为“无标题-记事本“的窗口 HWND hWnd = ::FindWindow(NULL,"无标题-记事本"); //也可以使用类名查找,如 FindWindow("Notepad",NULL); if(hWnd != NULL) ::SendMessage(hWnd,WM_CLOSE,0,0); return 0; }
- FindWindow函数:查找窗口类名称和窗口标题与指定字符串相匹配的窗口。
- SendMessage函数: 向窗口发送消息,直到目标窗口处理完这个消息才返回。参数与WindowProc函数相同。
以下是Windows程序的基本框架,win32程序都是在这个框架的基础上扩充而来:
1 LRESULT CALLBACK MainWndProc(HWND,UNIT,WPARAM,LPARAM); 2 int APIENTRY WinMain(HINSTANCE hInstance, 3 HINSTANCE hPrevInstance, 4 LPSTR lpCmdLine, 5 int nCmdShow) 6 { 7 char szClassName[] = "MainWClass"; 8 WNDCLASSEX wndclass; 9 //用描述主窗口的参数来填充WNDCLASSEX结构 10 wndclass.cbSize=sizeof(wndclass); //结构大小 11 wndclass.style=CS_HREDRAWICS_VREDRAW; //指定如果大小改变就重画 12 wndclass.lpfnWndProc=MainWndProc; //窗口指针函数 13 wndclass.cbClsExtra=0; //没有额外的类内存 14 wndclass.cbWndExtra=0; //没有额外窗口内存 15 wndclass.hInstance = hInstance; //实例句柄 16 wndclass.hIcon=::LoadIcon(NULL, IDI_APPLICATION); //使用预定义图标 17 wndclass.hCursor=::LoadCursor(NULL, IDC_ARROW); //使用预定义光标 18 wndclass.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); //使用白色背景画刷 19 wndclass.lpszMenuName=NULL; //不指定菜单 20 wndclass.lpszClassName=szClassName; //窗口类名称 21 wndclass.hIconSm=NULL; //没有类的小图标 22 23 //注册这个窗口类 24 ::RegisterClassEx(&wndclass); 25 //创建主窗口 26 HWND hWnd=::CreateWindowEx( 27 0, //dwExStyle,扩展样式 28 szClassName, //lpClassName,类名 29 "My First Window!", //lpWindowName,窗口标题 30 WS_OVERLAPPEDWINDOW //swStyle,窗口风格 31 CW_USEDEFAULT, //X,初始x坐标 32 CW_USEDEFAULT, //Y,初始y坐标 33 CW_USEDEFAULT, //nWidth,宽度 34 CW_USEDEFAULT, //nHeight,高度 35 NULL, //hWndParent,父窗口句柄 36 NULL, //hMenu,菜单句柄 37 hInstance, //hInstance,程序实例句柄 38 NULL); //lpParam,用户数据 39 40 if(hWnd == NULL) 41 { 42 ::MessageBox(NULL,"创建窗口出错!","error",MB_OK); 43 return -1; 44 } 45 //显示窗口,刷新窗口客户区 46 ::ShowWindow(hWnd,nCmdShow); 47 ::UpdateWindow(hWnd); 48 //从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环 49 MSG msg; 50 while(::GetMessage(&msg,NULL,0,0) 51 { 52 //转化键盘消息 53 ::TranslateMessage(&msg); 54 //将消息发送到相应的窗口函数 55 ::DispatchMessage(&msg); 56 } 57 return msg.wParam; 58 } 59 60 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) 61 { 62 char szText[]="Hello World!"; 63 switch(message) 64 { 65 case WM_PAINT: //窗口客户区重绘 66 { 67 HDC hdc; 68 PAINTSTRUCT ps; 69 //使无效的客户区变得有效,并取得设备环境句柄 70 hdc=::BeginPaint(hWnd,&ps); 71 //显示文字 72 ::TextOut(hdc,10,10,szText,strlen(szText)); 73 ::EndPaint(hWnd,&ps); 74 return 0; 75 } 76 case WM_DESTORY: //销毁窗口 77 ::PostQuitMessage(0); 78 return 0; 79 } 80 //将不处理的消息交给系统默认处理 81 return ::DefWindowProc(hWnd,message,wParam,lParam); 82 }