WEB开发网
开发学院软件开发VC MFC程序员WTL指南(3)WTL界面基类 阅读

MFC程序员WTL指南(3)WTL界面基类

 2008-01-19 20:26:39 来源:WEB开发网   
核心提示:CMessageLoop 的内部实现CMessageLoop为我们的应用程序提供一个消息泵,除了一个标准的DispatchMessage/TranslateMessage循环外,MFC程序员WTL指南(3)WTL界面基类(6),它还通过调用PreTranslateMessage()函数实现了消息过滤机制,通过调用OnI

CMessageLoop 的内部实现

CMessageLoop为我们的应用程序提供一个消息泵,除了一个标准的DispatchMessage/TranslateMessage循环外,它还通过调用PreTranslateMessage()函数实现了消息过滤机制,通过调用OnIdle()实现了空闲处理功能。下面是Run()函数的伪代码:

int Run()
{
MSG msg;
   for(;;)
     {
     while ( !PeekMessage(&msg) )
       DoIdleProcessing();
     if ( 0 == GetMessage(&msg) )
       break;  // WM_QUIT retrieved from the queue
     if ( !PreTranslateMessage(&msg) )
       {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
       }
     }
   return msg.wParam;
}

那些需要过滤消息的类只需要象CMainFrame::OnCreate()函数那样调用CMessageLoop::AddMessageFilter()函数就行了,CMessageLoop就会知道该调用那个PreTranslateMessage()函数,同样,如果需要空闲处理就调用CMessageLoop::AddIdleHandler()函数。

需要注意得是在这个消息循环中没有调用TranslateAccelerator() 或 IsDialogMessage() 函数,因为CFrameWindowImpl在这之前已经做了处理,但是如果你在程序中使用了非模式对话框,那你就需要在CMainFrame::PreTranslateMessage()函数中添加对IsDialogMessage()函数的调用。

CFrameWindowImpl 的内部实现

CFrameWindowImpl 和它的基类 CFrameWindowImplBase提供了对toolbars,rebars, status bars,工具条按钮的工具提示和菜单项的掠过式帮助,这些也是MFC的CFrameWnd类的基本特征。我会逐步介绍这些特征,完整的讨论CFrameWindowImpl类需要再写两篇文章,但是现在看看CFrameWindowImpl是如何处理WM_SIZE和它的客户区就足够了。需要记住一点前面提到的东西,m_hWndClient是CFrameWindowImplBase类的成员变量,它存储主窗口内的“视图”窗口的句柄。

CFrameWindowImpl类处理了WM_SIZE消息:

LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
   if(wParam != SIZE_MINIMIZED)
   {
     T* pT = static_cast<T*>(this);
     pT->UpdateLayout();
   }
   bHandled = FALSE;
   return 1;
}

它首先检查窗口是否最小化,如果不是就调用UpdateLayout(),下面是UpdateLayout():

void UpdateLayout(BOOL bResizeBars = TRUE)
{
RECT rect;
   GetClientRect(&rect);
   // position bars and offset their dimensions
   UpdateBarsPosition(rect, bResizeBars);
   // resize client window
   if(m_hWndClient != NULL)
     ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top,
       rect.right - rect.left, rect.bottom - rect.top,
       SWP_NOZORDER | SWP_NOACTIVATE);
}

注意这些代码是如何使用m_hWndClient得,既然m_hWndClient是一般窗口的句柄,它就可能是任何窗口,对这个窗口的类型没有限制。这一点不像MFC,MFC在很多情况下需要CView的派生类(例如分隔窗口类)。如果你回过头看看CMainFrame::OnCreate()就会看到它创建了一个视图窗口并赋值给m_hWndClient,由m_hWndClient确保视图窗口被设置为正确的大小。

上一页  1 2 3 4 5 6 7 8  下一页

Tags:MFC 程序员 WTL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接