PeekMessage与GetMessage

BOOL PeekMessage(
    LPMSG lpMsg,
    HWND hWnd,
    UINT wMsgFilterMin,
    UINT wMsgFilterMax,
    UINT wRemoveMsg
);

当消息队列中存在消息时, PeekMessage就返回TRUE, 最后一个参数可以为:

PM_REMOVE
PM_NOREMOVE

表示是否在接收到消息的时候从消息队列中删除它们。
与GetMessage的不同:
PeekMessage只要有消息的时候, 这相依返回TRUE, 即使消息是WM_QUIT, 没有消息的时候, 它不会等待,
而是立即返回,并返回FALSE。而GetMessage则是从消息队列中取出消息并删除它们, 当消息队列是空的时候,它会一直等待,直到队列中存在消息, 当收到WM_QUIT消息时, 它返回FALSE, 这是GetMessage惟一返回FALSE的情况, 其它都会返回TRUE, 代表一直等待或处理消息。
请记住:不管是PeekMessage还是GetMessage, 它们都不会删除WM_PAINT消息, 绝不会!!!从队列中删除WM_PAINT消息的情况是当显示区域重新变得有效的时候, 用ValidateRect和ValidateRgn或者BeginPaint和EndPaint来完成, 记住!!!!

哈哈, 不妨运行下面的程序, 你就会明白了:

#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
                 HINSTANCE hPrevInstance,
                 PSTR szCmdLine,
                 int iCmdShow) {
    static TCHAR szAppName[] = TEXT("rect demo");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;
    
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    
    if(!RegisterClass(&wndclass)) {
        MessageBox(NULL, TEXT("Register failure..."),
            szAppName, MB_ICONERROR);
        return 0;
    }
    
    hwnd = CreateWindow(szAppName,
        szAppName,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
    
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        if(msg.message == WM_QUIT)
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,
                         UINT message,
                         WPARAM wParam,
                         LPARAM lParam) {
    static int cxClient, cyClient;
    HDC hdc;
    PAINTSTRUCT ps;
    TCHAR buffer[5];
    static int i;
    RECT rect;

    switch(message) {
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        i = 0;
        return 0;

    case WM_PAINT:
        hdc = GetDC(hwnd);
        GetClientRect(hwnd, &rect);
        DrawText(hdc, buffer, wsprintf(buffer, "%5d",i++), &rect,
            DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        ReleaseDC(hwnd, hdc);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

Peekmessage和Getmessage都是向系统的消息队列中取得消息,不过性质不同。
  若第一次向消息队列中取不到消息,则程序的主线程会被OS(操作系统)挂起;等到OS重新调度到该线程时,而且消息队列仍然是空的时,两者的性质不同:  
  若使用Getmessage(),则程序的主线程会仍被OS挂起。  
  若是用Peekmessage(),则程序会取得OS控制权,运行一段时间。此函数多用于处理系统的空闲时间。
getmessage   and   peekmessage   are     both   get   the   message   from   send_message   queue.  
getmessage   supports     同步机制。PEEKMESSAGE   SUPPORTS   异步机制。

从原因上而言:GetMessage函数从消息队列中得到消息后并在队列中删除该消息  
              PeekMessage函数从消息队列中得到消息后并不在队列中删除该消息  
从结果上而言:GetMessage等待一个消息(就像_getch),直到拿到消息才返回
              PeekMessage不是这样(就像_kbhit),查询消息队列,有就取,即使没有也立即返回。  
    
为了实现windows的多任务,要用getmessage,因为当getmessage发现自己的消息队列里没有消息时,就会把控制权交还给系统,这样就可以让避免资源的浪费。

GetMessage函数每次调用是肯定会取回一个消息的,当消息队列为空的时候此进程会被挂起直到消息队列中有消息可取为止。  
PeekMessage函数不管消息队列中是否有消息都会立即返回,返回是可以从返回的值里判断是否取到了消息,准确地说此函数是询问了一下消息队列,至于取回消息后是否从消息队列中删除此消息,由参数可以指定。  
  Windows3.1时很多应用程序的消息队列是由GetMessage函数构成的,而Win32以后大多数的应用程序的消息队列是由 PeekMessage函数构成的,vc和bcb好像都是这样的,基于Win32的抢先式多任务处理机制,采用PeekMessage函数构成的消息循环也不会对系统造成什么威胁。

1.PeekMessage


函数功能:该函数为一个消息检查线程消息队列,并将该消息(如果存在)放于指定的结构。
函数原型:BOOL PeekMessage(LPMSG IpMsg,HWND hWnd,UINT wMSGfilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);
参数:
    lpMsg:接收消息信息的MSG结构指针。
    hWnd:其消息被检查的窗口的句柄。
    wMsgFilterMin:指定被检查的消息范围里的第一个消息。
    wMsgFilterMax:指定被检查的消息范围里的最后一个消息。
    wRemoveMsg:确定消息如何被处理。此参数可取下列值之一:
    PM_NOREMOVE:PeekMessage处理后,消息不从队列里除掉。
    PM_REMOVE:PeekMessage处理后,消息从队列里除掉。
    可将PM_NOYIELD随意组合到PM_NOREMOVE或PM_REMOVE。此标志使系统不释放等待调用程序空闲的线程。
    缺省地,处理所有类型的消息。若只处理某些消息,指定一个或多个下列值:
    PM_QS_INPUT:Windows NT5.0和Windows 98:处理鼠标和键盘消息。
    PM_QS_PAINT:Windows NT 5.0和Windows 98:处理画图消息。
    PM_QS_POSTMESSAGE:Windows NT 5.0和Windows 98:处理所有被寄送的消息,包括计时器和热键。
    PM_QS_SENDMESSAGE:Windows NT 5.0和Windows 98:处理所有发送消息。
    返回值:如果消息可得到,返回非零值;如果没有消息可得到,返回值是零。
    备注:和函数GetMessage不一样的是,函数PeekMesssge在返回前不等待消息被放到队列里。
    PeekMesssge只得到那些与参数hWnd标识的窗口相联系的消息或被lsChild确定为其子窗口相联系的消息,并且该消息要在由参数wMsgFiterMin和wMsgFiherMax确定的范围内。如果hWnd为NULL,则PeekMessage接收属于当前调用线程的窗口的消息(PeekMessage不接收属于其他线程的窗口的消息)。如果hWnd为C1,PeekMessage只返回hWnd值为NULL的消息,该消息由函数PostThreadMessage寄送。如果wMsgFilterMin和wMsgFilterMax都为零,GetMessage返回所有可得的消息(即,无范围过滤)。
    常数WM_KEYFIRST和WMKEYLAST可作为过滤值取得所有键盘消息;常数WM_MOUSEFIRST和WM_MOUSELAST可用来接收所有的鼠标消息。
    PeekMessage通常不从队列里清除WM_PAINT消息。该消息将保留在队列里直到处理完毕。但如果WM_PAINT消息有一个空更新区,PeekMessage将从队列里清除WM_PAINT消息。


2.PeekMessage和GetMessage的区别
a.GetMessage将等到有合适的消息时才返回,而PeekMessage只是撇一下消息队列.
b.GetMessage会将消息从队列中删除,而PeekMessage可以设置最后一个参数wRemoveMsg来决定是否将消息保留在队列中.

转载于:https://www.cnblogs.com/kex1n/archive/2010/08/10/2286482.html

MFC中PeekMessageGetMessage的区别 一、PeekMessageGetMessage的对比 相同点: PeekMessage函数GetMessage函数都用于查看应用程序消息队列,有消息时将队列中的消息派发出去。 不同点: GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,如果有消息,就返回true,否则返回false。 也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设 阅读详情

相关推荐

windows下GetMessagePeekMessage函数区别

摘要:本文详细解析了Windows API中的GetMessagePeekMessage函数,聚焦两大核心主题:1. 函数区别:GetMessage在消息队列为空时会阻塞线程,适用于标准消息循环;PeekMessage则立即返回,支持非阻塞处理,适合实时应用。2. 消息过滤机制:通过wMsgFilterMin/Max参数可精确控制消息获取范围,PeekMessage独有的wRemoveMsg参数可控制是否移除消息。文章还系统分类了常见WM_消息常量(如键盘/鼠标事件、窗口生命周期等),并给出典型应用场景和

sonadorje的专栏 902

PeekMessageGetMessage函数的主要区别

PeekMessageGetMessage函数的主要区别有: 1. GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,如果有消息,就返回true,否则返回false。也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设置为PM_REM

gencheng的专栏 2万+

GetMessagePeekMessage的区别

首先来看来GetMessagePeekMessage这两个API的函数原型: BOOL WINAPI GetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax );   BOOL WINAPI PeekMessage(LPMSG lpMsg, HWND hWnd, UIN

Fish的专栏 1200

GetMessagePeekMessage

<br />1.<br />GetMessage(LPMSG lpMsg,  HWND hWnd,   UINT wMsgFilterMin,   UINT wMsgFilterMax)<br />PeekMessage(LPMSG lpMsg,  HWND hWnd,   UINT wMsgFilterMin,   UINT wMsgFilterMax,UINT wRemoveMsg)<br /> 参数wRemoveMsg的作用是指定消息获取的方式,如果设为PM_NOREMOVE,那么消息将不会从消息队列

scollins的专栏 1397

Windows 消息循环 GetMessage() PeekMessage()

GetMessage()函数的消息循环的汇编代码.while TRUE invoke GetMessage,addr @stMsg,NULL,0,0 .break .if eax == 0 invoke TranslateMessage,addr @stMsg invoke DispatchMessage,addr @stMsg .endw ret 解读: 调...

OneTrianee的博客 2165

GetMessage TranslateMessage DispatchMessage 和PeekMessage

GetMessage 函数功能 GetMessage是计算机编程中的一个函数,从调用线程的消息队列里取得一个消息并把其放于指定的结构。GetMessage函数可取得指定窗口联系的消息和由PostThreadMesssge寄送的线程消息,接收一定范围的消息值,不接收属于其他线程或应用程序的消息。GetMessage获取消息成功后,线程把从消息队列中删除该消息,函数会一直等待直到有消息到来才有返回值。 函数声明 WINUSERAPI BOOL WINAPI GetMessage( _Out_ LPMS

寻梦&之璐 1225

【Visual C++】PeekMessageGetMessage的对比

PeekMessageGetMessage的对比相同点:PeekMessage函数GetMessage函数都用于查看应用程序消息队列,有消息时将队列中 的消息派发出去。不同点:无论应用程序消息队列是否有消息,PeekMessage函数都立即返回,程序得以继续执行后面的语句(无消息则执行其它指令,有消息时一般要将消息派发出去,再执行其它指令)。GetMessage函数只有在消息对立中有消息时返回

【浅墨的游戏编程Blog】毛星云(浅墨)的专栏 1万+

VC++ GetMessagePeekMessage的区别

PeekMessage:   有消息返回true,没有消息返回false 。 GetMessage:     有消息且该消息不为WM_QUIT则返回true,有消息且该消息为WM_QUIT则返回false。   会堵塞等待消息,直到从程序的消息队列中取得消息。 PeekMessage不堵塞。   普通的消息循环GetMessage while (GetMessage (&amp;ms...

daiyunxing0545的博客 591

Windows消息函数

Windows消息函数

zhangchuan7758的博客 1439

Programming Windows程式开发设计指南->第五章 例子程序6

/*_############################################################################  _##   _##  Programming Windows程式开发设计指南->第五章 例子程序6  _##  Author: xwlee                           _##  Time: 2007.06.20 

网络空间安全与企业信息化 1192

Win32消息处理API---PeekMessage

PeekMessage 功能说明

stubborn_boy的专栏 689

【DirectX11-Tutorial】实时消息循环The Real-Time Message Loop

这篇文章主要了解单独的函数PeekMessage(),并谈一下类似的GetMessage()函数有什么不同。GetMessage()也不是不好,只是没办法再游戏中取得持续卓越的效果所以考虑PeekMessage()函数代替前者。

ZON 955

深入解析MFC消息响应和消息路由

1.MFC中的消息分为三种 (1)标准消息,也叫窗口消息(例:WM_PAINT,WM_CREATE,WM_LBUTTONDOWN,WM_CHAR) (2)命令消息,来自菜单,工具栏和加速键,都以WM_COMMAND表示 (3)控件消息,控件消息又分为三小类,第一类和标准消息

倦鸟归时 9584

GetMessage()和PeekMessage()区别

GetMessage() 原型:BOOL GetMessage(LPMSG lpMsg, HWND hWNd, UINT wMsgFilterMin, UINT wMsgFilterMax); Retrieves a message from the calling threads queque. The function dispatches incoming sent message un...

weixin_30258027的博客 376

while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))

项目中用到了好多这个消息循环,很是困惑。遂百度之,难道一个窗口下可以有多个消息循环吗?百度结果都是介绍和GetMessage区别的,正经的说这个有啥作用的,少之又少。不过有一篇英文的不错,这是出处,可以参考一下 http://blog.csdn.net/scofieldlau/article/details/1965517#t0 。奈何我的疑惑仍然为解。最后查看MSDN,清晰一二 原文

奔跑吧,蜗牛! 8985

GetMessage PeekMessage 的区别

GetMessage 和 PeekMessage 函数的主要区别有: 1). GetMessage的主要功能是从消息队列中“取出”消息,消息被取出以后,就从消息队列中将其删除;而PeekMessage的主要功能是“窥视”消息,如果有消息,就返回true,否则返回false。也可以使用PeekMessage从消息队列中取出消息,这要用到它的一个参数(UINT wRemoveMsg),如果设置为P

HelloKandy's Blog 3316
上一篇: TinyXML Tutorial 中文指南
下一篇: C++ 的各种库--收藏
diaoqu4574
博客等级 码龄10年 26粉丝 311原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值