现在的位置: 首页 > 综合 > 正文

Win32消息处理API—GetMessage

2013年09月02日 ⁄ 综合 ⁄ 共 3495字 ⁄ 字号 评论关闭

 

02GetMessage

功能说明

WinCE下:该函数从呼叫进程的消息队列中检索消息,并且将所检索到的消息放入到一个指定的结构体(即MSG结构)中;

Win32下:该函数从呼叫进程的消息队列中检索消息,如果被检索到的消息为可分派消息,则该函数就分派该消息,如果被检索到的消息为不可分派消息,则GetMessage返回非正值,导致消息循环的结束。例如可分派的消息有:WM_PAINTWM_SIZEWM_CREATE等,不可分派的消息有WM_QUIT等。

   

函数格式

     BOOL GetMessage(

       LPMSG lpMsg,   // 检索到的消息

       HWND  hWnd,    // 窗口指向

       UINT  wMsgFilterMin, // 消息范围的下界限参数

       UINT  wMsgFilterMax  // 上界限参数

);

 

参数说明

1>lpMsg,【out

指向MSG结构的指针,该结构用于存放从进程消息队列里检索(接收)到的消息。

2>hWnd,【in

窗口句柄,如果非零,则GetMessage只检索该窗口(也包括其子窗口)消息,如果为零,则GetMessage检索整个进程内的消息。非零窗口句柄必须属于GetMessage所属的进程。

3>wMsgFilterMin,【in

指定被检索的最小消息值的整数,通常使用WM_KEYFIRST指定第一键盘消息或WM_MOUSEFIRST指定鼠标消息。Windows XP中:在此处使用的是WM_INPUT,同时wMsgFilterMax指定的消息也只有WM_INPUT

4>wMsgFilterMax,【in

指定被检索的最大消息值的整数,通常使用WM_KEYLAST指定最末键盘消息或WM_MOUSELAST指定最末鼠标消息。Windows XP中:在此处使用的是WM_INPUT,同时wMsgFilterMin指定的消息也只有WM_INPUT

 

如果wMsgFilterMinwMsgFilterMax都为零, 则GetMessage检索所有有效的信息(即,没有进行消息过滤,没有范围限制);同时,如果hWnd非零,则检索属于hWnd窗口的消息;如果hWnd为零,就是整个进程内的所有消息。

返回值

如果GetMessage检索到的消息不为WM_QUIT,则返回一个正值,如果检索到WM_QUIT消息,返回值是零,如果在检索消息时出现了错误,则返回值是-1。例如,当hWnd是无效的窗口句柄或lpMsg是空指针时。警示:因为返回值的三种状态,即:> 0= 0< 0,在使用GetMessage写程序时尽量避免如下格式的代码:

while (GetMessage(lpMsg, hWnd, 0, 0)) ...

因为当返回值为-1时,while循环还会继续执行的(读者可以自行验证),这样会导致应用程序出现致命错误而引起系统崩溃。所以建议写代码时应如下格式所示:

 

BOOL bRet = FALSE;

while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0) {

        if (bRet == -1)  {  // handle the error and possibly exit

        }  else {

            TranslateMessage(&msg);

            DispatchMessage(&msg);

        }

}

 

备注

1、应用程序在进行的消息循环内,通常用返回值来确定是否终止主消息循环并退出程序;

2GetMessage函数获取消息之后,将会使该消息被消息队列所删除(WM_PAINT消息除外,至于WM_PAINT则只有在其被合并处理之后才被删除);

3GetMessage只检索呼叫进程的消息,不检索属于其它进程的消息。

4、常数 WM_KEYFIRSTWM_KEYAST可作为过滤值检索与键盘输入相关的所有消息,常数WM_MOUSEFIRSTWM_MOUSELST可用来检索所有的鼠标消息;而在Windows XP中,二参数均使用WM_INPUT作为检索键盘和鼠标的输入。

5、当消息检索对象为进程消息队列时,如果进程消息队列正在进行消息存放操作,则GetMessage会等待这个存放操作结束后,再检索消息;如果消息队列为空,GetMessage也会等待的。

6、应用程序只能使用wMsgFilterMinwMsgFilterMax参数的低字节,而高字节是保留给系统使用的。

 

适用

Windows NT 3.1及以上版本;Windows95及以上版本;Windows CE1.0及以上版本:头文件:winuser.h;输入库:user32.IibUnicode:在Windows NT环境下以UnicodeANSI方式实现。

 

应用举例

这是一个Win32程序的创建,在创建该Win32程序时,初始化程序入口函数:包括注册应用程序主窗口、注册主窗口事件发布函数、创建窗体和消息循环体。

HINSTANCE  hinst;  HWND  hwndMain;

 

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  LPSTR lpszCmdLine, int nCmdShow) {

    MSG msg;    BOOL bRet;    WNDCLASS wc;

    UNREFERENCED_PARAMETER(lpszCmdLine); // 告诉编译器,该参数没有被引用,不要报警告

 

    // Register the window class for the main window.

    if (!hPrevInstance) {

        wc.style = 0;

        wc.lpfnWndProc = (WNDPROC)WndProc; // 注册窗口事件发布函数

        wc.cbClsExtra  = 0;

        wc.cbWndExtra  = 0;

        wc.hInstance   = hInstance;

        wc.hIcon   = LoadIcon((HINSTANCE)NULL, IDI_APPLICATION);

        wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);

        wc.hbrBackground = GetStockObject(WHITE_BRUSH);

        wc.lpszMenuName  = _T("MainMenu");

        wc.lpszClassName = _T("MainWndClass");

        if (!RegisterClass(&wc))  return FALSE; // 注册进程主窗口类

    }

 

    hinst = hInstance;  // save instance handle

    // Create the main window.

hwndMain  = CreateWindow(_T("MainWndClass"), _T("Sample"),

WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

(HWND)NULL, (HMENU)NULL, hinst, (LPVOID)NULL);

 

    // If the main window cannot be created, terminate the application.

    if (!hwndMain)  return FALSE;

 

    // Show the window and paint its contents.

    ShowWindow(hwndMain, nCmdShow);

    UpdateWindow(hwndMain);

    // Start the message loop.

    while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) { // 注册消息循环体

        if (bRet == -1) {   // handle the error and possibly exit

        } else {

  TranslateMessage(&msg);

            DispatchMessage(&msg);

        }

    }

 

    // Return the exit code to the system.

    return msg.wParam;

}

 

抱歉!评论已关闭.