消息积累-CSDN问题整理,以备自己日后查询

来源:互联网 发布:newblue mac 编辑:程序博客网 时间:2024/06/01 14:20

(2008-08-02)jxcyly1985 问:
我想在edit里显示变化的数据,我写了个简单的循环
while(a <10)
{
  a++;
  m_edit=a;
  UpdateData(FALSE);
  //Sleep(500);
}
结果是直接出现了9,我觉得是刷新的太快了,所以加了Sleep(500);可是却是在过了5秒后还是直接显示了9,我想知道UpdateData()的工作原理,有人说是Sleep()暂停了线程的执行,但我是在UpdateData()之后暂停的啊,是不是我对Sleep()理解有误,我知道SetTimer(ID,500,null),SetDlgItemText可以达到我想要的效果,但我想知道为什么这样UpdateData()不行。

 

问题原因消息积累.
UpdateData(FALSE); 并没有发WM_SETTEXT消息, 用的是"::SetWindowText(...)",这样消息队列中是查不到WM_SETTEXT的. 消息积累以后最后只得到一次WM_PAINT.

The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine.

回答1:
int a=0;
while(a <9)
{
   a++;
   m_edit.SetWindowText(CString (a+0x30));
   m_edit.SendMessage(WM_PAINT); //同步的,一定会执行
// m_edit.PostMessage(WM_PAINT);   //异步的,强制发送,不管执行不执行,在消息队列中排队.消息环则需要GetMessage配对
}

 

回答2:

//可以通过下面这段程序检查到底有多少个WM_PAINT消息
BOOL CUpdatetestDlg::PreTranslateMessage(MSG* pMsg)
{
  // TODO: Add your specialized code here and/or call the base class
   static int times=0;
   HWND hWnd;
   GetDlgItem(IDC_EDIT1,&hWnd);
   if((pMsg->message==WM_PAINT) && (pMsg->hwnd==hWnd))
   {
        times++;
        CString prompt;
        prompt.Format("You get WM_PAINT  message :%d times",times);
        AfxMessageBox(prompt);
       // AfxMessageBox("If you can see this message more than once,do tell me!");
   }
   return CDialog::PreTranslateMessage(pMsg);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

回答3:
那么如何查WM_PAINT消息有几个呢?通过增加如下代码:
UpdateData(FALSE);
HWND hWnd;
GetDlgItem(IDC_EDIT1,&hWnd);
MSG msg;
if(PeekMessage(&msg,hWnd,WM_PAINT,WM_PAINT,PM_NOREMOVE))
  afxDump < < a < <":WM_PAINT/n";
可以得到:
1:WM_PAINT
2:WM_PAINT
3:WM_PAINT
4:WM_PAINT
5:WM_PAINT
6:WM_PAINT
7:WM_PAINT
8:WM_PAINT
9:WM_PAINT
这是因为
UpdateData(FALSE)调用"::SetWindowText(...)"后客户区就要重画,所以每次都有WM_PAINT消息.
下面我们看到底那个在起作用?
把代码改成:
if(PeekMessage(&msg,hWnd,WM_PAINT,WM_PAINT,PM_NOREMOVE))
{
   afxDump < < a < <":WM_PAINT/n";
   ValidateRect(0);// 你把这句放if外就不会有WM_PAINT消息了
}
这样一来'9'就不会显示了.
所以我们只去前面的,保留最后一个PAINT:
if(a <8) ValidateRect(0);
这样就正常了,可见系统把9个PAINT改成1个PAINT.这就是消息积累.

其实通过下面语句是可以检查消息队列的:
if(PeekMessage(&msg,hWnd,WM_SETTEXT,WM_SETTEXT,PM_NOREMOVE))
{
 afxDump < < a < <":WM_SETTEXT/n";
}
你会发现根本就没有"WM_SETTEXT"消息

 

 

原文见http://topic.csdn.net/u/20080802/23/f3d42cce-36ff-4d44-ad69-0aae1bacaf9a.html

原创粉丝点击