6.windows消息机制(一)

1.所谓程序执行机制分为:

  过程驱动:程序的执行过程总是按照预定好的顺序执行。

  事件驱动:程序的执行是无序的,用户可以根据需要随机出发相应的事件。

  win32窗口程序就是采用事件驱动方式执行,也就是消息机制。

2.什么是消息?

  当系统通知窗口工作时,DispatchMessage函数就采用消息的方式派发给窗口处理函数。

  消息的组成:(windows平台下消息必须由这6个部分组成)

    窗口句柄

    消息ID

    消息的两个参数(两个附带信息)

    消息的产生时间

    消息产生时的鼠标位置

3.DispatchMessage( &nMsg )是怎么派发消息?(其实就是调用我们的窗口处理函数来处理这个消息)

  通过nMsg.hWnd保存窗口数据的内存,然后找到窗口对应的窗口类名称,用这个名称去匹配每个窗口类名称。

  一旦匹配成功,就直接调用我们自己定义的窗口处理函数。

  然后给我们的窗口处理函数传参:WndProc(nMsg.hWnd, nMsg.message, nMsg.wParam, nMsg.lParam)

4.窗口处理函数

  (1)每个窗口都必须具有窗口处理函数

    LRESULT CALLBACK WindowProc( HWND      hWnd,     //窗口句柄

                                                             UINT        uMsg,      //消息ID

                                                             WPARAM  wParam,   //消息参数

                                                      LPARAM    lParam);  //消息参数

    当系统通知窗口时,会调用窗口处理函数,同时将参数(窗口句柄、消息ID、消息两个参数)传递给窗口处理函数。

    在窗口处理函数中,不处理的消息,使用缺省窗口处理函数,例如DefWindowProc。

5.消息相关函数

  (1)GetMessage - 获取本进程的消息

    BOOL GetMessage( LPMSG  lpMsg,                //存放获取到的消息buffer

                            HWND   hWnd,                //窗口句柄

                            UINT     wMsgFilterMin,      //获取消息的最小ID

                                UINT     wMsgFilterMax); //获取消息的最大ID

    lpMsg - 获取到消息后,将消息的参数存放到MSG结构中

    hWnd - 获取到hWnd所指窗口的消息,不获取其他窗口消息;如果为NULL,任意窗口的消息都获取。

    wMsgFilterMin和wMsgFilterMax - 只能获取到由它指定的消息范围内的消息,如果都为0,表示没有范围。

    如果抓取到的消息是WM_QUIT,那么返回值为0;否则,返回非0。

  (2)TranslateMessage - 翻译消息,将按键消息翻译成字符消息

    BOOL TranslateMessage( CONST MSG *lpMsg);  //消息的地址

    检查消息是否是按键的消息,如果不是按键消息,不做任何处理继续执行。

    为什么只翻译按键消息,不翻译其他消息呢?因为键盘中的可见字符按键有多种状态(比如大小写)。

  (3)DispatchMessage - 派发消息,将消息派发到该消息所属窗口的窗口处理函数上

    LRESULT DispatchMessage( CONST MSG *lpMsg);  //消息的地址

 6.Windows常用消息

  (1)WM_DESTROY - 窗口被销毁(保存窗口数据的内存释放)时的消息,无消息参数。常用于在窗口被销毁之前,做相应的善后处理,

                                     例如资源、内存等。

  (2)WM_SYSCOMMAND - 系统命令消息,当点击窗口的最大化、最小化、关闭等命令时,收到这个消息,常用在窗口关闭时,提示用户处理。

      wPARAM- 具体点击位置,例如关闭SC_CLOSE等。

      lPARAM - 鼠标位置:LOWORD - 水平位置,HIWORD - 垂直位置。

  (3)WM_CREATE - 在窗口创建成功还未显示之前,收到这个消息。常用于初始化窗口的参数、资源等,包括创建子窗口等。

      WPARAM - 不使用。

      LPARAM - 是CREATESTRUCT结构指针,保存了CreateWindowEx中的12个参数。

  (4)WM_SIZE - 在窗口的大小发生变化后,会收到这个消息。常用于窗口大小变化后,调整窗口内各个部分的布局。

      wPARAM - 窗口大小变化的原因。

      lPARAM - 变化窗口客户区的大小:LOWORD - 变化后的宽度,HIWORD - 变化后的高度。

  (5)WM_QUIT - 用于结束消息循环处理

      wPARAM  - PostQuitMessage函数传递的参数

      lPARAM - 不使用

      当GetMessage收到这个消息后,会返回FALSE,结束while处理,退出消息循环。

  (6)WM_PAINT - 绘图消息

  (7)键盘消息

  (8)鼠标消息

  (9)定时器消息

下面是示例代码:

复制代码
#include "stdafx.h"

HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄

//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_SYSCOMMAND:
        if (SC_CLOSE == wParam)
        {
            int nRet = MessageBox(NULL, "是否退出", "Info", MB_YESNO);
            if (IDNO == nRet)
            {
                return 0;
            }
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
{
    WNDCLASSEX wce = { 0 };

    wce.cbSize = sizeof(wce);
    wce.cbClsExtra = 200;
    wce.cbClsExtra = 200;
    wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wce.hCursor = NULL;
    wce.hIcon = NULL;
    wce.hIconSm = NULL;
    wce.hInstance = g_hInstance;
    wce.lpfnWndProc = wndProc;
    wce.lpszClassName = lpClassName;
    wce.lpszMenuName = NULL;
    wce.style = CS_HREDRAW | CS_VREDRAW;

    ATOM nAtom = RegisterClassEx(&wce);
    if (0 == nAtom)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
{
    HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, g_hInstance, NULL);
    return hWnd;
}//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0))
    {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    g_hInstance = hInstance;
    Register("Main", WndProc);
    HWND hWnd = CreateMainWindow("Main", "window");
    Display(hWnd);
    Message();
    return 0;
}
View Code
复制代码

运行结果:

  

 

posted @   甩锅侠  阅读(269)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示