Windows程序消息机制浅析

1、消息

    消息是由MSG结构体来表示的。如下:

1 typedef struct tagMSG {
2   HWND   hwnd;
3   UINT   message;
4   WPARAM wParam;
5   LPARAM lParam;
6   DWORD  time;
7   POINT  pt;
8 } MSG

2、WinMain函数的定义 

        WinMain函数的原型声明如下:

1 int WINAPI WinMain(
2   HINSTANCE hInstance,            // handle to current instance
3   HINSTANCE hPrevInstance,        // handle to previous instance
4   LPSTR lpCmdLine,                // command line
5   int nCmdShow                    // show state
6 );

3、窗口的创建:设计一个窗口类、注册窗口类、创建窗口、显示及更新窗口。 

        设计一个窗口:WNDCLASS结构体的定义如下:

 1 typedef struct _WNDCLASS {
 2     UINT       style;
 3     WNDPROC    lpfnWndProc;
 4     int        cbClsExtra;
 5     int        cbWndExtra;
 6     HINSTANCE  hInstance;
 7     HICON      hIcon;
 8     HCURSOR    hCursor;
 9     HBRUSH     hbrBackground;
10     LPCTSTR    lpszMenuName;
11     LPCTSTR    lpszClassName;
12 } WNDCLASS;

        注册窗口类:注册函数的原型声明如下:

1 ATOM RegisterClass(
2   CONST WNDCLASS *lpWndClass  // class data
3 );

        创建窗口:CreateWindow函数的原型声明如下:

 1 HWND CreateWindow(
 2   LPCTSTR lpClassName,  // registered class name
 3   LPCTSTR lpWindowName, // window name
 4   DWORD dwStyle,        // window style
 5   int x,                // horizontal position of window
 6   int y,                // vertical position of window
 7   int nWidth,           // window width
 8   int nHeight,          // window height
 9   HWND hWndParent,      // handle to parent or owner window
10   HMENU hMenu,          // menu handle or child identifier
11   HINSTANCE hInstance,  // handle to application instance
12   LPVOID lpParam        // window-creation data
13 );

        更新及更新窗口:显示窗口ShowWindow函数的原型声明如下:

1 BOOL ShowWindow(
2   HWND hWnd,     // handle to window
3   int nCmdShow   // show state
4 );

        更新及更新窗口:更新窗口UpdateWindow函数的原型声明如下:

1 BOOL UpdateWindow(HWND hWnd);

4、消息循环:不断从消息队列中取出消息,并进行响应。 

1 BOOL GetMessage(
2   LPMSG lpMsg,         // message information
3   HWND hWnd,           // handle to window
4   UINT wMsgFilterMin,  // first message
5   UINT wMsgFilterMax   // last message
6 );

      Windows应用程序消息处理机制如下图所示:

  

  1. 操作系统接收到应用程序的窗口消息,将消息投递到应用程序的消息队列中。

  2. 应用程序在消息循环中调用GetMessage函数从消息队列中取出一条一条的消息。取出消息后,应用程序可以对消息进行一些预处理,例如,放弃对某些消息的响应,或者调用TranslateMessage产生新的消息。

  3. 应用程序调用DispatchMessage,将消息回传给操作系统。消息是由MSG结构体对象来表示的,其中就包含了接收消息的窗口的句柄。因此,DispatchMessage函数总能进行正确的传递。

  4. 系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理(即“系统给应用程序发送了消息”)。

5、编写窗口过程函数:窗口过程函数的声明形式如下:

1 LRESULT CALLBACK WindowProc(
2   HWND hwnd,      // handle to window
3   UINT uMsg,      // message identifier
4   WPARAM wParam,  // first message parameter
5   LPARAM lParam   // second message parameter
6 );
提示:系统通过窗口过程函数的地址(指针)来调用窗口过程函数,而不是名字。 
 
 
例:WinMain.cpp
 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 LRESULT CALLBACK WinSunProc(
 5                   HWND hwnd,      // handle to window
 6                   UINT uMsg,      // message identifier
 7                   WPARAM wParam,  // first message parameter
 8                   LPARAM lParam   // second message parameter
 9                 );
10 
11 int WINAPI WinMain(
12             HINSTANCE hInstance,      // handle to current instance
13             HINSTANCE hPrevInstance,  // handle to previous instance
14             LPSTR lpCmdLine,          // command line
15             int nCmdShow              // show state
16            )
17 {
18     WNDCLASS wndcls;
19     wndcls.cbClsExtra=0;
20     wndcls.cbWndExtra=0;
21     wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
22     wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
23     wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
24     wndcls.hInstance=hInstance;
25     wndcls.lpfnWndProc=WinSunProc;
26     wndcls.lpszClassName="bedrock32";
27     wndcls.lpszMenuName=NULL;
28     wndcls.style=CS_HREDRAW | CS_VREDRAW;
29     RegisterClass(&wndcls);
30 
31     HWND hwnd;
32     hwnd=CreateWindow("bedrock32","http://www.cnblogs.com/bedrock32",WS_OVERLAPPEDWINDOW,
33         0,0,600,400,NULL,NULL,hInstance,NULL);
34 
35     ShowWindow(hwnd,SW_SHOWNORMAL);
36     UpdateWindow(hwnd);
37 
38     MSG msg;
39     while(GetMessage(&msg,NULL,0,0))
40     {
41         TranslateMessage(&msg);
42         DispatchMessage(&msg);
43     }
44     return msg.wParam;
45 }
46 
47 LRESULT CALLBACK WinSunProc(
48                   HWND hwnd,      // handle to window
49                   UINT uMsg,      // message identifier
50                   WPARAM wParam,  // first message parameter
51                   LPARAM lParam   // second message parameter
52                 )
53 {
54     switch(uMsg)
55     {
56     case WM_CHAR:
57         char szChar[20];
58         sprintf(szChar,"char code is %d",wParam);
59         MessageBox(hwnd,szChar,"char",0);
60         break;
61     case WM_LBUTTONDOWN:
62         MessageBox(hwnd,"mouse clicked","message",0);
63         HDC hdc;
64         hdc=GetDC(hwnd);
65         TextOut(hdc,0,50,"我是高手",strlen("我是高手"));
66         //ReleaseDC(hwnd,hdc);
67         break;
68     case WM_PAINT:
69         HDC hDC;
70         PAINTSTRUCT ps;
71         hDC=BeginPaint(hwnd,&ps);
72         TextOut(hDC,0,0,"http://www.cnblogs.com/bedrock32",strlen("http://www.cnblogs.com/bedrock32"));
73         EndPaint(hwnd,&ps);
74         break;
75     case WM_CLOSE:
76         if(IDYES==MessageBox(hwnd,"是否真的结束?","message",MB_YESNO))
77         {
78             DestroyWindow(hwnd);
79         }
80         break;
81     case WM_DESTROY:
82         PostQuitMessage(0);
83         break;
84     default:
85         return DefWindowProc(hwnd,uMsg,wParam,lParam);
86     }
87     return 0;
88 }
原文地址:https://www.cnblogs.com/shfanzie/p/4592569.html