上一篇 | 下一篇

WTL for MFC Programming实践篇 --- 一个自定义ComboBox的移植过程(上)

发布: 2008-6-26 11:25 | 作者: admin | 来源: | 查看: 13次

WTL for MFC Programming实践篇

--- 一个自定义ComboBox的移植过程

现在有一个MFC写的自定义ComboBox打算移植到WTL上,于是根据WTL的书写方法修改了程序,就得到下面的代码:

Class CComboBoxEx : public CComboBox

{

protected:

void OnDrawItem(UINT wParam, LPDRAWITEMSTRUCT lpDrawItemStruct);

public:

BEGIN_MSG_MAP_EX(CComboBoxEx)

MSG_OCM_DRAWITEM(OnDrawItem)

END_MSG_MAP()

}

Class CMainDlg : public CDialogImpl< CMainDlg >

{

Protected:

CComboBoxEx m_cmbEx;

Public:

BEGIN_DDX_MAP(CPageConfigFont)

DDX_CONTROL_HANDLE(IDC_COMBOBOXEX, m_cmbEx);

END_DDX_MAP()

BEGIN_MSG_MAP_EX(CPageConfigFont)

MSG_WM_INITDIALOG(OnInitDialog)

REFLECT_NOTIFICATIONS()

END_MSG_MAP()

}

如何生成以上代码及代码的含义,原书都有介绍,由于不是本文的重点,不再一一解释。

要说的是,在WTL 7.1中添加了DDX_CONTROL_HANDLE宏,可以用来设置控件,与DDX_CONTROL不同的是,它不要求控件类由CWindowImpl派生,即不需要包含SubclassWindow()函数,这样我们才可以使用DDX来设置我们从CComboBox派生的类(听上去很有道理,其实却是在MFC编程习惯带动下错误思维)。

当然,要实现还有一个小小的问题,DDX_CONTROL_HANDLE宏需要我们的类包含一个操作符“=”,怎么写这个函数呢?参看了一下基类的实现方法:

CComboBoxExT< TBase >& operator =(HWND hWnd)

{

m_hWnd = hWnd;

return *this;

}

参看WTL文件

原来只是将m_hWnd赋值,于是我们在我们的类中添加如下的代码:

CComboBoxEx& operator=(HWND hWnd)

{

m_hWnd = hWnd;

return *this;

}

于是编译通过了。(殊不知潜在的错误就这样被深深的埋起来了)

可是为什么DDX_CONTROL_HANDLE宏需要我们的类包含操作符“=”呢?我们来看看DDX_CONTROL_HANDLE宏是怎么实现的:

整个DDX_MAP其实是定义了一个DoDataExchange函数,BEGIN_DDX_MAP宏定义了函数头,而END_DDX_MAP定义了函数尾,中间一项项的DDX定义函数的具体内容,而当你在代码中定义DDX_MAP的时候就等于重载了CWinDataExchange::DoDataExchange()函数,具体代码如下:

#define BEGIN_DDX_MAP(thisClass) \

BOOL DoDataExchange(BOOL bSaveAndValidate = FALSE, UINT nCtlID = (UINT)-1) \

{ \

bSaveAndValidate; \

nCtlID;

#define END_DDX_MAP() \

return TRUE; \

}

参看WTL文件

对于DDX_CONTROL_HANDLE宏,它其实是调用了CWinDataExchange:: DDX_Control_Handle函数,具体代码如下:

// Simple control attaching (for HWND wrapper controls)

template

void DDX_Control_Handle(UINT nID, TControl& ctrl, BOOL bSave)

{

if(!bSave && ctrl.m_hWnd == NULL

字号: | 推荐给好友

41/41234>

评分:0

我来说两句