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

MFC程序员WTL指南(2)ATL界面类

 2008-01-19 20:26:41 来源:WEB开发网   
核心提示:你可能注意到消息响应函数的到的是原始的WPARAM 和 LPARAM值,你需要自己将其展开为相应的消息所需要的参数,MFC程序员WTL指南(2)ATL界面类(5),还有第四个参数bHandled,这个参数在消息相应函数调用被ATL设置为TRUE,因为所有需要响应消息的类只需使用BEGIN_MSG_MAP宏就足够了,所以

你可能注意到消息响应函数的到的是原始的WPARAM 和 LPARAM值,你需要自己将其展开为相应的消息所需要的参数。还有第四个参数bHandled,这个参数在消息相应函数调用被ATL设置为TRUE,如果在你的消息响应处理完之后需要ATL调用默认的WindowProc()处理该消息,你可以讲bHandled设置为FALSE。这与MFC不同,MFC是显示的调用基类的响应函数来实现的默认的消息处理的。

让我们也添加一个对WM_COMMAND消息的处理,假设我们的窗口有一个ID为IDC_ABOUT的About菜单:

class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CFrameWinTraits>
{
public:
   DECLARE_WND_CLASS(_T("My Window Class"))
   BEGIN_MSG_MAP(CMyWindow)
     MESSAGE_HANDLER(WM_CLOSE, OnClose)
     MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
     COMMAND_ID_HANDLER(IDC_ABOUT, OnAbout)
   END_MSG_MAP()
   LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
     DestroyWindow();
     return 0;
   }
   LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
     PostQuitMessage(0);
     return 0;
   }
   LRESULT OnAbout(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
   {
     MessageBox ( _T("Sample ATL window"), _T("About MyWindow") );
     return 0;
   }
};

需要注意得是COMMAND_HANDLER宏已经将消息的参数展开了,同样,NOTIFY_HANDLER宏也将WM_NOTIFY消息的参数展开了。

高级消息映射链和嵌入类

ATL的另一个显著不同之处就是任何一个C++类都可以响应消息,而MFC只是将消息响应任务分给了CWnd类和CCmdTarget类,外加几个有PreTranslateMessage()方法的类。ATL的这种特性允许我们编写所谓的“嵌入类”,为我们的窗口添加特性只需将该类添加到继承列表中就行了,就这么简单!

一个基本的带有消息映射链的类通常是模板类,将派生类的类名作为模板的参数,这样它就可以访问派生类中的成员,比如m_hWnd(CWindow类中的HWND成员)。让我们来看一个嵌入类的例子,这个嵌入类通过响应WM_ERASEBKGND消息来画窗口的背景。

template <class T, COLORREF t_crBrushColor>
class CPaintBkgnd : public CMessageMap
{
public:
   CPaintBkgnd() { m_hbrBkgnd = CreateSolidBrush(t_crBrushColor); }
   ~CPaintBkgnd() { DeleteObject ( m_hbrBkgnd ); }
   BEGIN_MSG_MAP(CPaintBkgnd)
     MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
   END_MSG_MAP()
   LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
   {
     T*  pT = static_cast<T*>(this);
     HDC dc = (HDC) wParam;
     RECT rcClient;
     pT->GetClientRect ( &rcClient );
     FillRect ( dc, &rcClient, m_hbrBkgnd );
     return 1;  // we painted the background
   }
protected:
   HBRUSH m_hbrBkgnd;
};

让我们来研究一下这个新类。首先,CPaintBkgnd有两个模板参数:使用CPaintBkgnd的派生类的名字和用来画窗口背景的颜色。(t_ 前缀通常用来作为模板类的模板参数的前缀)CPaintBkgnd也是从CMessageMap派生的,这并不是必须的,因为所有需要响应消息的类只需使用BEGIN_MSG_MAP宏就足够了,所以你可能看到其他的一些嵌入类的例子代码,它们并不是从该基类派生的。

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

Tags:MFC 程序员 WTL

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