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

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

 2008-01-19 20:26:39 来源:WEB开发网   
核心提示:调用 UIEnable()现在返回到OnCreate()函数看看是如何设置Clock菜单的初始状态,LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){ m_hWndC

调用 UIEnable()

现在返回到OnCreate()函数看看是如何设置Clock菜单的初始状态。

LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/,
               LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
   m_hWndClient = m_view.Create(...);
 
   // register object for message filtering and idle updates
   // [omitted for clarity]
   // Set the initial state of the Clock menu items:
   UIEnable ( IDC_START, false );
   UIEnable ( IDC_STOP, true );
   return 0;
}

我们的程序开始时Clock菜单是这样的:

CMainFrame现在需要处理两个新菜单项,在视图类调用它们开始和停止时钟时处理函数需要翻转这两个菜单项的状态。这是MFC的内建消息处理无法想象的地方之一。在MFC的程序中,所有的界面更新和命令消息处理必须完整的放在视图类中,但是在WTL中,主窗口类和视图类通过某种方式沟通;菜单由主窗口拥有,主窗口获得这些菜单消息并做相应的处理,要么响应这些消息,要么发送给视图类。

这种沟通是通过PreTranslateMessage()完成的,当然CMainFrame仍然要调用UIEnable()。CMainFrame可以将this指针传递给视图类,这样视图类也可以通过这个指针调用UIEnable()。在这个例子中我选择的这种解决方案导致主窗口和视图成为紧密耦合体,但是我发现这很容易理解(和解释!)。

class CMainFrame : public ...
{
public:
   BEGIN_MSG_MAP_EX(CMainFrame)
     // ...
     COMMAND_ID_HANDLER_EX(IDC_START, OnStart)
     COMMAND_ID_HANDLER_EX(IDC_STOP, OnStop)
   END_MSG_MAP()
   // ...
   void OnStart(UINT uCode, int nID, HWND hwndCtrl);
   void OnStop(UINT uCode, int nID, HWND hwndCtrl);
};
void CMainFrame::OnStart(UINT uCode, int nID, HWND hwndCtrl)
{
   // Enable Stop and disable Start
   UIEnable ( IDC_START, false );
   UIEnable ( IDC_STOP, true );
   // Tell the view to start its clock.
   m_view.StartClock();
}
void CMainFrame::OnStop(UINT uCode, int nID, HWND hwndCtrl)
{
   // Enable Start and disable Stop
   UIEnable ( IDC_START, true );
   UIEnable ( IDC_STOP, false );
   // Tell the view to stop its clock.
   m_view.StopClock();
}

每个处理函数都更新Clock菜单,然后在视图类中调用一个方法,选择在视图类中使用是因为时钟是由视图类控制得。StartClock() 和 StopClock()得代码没有列出,但可以在这个工程得例子代码中找到它们。

消息映射链中最后需要注意的地方

如果你使用VC 6,你会注意到将BEGIN_MSG_MAP改为BEGIN_MSG_MAP_EX后ClassView显得有些杂乱无章:

出现这种情况是因为ClassView不能解释BEGIN_MSG_MAP_EX宏,它以为所有得WTL消息映射宏是函数定义。你可以将宏改回为BEGIN_MSG_MAP并在stdafx.h文件得结尾处添加这两行代码来解决这个问题:

#undef BEGIN_MSG_MAP

#define BEGIN_MSG_MAP(x) BEGIN_MSG_MAP_EX(x)

下一站, 1995

我们现在只是掀起了WTL的一角,在下一篇文章我会为我们的时钟程序添加一些Windows 95的界面标准,比如工具条和状态条,同时体验一下CUpdateUI的新东西。例如试着用UISetCheck()代替UIEnable(),看看菜单项会有什么变化。

修改记录

2003年3月26日,本文第一次发表。

上一页  3 4 5 6 7 8 

Tags:MFC 程序员 WTL

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