ATL中有三个模板类可用于创建一个对话框:
(1)CSimpleDialog:创建模式对话框, 可以host Windows Controls
template < WORD t_wDlgTemplateID, BOOL t_bCenter = TRUE >
class CSimpleDialog : public CDialogImplBase
(2)CDialogImpl:创建模式或非模式对话框, 可以host Windows Controls
template < class T, class TBase = CWindow >
class ATL_NO_VTABLE CDialogImpl : public CDialogImplBaseT< TBase >
(3)CAxDialogImpl:创建模式或非模式对话框, 可以host Windows Controls和ActiveX Controls
template < class T, class TBase = CWindow >
class ATL_NO_VTABLE CAxDialogImpl : public CDialogImplBaseT< TBase >
用CSimpleDialog和CDialogImpl不能显示含有ActiveX控件的对话框,只有CAxDialogImpl可以。如果想处理对话框中ActiveX控件的事件,在OnInitDialog()中加入AtlAdviseSinkMap(this, TRUE)。在退出时加入 AtlAdviseSinkMap(this, FALSE)。通过Insert/New ATL Object/miscellaneous/Dialog生成的对话框缺省就是从CAxDialogImpl继承的。
这三个类的使用方法很类似。都是派生出一个新类,并确保有一个IDD的成员指明资源ID。如:
class CMyDialog : public CDialogImpl, ...
{
public:
enum { IDD = IDD_MYDIALOG }; //必须要有IDD这个成员,一般都是enum型
BEGIN_MSG_MAP(CMyDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
END_MSG_MAP()
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return 1;
}
};
CMyDialog dlg ;
dlg.DoModal() ;
CSimpleDialog的使用可以更简单一些,如下:
CSimpleDialog< IDD_MYDIALOG > dlg ;
dlg.DoModal() ;
另外CSimpleDialog对IDOK和IDCANCEL有内在的支持,即会自动调用EndDialog,在其定义中包含如下代码:
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_RANGE_HANDLER(IDOK, IDNO, OnCloseCmd)
END_MSG_MAP()
......
LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
::EndDialog(m_hWnd, wID);
return 0;
}
但CDialogImpl和CAxDialogImpl没有内在的支持,所以必须自己加消息处理函数调用EndDialog,比如:
COMMAND_ID_HANDLER(IDOK, OnOK)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
EndDialog(wID);
return 0;
}
LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
EndDialog(wID);
return 0;
}