zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    C++ 虚基类表指针字节对齐
    C++ 虚函数的内存分配
    虚函数&&虚继承
    内存管理简便复习总结
    stack,heap的区别
    内存泄漏(memory leak)和内存溢出
    php+mysqli预处理技术实现添加、修改及删除多条数据的方法
    JavaScript 常用方法总结
    6个超实用的PHP代码片段
    php 备份数据库代码(生成word,excel,json,xml,sql)
  • 原文地址:https://www.cnblogs.com/shfanzie/p/4592569.html
Copyright © 2011-2022 走看看