先看下MSDN对OnIdle()介绍:

CWinApp::OnIdle

OnIdle is called in the default message loop when the application's message queue is

empty. Use your override to call your own background idle-handler tasks.

     对于一般桌面应用程序中比较少重载这个函数。对于像是视频游戏这一块确有不少用处。在Win32 SDK的开发环境中,通过在消息循环中添加自已的render()等接口来使自已的程序核心运转起来,这也是常用的一种办法。来到MFC的环境中,保证程序运转的核心循环已经被整合到MFC中去了,这时侯要想将自已的接口函数可以合理的插进MFC的循环结构中,那么这个OnIdle()就是一个非常好的地方,在这儿你可以让你的代码获的足够的运行机会。先看看MSDN中对MFC的程序中Idle状态的处理:

 

    对CWinApp::OnIdle进行重载,返回非零值代表还有Idle Task任务要处理,这样下次OnIdle()仍然会继续执行。在你重载CWinApp::OnIdle()时,不要忘记要先调用CWinApp::OnIdle()进行MFC默认处理:

 if (CWinApp::OnIdle(lCount))
      return TRUE; 

如果忘掉了的话,你会发现一些MFC的UI会出现问题,比如菜单上的选择状态无法更新等问题。

 

 再下面加上你自已的处理函数即可:

YourMethod();

return TRUE; // 需要更多次的执行。。。

 

    对于MFC程序来讲,很多是采用MFC的文档视图类的框架。比如如果你要让视图不断刷新,在这个不断刷新的视图中可以完成场景渲洒更新等操作。你当然可以在 YourMethod()获取视图的pView的指针,然后调用其内的接口函数, 就像这样:

 CMainFrame *parent = (CMainFrame *)AfxGetMainWnd();

 if ( parent && parent->GetSafeHwnd() )
 { 
   CFrameWnd* pFrame = parent->GetActiveFrame();

       CView *pView = pFrame->GetActiveView();
       if ( pView )
      {
         pView->Invalidate();
       }
  
 }

 

但这会明显的让你的程序和MFC的框架不那么配套,MFC的文档视图结构的设计思想并没有体现出来。当然这样做也没什么错。类似这样的写法也是可以正常工作的。

 

 

     如果你查看过MFC文档类CDocument的话,你会发现它也有一个虚函数叫OnIdle(),很明显这个函数就是让你完成文档视图在Idle时期的处理工作的地方。你完全在其中可以这样写: 

POSITION pos = GetFirstViewPosition();
while ( pos != NULL )
{
  CView* pView = GetNextView( pos );
  pView->Invalidate();
    pView->UpdateWindow();
 }  

通过在文档的OnIdle中进行处理是更合适的地方。但是同样需要在CWinApp::OnIdle重载函数中进行一些处理:

 // In this example, as in most applications, you should let the
 // base class CWinApp::OnIdle complete its processing before you
 // attempt any additional idle loop processing.
 if ( CWinApp::OnIdle(lCount) )
   return TRUE;

 

CWinAppEx::OnIdle(0);

return TRUE;

你也许会问为什么要加上这句 CWinAppEx::OnIdle(0):加这句的目的其实我是希望调用MFC默认的对文档视图OnIdle的处理,也就是借用下面一段代码:

 // call doc-template idle hook
 POSITION pos = NULL;
 if ( m_pDocManager != NULL )
  pos = m_pDocManager->GetFirstDocTemplatePosition();

 while ( pos != NULL )
 {
    CDocTemplate* pTemplate = m_pDocManager->GetNextDocTemplate(pos);
    ASSERT_KINDOF( CDocTemplate, pTemplate );
    pTemplate->OnIdle();
 }

 

你完全可以用上面的代码代替CWinAppEx::OnIdle(0)这句。

 

至此关于MFC中OnIdle的使用介绍已经完了。很多具体的东西还是需要深入MFC的具体实现当中去看。

 

 

 

 

 

 

 

 

posted on 2011-01-08 16:01  操作系统  阅读(1743)  评论(0编辑  收藏  举报