头文件:
#pragma once#include "StdRes.h"class CMainDialog : public CDialogImpl<CMainDialog>,
public CDialogResize<CMainDialog>
{
public:
enum { IDD = IDD_DIALOG };
enum
{
ID_BTN1 = 2000,
ID_BTN2,
ID_EDT1
}; BEGIN_MSG_MAP(CMainDialog)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CLOSE(OnClose)
MSG_WM_DESTROY(OnDestroy)
COMMAND_ID_HANDLER_EX(ID_BTN1, OnButton1Click)
COMMAND_ID_HANDLER_EX(ID_BTN2, OnButton2Click)
CHAIN_MSG_MAP(CDialogResize<CMainDialog>)
END_MSG_MAP() BEGIN_DLGRESIZE_MAP(CMainDialog)
DLGRESIZE_CONTROL(ID_BTN1, DLSZ_SIZE_X | DLSZ_SIZE_Y)
DLGRESIZE_CONTROL(ID_BTN2, DLSZ_SIZE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ID_EDT1, DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_Y)
END_DLGRESIZE_MAP() BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnClose();
void OnDestroy();
void OnButton1Click(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnButton2Click(UINT uNotifyCode, int nID, CWindow wndCtl);protected:
std::list<CWindow *> m_wndList;
};源文件:
#include "StdAfx.h"
#include "MainDialog.h"BOOL CMainDialog::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
MoveWindow(CRect(0, 0, 0, 160), FALSE); CButton* btn = new CButton;
btn->Create(m_hWnd, CRect(8, 8, 96, 38), _T("按钮一"), WS_CHILD, 0, ID_BTN1);
m_wndList.push_back(btn); CEdit* edt = new CEdit;
edt->Create(m_hWnd, CRect(8, 48, 96, 78), _T("文本"), WS_CHILD, 0, ID_EDT1);
m_wndList.push_back(edt); btn = new CButton;
btn->Create(m_hWnd, CRect(8, 88, 96, 118), _T("按钮二"), WS_CHILD, 0, ID_BTN2);
m_wndList.push_back(btn); std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->ShowWindow(SW_SHOW);
p->SetFont(GetFont());
}); DlgResize_Init();
CenterWindow();
SetMsgHandled(FALSE);
return TRUE;
}void CMainDialog::OnClose()
{
EndDialog(IDOK);
SetMsgHandled(FALSE);
}void CMainDialog::OnDestroy()
{
std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->DestroyWindow();
delete p;
});
m_wndList.clear();
SetMsgHandled(FALSE);
}void CMainDialog::OnButton1Click(UINT uNotifyCode, int nID, CWindow wndCtl)
{
MessageBox(_T("OnButton1Click"));
}void CMainDialog::OnButton2Click(UINT uNotifyCode, int nID, CWindow wndCtl)
{
MessageBox(_T("OnButton2Click"));
}
疑问一:基于CDialogImpl创建对话框时,我将被迫使用一个对话框资源:
#include <Windows.h>#define IDD_DIALOG 1000IDD_DIALOG DIALOGEX 0,0,160,100
FONT 8,"Ms Shell Dlg",0,0,0
STYLE WS_VISIBLE|WS_OVERLAPPEDWINDOW
BEGIN
END不知道ATL或WTL有没有内置的对话框资源ID可用?疑问二:
void CMainDialog::OnDestroy()
{
std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->DestroyWindow();
delete p;
});
m_wndList.clear();
SetMsgHandled(FALSE);
}
在这个函数中,我调用了DestroyWindow()以销毁动态创建的子窗口:不知道是否有这个必要?
我查了CWindow的源码,在析构函数中并没有调用DestroyWindow()。
但由于这个控件是以当前对话框为父窗口的。
不知道在父窗口销毁的时候,是否会销毁所有子窗口?
#pragma once#include "StdRes.h"class CMainDialog : public CDialogImpl<CMainDialog>,
public CDialogResize<CMainDialog>
{
public:
enum { IDD = IDD_DIALOG };
enum
{
ID_BTN1 = 2000,
ID_BTN2,
ID_EDT1
}; BEGIN_MSG_MAP(CMainDialog)
MSG_WM_INITDIALOG(OnInitDialog)
MSG_WM_CLOSE(OnClose)
MSG_WM_DESTROY(OnDestroy)
COMMAND_ID_HANDLER_EX(ID_BTN1, OnButton1Click)
COMMAND_ID_HANDLER_EX(ID_BTN2, OnButton2Click)
CHAIN_MSG_MAP(CDialogResize<CMainDialog>)
END_MSG_MAP() BEGIN_DLGRESIZE_MAP(CMainDialog)
DLGRESIZE_CONTROL(ID_BTN1, DLSZ_SIZE_X | DLSZ_SIZE_Y)
DLGRESIZE_CONTROL(ID_BTN2, DLSZ_SIZE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ID_EDT1, DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_Y)
END_DLGRESIZE_MAP() BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam);
void OnClose();
void OnDestroy();
void OnButton1Click(UINT uNotifyCode, int nID, CWindow wndCtl);
void OnButton2Click(UINT uNotifyCode, int nID, CWindow wndCtl);protected:
std::list<CWindow *> m_wndList;
};源文件:
#include "StdAfx.h"
#include "MainDialog.h"BOOL CMainDialog::OnInitDialog(CWindow wndFocus, LPARAM lInitParam)
{
MoveWindow(CRect(0, 0, 0, 160), FALSE); CButton* btn = new CButton;
btn->Create(m_hWnd, CRect(8, 8, 96, 38), _T("按钮一"), WS_CHILD, 0, ID_BTN1);
m_wndList.push_back(btn); CEdit* edt = new CEdit;
edt->Create(m_hWnd, CRect(8, 48, 96, 78), _T("文本"), WS_CHILD, 0, ID_EDT1);
m_wndList.push_back(edt); btn = new CButton;
btn->Create(m_hWnd, CRect(8, 88, 96, 118), _T("按钮二"), WS_CHILD, 0, ID_BTN2);
m_wndList.push_back(btn); std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->ShowWindow(SW_SHOW);
p->SetFont(GetFont());
}); DlgResize_Init();
CenterWindow();
SetMsgHandled(FALSE);
return TRUE;
}void CMainDialog::OnClose()
{
EndDialog(IDOK);
SetMsgHandled(FALSE);
}void CMainDialog::OnDestroy()
{
std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->DestroyWindow();
delete p;
});
m_wndList.clear();
SetMsgHandled(FALSE);
}void CMainDialog::OnButton1Click(UINT uNotifyCode, int nID, CWindow wndCtl)
{
MessageBox(_T("OnButton1Click"));
}void CMainDialog::OnButton2Click(UINT uNotifyCode, int nID, CWindow wndCtl)
{
MessageBox(_T("OnButton2Click"));
}
疑问一:基于CDialogImpl创建对话框时,我将被迫使用一个对话框资源:
#include <Windows.h>#define IDD_DIALOG 1000IDD_DIALOG DIALOGEX 0,0,160,100
FONT 8,"Ms Shell Dlg",0,0,0
STYLE WS_VISIBLE|WS_OVERLAPPEDWINDOW
BEGIN
END不知道ATL或WTL有没有内置的对话框资源ID可用?疑问二:
void CMainDialog::OnDestroy()
{
std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->DestroyWindow();
delete p;
});
m_wndList.clear();
SetMsgHandled(FALSE);
}
在这个函数中,我调用了DestroyWindow()以销毁动态创建的子窗口:不知道是否有这个必要?
我查了CWindow的源码,在析构函数中并没有调用DestroyWindow()。
但由于这个控件是以当前对话框为父窗口的。
不知道在父窗口销毁的时候,是否会销毁所有子窗口?
2、不需要,销毁窗口时会自动销毁其全部子窗口(具有WS_CHILD风格)。
{
delete this;
}OnFinalMessage是个虚函数。
可以参考MFC的一些代码。
既不想用资源文件,你干脆不用对话框,把CDialogImpl换成CWindowImpl,直接用普通窗口。(普通窗口也可以容得下你所有的控件)
2.父窗口在要挂之前,会把它的child统统Destroy掉
还没试过能否把这个类用在CWindowImpl上。
重新学习WTL,还没入门。发现CDialogResize可以应用在CWindowImpl上的。
头文件:
#pragma onceclass CMainFrame : public CFrameWindowImpl<CMainFrame>,
public CDialogResize<CMainFrame>
{
public:
DECLARE_FRAME_WND_CLASS(_T("Wtl Window Class"), 0) enum
{
ID_BTN1 = 2000,
ID_BTN2,
ID_EDT1
}; BEGIN_MSG_MAP(CMainFrame)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestroy)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
CHAIN_MSG_MAP(CDialogResize<CMainFrame>)
END_MSG_MAP() BEGIN_DLGRESIZE_MAP(CMainFrame)
DLGRESIZE_CONTROL(ID_BTN1, DLSZ_SIZE_X | DLSZ_SIZE_Y)
DLGRESIZE_CONTROL(ID_BTN2, DLSZ_SIZE_X | DLSZ_MOVE_Y)
DLGRESIZE_CONTROL(ID_EDT1, DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_Y)
END_DLGRESIZE_MAP() int OnCreate(LPCREATESTRUCT lpCreateStruct);
void OnDestroy();
void OnFinalMessage(HWND hWnd);protected:
std::list<CWindow *> m_wndList;
};源文件:
#include "StdAfx.h"
#include "MainFrame.h"int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
MoveWindow(CRect(0, 0, 0, 160), FALSE); CButton* btn = new CButton;
btn->Create(m_hWnd, CRect(8, 8, 96, 38), _T("按钮一"), WS_CHILD, 0, ID_BTN1);
m_wndList.push_back(btn); CEdit* edt = new CEdit;
edt->Create(m_hWnd, CRect(8, 48, 96, 78), _T("文本"), WS_CHILD, 0, ID_EDT1);
m_wndList.push_back(edt); btn = new CButton;
btn->Create(m_hWnd, CRect(8, 88, 96, 118), _T("按钮二"), WS_CHILD, 0, ID_BTN2);
m_wndList.push_back(btn); std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->ShowWindow(SW_SHOW);
p->SetFont(AtlGetDefaultGuiFont());
}); DlgResize_Init(false);
CenterWindow();
SetMsgHandled(FALSE);
return 0;
}void CMainFrame::OnDestroy()
{
MessageBox(_T("OnDestroy"));
SetMsgHandled(FALSE);
}void CMainFrame::OnFinalMessage(HWND hWnd)
{
std::for_each(m_wndList.begin(), m_wndList.end(), [](CWindow *p)
{
delete p;
});
m_wndList.clear();
}
区别:
DlgResize_Init(false); // 这里传false,因为背景色不一样[/code
另:
[code=C/C++]std::for_each(m_wndList.begin(), m_wndList.end(), [this](CWindow *p)
{
p->ShowWindow(SW_SHOW);
p->SetFont(AtlGetDefaultGuiFont());
});
要用AtlGetDefaultGuiFont()来获取字体。
标记一下!!