Win32 event message handlers

  1. event message    

An event in Windows is an "action", which may be generated by the user operating the application or by Windows itself.

The message is used to describe these "actions", such as:    

When did this action take place?    

Which application produced it?    

Where did it arise?    

etc. . .    

Event-driven messages, messages encapsulating events

In order to accurately describe these information, Windows provides a structure: MSG, the detailed information of the events recorded in the structure.

typedef struct tagMSG {    

HWND hwnd; // window handle

UINT message; //Message type

WPARAM wParam; // Further description of the message type

LPARAM lParam; //Same as above

DWORD time; // time when the action occurred

POINT pt; //Coordinates, the structure is encapsulated, the interior is x, y

} MSG, *PMSG;     

illustrate:    

1、hwnd:    

Indicates the window to which the message belongs    

A message is generally associated with a window    

In Windows, variables of type HWND are often used to identify windows.    

2、message    

In Windows, a message is represented by a number    

But because the value is not easy to remember, Windows defines the value corresponding to the message as the WM_XXX macro (WM == Window Message)    

Left mouse button pressed WM_LBUTTONDOWN Keyboard pressed WM_KEYDOWN    

3、wParam 和 lParam    

Additional information specific to a 32-bit message, specifically indicating what to resolve to the message     

4、time    

The time when the message was created     

5. The mouse position when the message was created

Specifically: as shown in the figure below, after the user enters, it is packaged into a message, added to the system's message queue, and then the application has a queue

用来存储自己的消息队列,所以系统队列到应用程序队列是分流而治的过程。

从队列中取出消息,使用的是循环机制,就是不停的取出消息,而后面的判断消息类型是不是我们关心的意思其实是

我们是否写了该消息下的响应函数,或者说回调函数。

具体流程如下图:

 

2.创建一个窗口程序

步骤1:创建Windows应用程序 选择空项目    

步骤2:在新建项窗口中选C++代码文件 创建一个新的cpp文件    

步骤3:在新的cpp文件中添加:#include <Windows.h>    

并添加入口函数:    

int CALLBACK WinMain(                 CALLBACK 是一个宏             

_In_ HINSTANCE hInstance,         #define CALLBACK __stdcall    

_In_ HINSTANCE hPrevInstance,     

_In_ LPSTR lpCmdLine,                 

_In_ int nCmdShow             

)                     所有的Win32 API函数都遵循该约定    

{                     

return 0;             

}                     

步骤4:设计窗口类    

代码:    

//窗口的类名    

TCHAR className[] = "My First Window";     

// 创建窗口类的对象     

WNDCLASS wndclass = {0};        //一定要先将所有值赋值    

wndclass.hbrBackground = (HBRUSH)COLOR_MENU;        //窗口的背景色    

wndclass.lpfnWndProc = WindowProc;        //窗口过程函数    

wndclass.lpszClassName = className;        //窗口类的名字    

wndclass.hInstance = hInstance;        //定义窗口类的应用程序的实例句柄    

步骤5:注册窗口类    ,这是什么?哈哈哈,就是把结构体赋值后传参调用。

RegisterClass(&wndclass);     

步骤6:创建窗口    

// 创建窗口     

HWND hwnd = CreateWindow(     

className,        //类名    

TEXT("我的第一个窗口"),        //窗口标题    

WS_OVERLAPPEDWINDOW,        //窗口外观样式     

10,        //相对于父窗口的X坐标    

10,        //相对于父窗口的Y坐标    

600,        //窗口的宽度     

300,        //窗口的高度     

NULL,        //父窗口句柄,为NULL     

NULL,        //菜单句柄,为NULL     

hInstance,        //当前应用程序的句柄     

NULL);        //附加数据一般为NULL    

if(hwnd == NULL)        //是否创建成功     

return 0;     

步骤7:显示窗口    

// 显示窗口     

ShowWindow(hwnd, SW_SHOW);     

步骤8:消息循环    

MSG msg;     

while(GetMessage(&msg, NULL, 0, 0))     

{     

TranslateMessage(&msg);     

DispatchMessage(&msg);     

}     

步骤9:回调函数    

/*                        

窗口消息处理程序 窗口回调函数:            

1、窗口回调函数处理过的消息,必须传回0.        

2、窗口回调不处理的消息,由DefWindowProc来处理.    

*/                        

LRESULT CALLBACK WindowProc(         

IN HWND hwnd,     

IN UINT uMsg,     

IN WPARAM wParam,     

IN LPARAM lParam     

)     

{     

switch(uMsg)    

{    

//窗口消息    

case WM_CREATE:     

{    

DbgPrintf("WM_CREATE %d %d\n",wParam,lParam);    

CREATESTRUCT* createst = (CREATESTRUCT*)lParam;    

DbgPrintf("CREATESTRUCT %s\n",createst->lpszClass);    

return 0;    

}    

case WM_MOVE:    

{    

DbgPrintf("WM_MOVE %d %d\n",wParam,lParam);    

POINTS points = MAKEPOINTS(lParam);    

DbgPrintf("X Y %d %d\n",points.x,points.y);    

return 0;    

}    

case WM_SIZE:    

{    

DbgPrintf("WM_SIZE %d %d\n",wParam,lParam);    

int newWidth = (int)(short) LOWORD(lParam);     

int newHeight = (int)(short) HIWORD(lParam);     

DbgPrintf("WM_SIZE %d %d\n",newWidth,newHeight);    

return 0;    

}    

case WM_DESTROY:    //销毁

{    

DbgPrintf("WM_DESTROY %d %d\n",wParam,lParam);    

PostQuitMessage(0);    

return 0;    

}    

//键盘消息    

case WM_KEYUP:    

{    

DbgPrintf("WM_KEYUP %d %d\n",wParam,lParam);    

return 0;    

}    

case WM_KEYDOWN:    

{    

DbgPrintf("WM_KEYDOWN %d %d\n",wParam,lParam);    

return 0;    

}    

//鼠标消息    

case WM_LBUTTONDOWN:    

{    

DbgPrintf("WM_LBUTTONDOWN %d %d\n",wParam,lParam);    

POINTS points = MAKEPOINTS(lParam);    

DbgPrintf("WM_LBUTTONDOWN %d %d\n",points.x,points.y);    

return 0;    

}    

}    

return DefWindowProc(hwnd,uMsg,wParam,lParam);    //扔给windows处理其他消息

}     

 

MFC就是基于此封装

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325468304&siteId=291194637