看到讲SendMessage和PostMessage区别 不错的文章,转载一下方便查看
理论篇:
原文地址:http://df22b.blog.163.com/blog/static/2488576520119994458230/
1、SendMessage、PostMessage的运行机制
我们先来看最简单的。
SendMessage可以理解为,SendMessage函数发送消息,等待消息处理完成后,SendMessage才返回。稍微深入一点,是等待窗口处理函数返回后,SendMessage就返回了。
PostMessage可以理解为,PostMessage函数发送消息,不等待消息处理完成,立刻返回。稍微深入一点,PostMessage只管发送消息,消息有没有被送到则并不关心,只要发送了消息,便立刻返回。
对于写一般Windows程序的程序员来说,能够这样理解也就足够了。但SendMessage、PostMessage真的是一个发送消息等待、一个发送消息不等待吗?具体细节,下面第2点将会讲到。
2、SendMessage、PostMessage的运行内幕
在写一般Windows程序时,如上第1点讲到的足以应付,其实我们可以看看MSDN来确定SendMessage、PostMessage的运行内幕。
在MSDN中,SendMessage解释如为:The SendMessage function sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message.
翻译成中文为:SendMessage函数将指定的消息发到窗口。它调用特定窗口的窗口处理函数,并且不会立即返回,直到窗口处理函数处理了这个消息。
再看看PostMessage的解释:The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.
翻译成中文为:PostMessage函数将一个消息放入与创建这个窗口的消息队列相关的线程中,并立刻返回不等待线程处理消息。
仔细看完MSDN解释,我们了解到,SendMessage的确是发送消息,然后等待处理完成返回,但发送消息的方法为直接调用消息处理函数(即WndProc函数),按照函数调用规则,肯定会等消息处理函数返回之后,SendMessage才返回。而PostMessage却没有发送消息,PostMessage是将消息放入消息队列中,然后立刻返回,至于消息何时被处理,PostMessage完全不知道,此时只有消息循环知道被PostMessage的消息何时被处理了。
至此我们拨开了一层疑云,原来SendMessage只是调用我们的消息处理函数,PostMessage只是将消息放到消息队列中。
实例讲解:
原文地址:http://blog.csdn.net/clever101/article/details/5947516
PostMessage是一个异步行为,就是先把消息扔到对方的消息队列,然后沿着原调用点继续执行;
SendMessage是一个同步行为,就是等待对方把这个消息处理完再回到调用点继续执行。
我想怎么测试这个结论呢?为此我设计了一个小试验:在视图中弹出一个非模式的帮助对话框,然后分别用PostMessage和SendMessage给这个对话框发消息,消息处理函数很简单,就是在视图上打印字符串。
- // 使用SendMessage给对话框发送自定义消息WM_ABOUTSENDMSG,然后打印5个"字符串来// 自视图窗口"的字符串
- void CTestUnicodeView::OnTestSendmsg()
- {
- // TODO: 在此添加命令处理程序代码
- int i = 0;
- // m_pAboutDlg为CAboutDlg类指针的变量
- ::SendMessage(m_pAboutDlg->GetSafeHwnd(),WM_ABOUTSENDMSG,(WPARAM)this->GetSafeHwnd(),(LPARAM)i);
- CDC *pDC = GetDC();
- for ( i = 0;i<5;i++)
- {
- CString str = _T("字符串来自视图窗口");
- CRect rt(0,120+i*20,200,140+i*20);
- pDC->DrawText(str,&rt,DT_CENTER);
- Sleep(2000); // 睡眠2秒,可以更好看到输出
- }
- ReleaseDC(pDC);
- }
- // 使用PostMessage给对话框发送自定义消息WM_ABOUTPOSTMSG,然后打印5个"字符串来// 自视图窗口"的字符串
- void CTestUnicodeView::OnTestPostmsg()
- {
- // TODO: 在此添加命令处理程序代码
- int i = 0;
- ::PostMessage(m_pAboutDlg->GetSafeHwnd(),WM_ABOUTPOSTMSG,(WPARAM)this->GetSafeHwnd(),(LPARAM)i);
- CDC *pDC = GetDC();
- for ( i = 0;i<5;i++)
- {
- CString str = _T("字符串来自视图窗口");
- CRect rt(0,120+i*20,200,140+i*20);
- pDC->DrawText(str,&rt,DT_CENTER);
- Sleep(2000); // 睡眠2秒,可以更好看到输出
- }
- ReleaseDC(pDC);
- }
- // WM_ABOUTSENDMSG消息的处理函数,在视图上打印5个"字符串来自对话框窗口"
- LRESULT CAboutDlg::AboutSendMsg( WPARAM wp,LPARAM lp )
- {
- HWND hView = (HWND)wp;
- int i = (int)lp;
- CTestUnicodeView *pView = dynamic_cast<CTestUnicodeView*>(CWnd::FromHandle(hView));
- CDC *pDC = pView->GetDC();
- for (i = 0;i<5;i++)
- {
- CString str = _T("字符串来自对话框窗口");
- CRect rt(0,i*20,200,20+i*20);
- pDC->DrawText(str,&rt,DT_CENTER);
- Sleep(2000); // 睡眠2秒,可以更好看到输出
- }
- pView->ReleaseDC(pDC);
- return 0;
- }
- // WM_ABOUTPOSTMSG消息处理函数,在视图上打印5个"字符串来自对话框窗口"
- LRESULT CAboutDlg::AboutPostMsg( WPARAM wp,LPARAM lp )
- {
- HWND hView = (HWND)wp;
- int i = (int)lp;
- CTestUnicodeView *pView = dynamic_cast<CTestUnicodeView*>(CWnd::FromHandle(hView));
- CDC *pDC = pView->GetDC();
- for (i = 0;i<5;i++)
- {
- CString str = _T("字符串来自对话框窗口");
- CRect rt(0,i*20,200,20+i*20);
- pDC->DrawText(str,&rt,DT_CENTER);
- Sleep(2000); // 睡眠2秒,可以更好看到输出
- }
- pView->ReleaseDC(pDC);
- return 0;
- }
试验结果是使用SendMessage给对话框发送消息,先是依次输出5个"字符串来自对话框窗口",再依次输出5个"字符串来自视图窗口"。而使用PostMessage给对话框发送消息,结果相反,先依次输出5个"字符串来自视图窗口",再依次输出5个"字符串来自对话框窗口"。