HWND hwnd; 
BOOL fDone; 
MSG msg; 
 
// Begin the operation and continue until it is complete 
// or until the user clicks the mouse or presses a key. 
 
fDone = FALSE; 
while (!fDone) 

    fDone = DoLengthyOperation(); // application-defined function 
 
    // Remove any messages that may be in the queue. If the 
    // queue contains any mouse or keyboard 
    // messages, end the operation. 
 
    while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) 
    { 
        switch(msg.message) 
        { 
            case WM_LBUTTONDOWN: 
            case WM_RBUTTONDOWN: 
            case WM_KEYDOWN: 
                // 
                // Perform any required cleanup. 
                // 
                fDone = TRUE; 
        } 
    } 

上述msdn的这段话是什么意思呢?DoLengthyOperation();这个耗时的操作也要先执行完了才行啊。还是有别的玄机。还有我想知道下面是如何实现的,能讲解一下吗
在单线程程序中,如果要执行一个长时间的复杂操作而且界面要有相应的话,可以考虑用自己的消息泵。比如,可以将一个阻塞等待操作放在一个循环中,并将超时值设置得比较小,然后每个等待的片段中用消息泵继续消息循环,使界面能够响应用户操作。等等之类,都可以应用消息泵(调用一个类似这样的函数):BOOL CChildView::PeekAndPump()
{
 MSG msg;
 while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
 {
  if(!AfxGetApp()->PumpMessage())
  {
   ::PostQuitMessage(0);
   return false;
  }
 } 
 return true;
}
mfc消息循环peekmessage

解决方案 »

  1.   

    前个例子DoLengthyOperation函数本身是很快返回的,但是其所谓漫长的操作意思是一次操作可能没有全部完成,下个循环调用该函数继续该操作,比如复制文件,每次调用就复制一个,循环多次才复制完成。这么做的目的是把操作分次,以使得函数能够返回,通过消息循环避免界面的死锁,比如函数中修改了数据来刷新窗口,这时窗口就可以更新。
    第二种方式更加常用些,比如还是一个长时间操作,现在用循环,每次循环调用一下PeekAndPump函数,窗口消息泵就不会死锁。
      

  2.   

     第一个函数,我想你说的可能是,漫长操作必须是复制文件,IO操作,网络连接等这类,而且最重要的就是在操作中设置一个退出时间,每次执行了这个时间后,就返回函数。  while (PeekMessage(&msg, hwnd,  0, 0, PM_REMOVE)) 这个循环的作用就是响应消息,只要不是上述三个消息,就默认处理这些消息以实现用户的响应。
    第二种方式的的长时间操作也是上面那个意思吧,那么这两种方式就是一样的。有什么不一样吗BOOL CChildView::PeekAndPump()
    {
     MSG msg;
     while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
     {
      if(!AfxGetApp()->PumpMessage())
      {
       ::PostQuitMessage(0);
       return false;
      }
     } 
     return true;
    具体都是什么意思,如何实现那功能的。
    感谢各位大神啊!
      

  3.   

    我看你看得就是MSDN,那里不是解释得很明白了么,具体每个函数干嘛自己再查一下。
      

  4.   

     if(!AfxGetApp()->PumpMessage())//As long as that call returns a nonzero value, the loop calls CWinThread::PumpMessage to perform normal message translation and dispatching.上面是说循环获取队列中的消息,然后处理这些消息。当没有消息的时候,也就是空闲的时候,返回true。这样下面就可以处理空闲时的清理工作了。但是处理空闲工作的时候,必须设定一个超时时间。每隔这段时间来检查没有消息进来,便进行处理。没有就继续执行空闲操作。
      

  5.   

    还有我想知道下面是如何实现的,能讲解一下吗
     在单线程程序中,如果要执行一个长时间的复杂操作而且界面要有相应的话,可以考虑用自己的消息泵。比如,可以将一个阻塞等待操作放在一个循环中,并将超时值设置得比较小,然后每个等待的片段中用消息泵继续消息循环,使界面能够响应用户操作。等等之类,都可以应用消息泵(调用一个类似这样的函数):BOOL CChildView::PeekAndPump()
     {
     MSG msg;
     while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
     {
      if(!AfxGetApp()->PumpMessage())
      {
       ::PostQuitMessage(0);
       return false;
      }
     } 
     return true;
     }
    这个PeekAndPump所实现的功能,实际上就是MFC框架定义的函数PumpMessage的雏形。你可以直接在循环中调用PumpMessage来实现在繁忙的循环中响应界面消息。比如在一个一万次的循环处理中加入PumpMessage的调用。这样每循环一次就会检查有没有消息,有的话就处理完这些消息再继续循环
      

  6.   

    还有一个问题很奇怪,求解释:
    AfxGetMainWnd()->EnableWindow(FALSE);
    while(::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
    { } 我把窗口EnableWindow了,应该是说窗口不能接受消息;Enables or disables mouse and keyboard input to the specified window or control.但是::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)这句话就永不返回false了。意思就是一直有消息在产生,我调试也发现了,消息一直都在变化,就是不完。