1.初始化控件
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
…
AtlInitCommonControls ( ICC_WIN95_CLASSES );
…
return nRet;
}
// Common Controls initialization helper
inline BOOL AtlInitCommonControls(DWORD dwFlags)
{
INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags };
BOOL bRet = ::InitCommonControlsEx(&iccx);
ATLASSERT(bRet);
return bRet;
}
2.继承自ATL的CDialogImpl
3.使用DDX,继承自CWinDataExchange
class CMainDlg : public CDialogImpl<CMainDlg>,
public CWinDataExchange<CMainDlg>
{
public:
enum { IDD = IDD_MAINDLG };
CMainDlg();
~CMainDlg();
}
BEGIN_DDX_MAP(CMainDlg)
DDX_CONTROL(IDC_EDIT, m_wndEdit)
DDX_TEXT(IDC_EDIT, m_sEditContents)
DDX_FLOAT(IDC_EDIT, m_fEditFloat)
DDX_FLOAT(IDC_EDIT, m_dEditDouble)
DDX_CHECK(IDC_SHOW_MSG, m_bShowMsg)
DDX_CONTROL(IDC_TREE, m_wndTree)
END_DDX_MAP()
使用Attach方法获取控件句柄
// Attach m_wndList to the list control.
m_wndList.Attach ( GetDlgItem(IDC_LIST) );
4.处理子控件消息
(1)使用Command
COMMAND_ID_HANDLER_EX(ID_APP_ABOUT, OnAppAbout)
COMMAND_ID_HANDLER_EX(IDOK, OnOK)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
(2)使用CContainedWindow
一共需要4个步骤
- 定义CContainedWindow
- 定义消息节点
- 构造CContainedWindow接收特定的消息节点
- 通过子类继承的方式将相关句柄传递给CContainedWindow
CContainedWindow m_wndOKBtn, m_wndExitBtn;
CMainDlg::CMainDlg() : m_wndOKBtn(this, 1), m_wndExitBtn(this, 2)
{
}
ALT_MSG_MAP(1)
MSG_WM_SETCURSOR(OnSetCursor_OK)
ALT_MSG_MAP(2)
MSG_WM_SETCURSOR(OnSetCursor_Exit)
m_wndOKBtn.SubclassWindow ( GetDlgItem(IDOK) );
m_wndExitBtn.SubclassWindow ( GetDlgItem(IDCANCEL) );
(3)空消息处理,可以收到消息不处理
ALT_MSG_MAP(3)
// no msg handlers for the list control
END_MSG_MAP()
(4)使用CWindowImplBaseT的子类继承
调用方法相同,还是SubclassWindow,子窗体自己处理消息,而不是交给父窗体
// CButtonImpl - CWindowImpl-derived class that implements a button. We need a
// class like this to do subclassing or DDX.
class CButtonImpl : public CWindowImpl<CButtonImpl, CButton>
{
BEGIN_MSG_MAP(CButtonImpl)
MSG_WM_SETCURSOR(OnSetCursor)
END_MSG_MAP()
LRESULT OnSetCursor(HWND hwndCtrl, UINT uHitTest, UINT uMouseMsg)
{
static HCURSOR hcur = LoadCursor ( NULL, IDC_SIZEALL );
if ( NULL != hcur )
{
SetCursor ( hcur );
return TRUE;
}
else
{
SetMsgHandled(false);
return FALSE;
}
}
};
CButtonImpl m_wndAboutBtn;
// CButtonImpl: subclass the About button
m_wndAboutBtn.SubclassWindow ( GetDlgItem(ID_APP_ABOUT) );
(5)更新DDX数据状态
调用DoDataExchange方法来更新双向状态