实例说明>

首先自定义一个消息ID: UM_TEST,用于测试SendMessage和PostMessage的在发生该消息的具体区别,我们在主框架的OnCreate函数中实现该消息的测试,相关说明如下:

消息映射:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
    ....
    ON_MESSAGE(UM_TEST, &OnTest)//自定消息
END_MESSAGE_MAP()
函数声明:
对于自定义的消息,其函数声明必须是LRESULT类型,第一参数是WPARAM,第二参数是LPARAM,如下所示:

afx_msg LRESULT OnTest(WPARAM wParam, LPARAM lParam);
函数实现:

LRESULT CMainFrame::OnTest(WPARAM wParam, LPARAM lParam)
{     
    MessageBox("Process Msg Sucess");
    return 0;
}
OnCreate消息响应函数:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
   
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("未能创建工具栏
");
        return -1;      // 未能创建
    }

    ...//中间省略

    SendMessage(UM_TEST, 0, 0);
    return 0;
}

过程分析:

       我们首先在SendMessage()函数和return0两行分别打上断点,同时在OnTest消息响应函数体内打一个断点,F5 Debug执行代码,可以发现函数执行大致流程是:

SendMessage()->OnTest函数->SendMessage的下一句(return 0).

而如果将SendMessage改成PostMessage程序执行大致流程:

SendMessage()->SendMessage的下一句(return 0)->OnTest函数。


总结:

       从程序的执行顺序可以看出,当前程序会将SendMessage的消息处理完毕后,才会返回;而PostMessage只是将消息投递到线程的消息队列中,就立即返回。下一时刻该消息才从消息队列中取出,由对应的消息处理程序处理。


运行效果:

       对于SendMessage,如果我们不将“Process Msg Sucess”模态窗口点击确定,程序会一致阻塞在OnTest函数体内,不会往下执行;点击确定后,主框架窗口才会显示出来。

       对于PostMessage而言,主框架窗口完成显示后,提示框的窗口也显示出来了,两者有一定的先后顺序。

从执行效果上看,就可以明白SendMessage 是同步的,具有阻塞性质,而PostMessage是异步的,没有阻塞性质


原文地址:https://www.cnblogs.com/jinxiang1224/p/8468355.html