Sos*_*der 3 c++ winapi wtl atl
我试图第一次创建一个子类控件,但我觉得我做错了.控件是一个Button,我放在设计器中.这是它的类:
class TTTField : public CButton
{
public:
BEGIN_MSG_MAP_EX(TTTField)
MSG_WM_INITDIALOG(OnInitDialog);
END_MSG_MAP()
TTTField operator=(const CWindow& btn);
private:
const BOOL OnInitDialog(const CWindow wndFocus, const LPARAM lInitParam);
};
Run Code Online (Sandbox Code Playgroud)
到目前为止没什么好看的.
但是,我无法真正实现在此控件中接收Windows消息.这很糟糕,考虑到尝试子类化控件的主要原因是这应该是一个可重用的类,具有可重用的自定义Paint行为.我想覆盖某些消息处理程序,同时保留那些我没有明确要求通常的CButton例程.
正如您所看到的,我实现了一个消息映射,但消息并没有进入.
这是我尝试设置此类的实例的方法:
TTTField fld;
Run Code Online (Sandbox Code Playgroud)
是我的主对话框类的成员变量.在本课程中,我添加了以下DDX_MAP:
BEGIN_DDX_MAP(TTTMainDialog)
DDX_CONTROL_HANDLE(IDC_BTN, fld)
END_DDX_MAP()
Run Code Online (Sandbox Code Playgroud)
IDC_BTN是设计器上按钮的id.
在TTTField的赋值运算符重载中,我有以下内容:
TTTField TTTField::operator=(const CWindow& btn)
{
Attach(btn);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
我觉得这个运算符重载可能是我的问题的根源,但我无法找到一个正确解释整个主题的网站,而不使用似乎过时了20年的代码.
我在这做错了什么?我现在真的迷路了.
按钮类应定义如下:
class TTTField : public CWindowImpl<TTTField, CButton>
{
protected:
BEGIN_MSG_MAP_EX(TTTField)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
END_MSG_MAP()
protected:
LRESULT OnLButtonDown(UINT, CPoint)
{
//Edit: this override is meant for testing the subclass only
//it's insufficient for handling button clicks
MessageBox(L"Testing override...");
return 0;
}
};
Run Code Online (Sandbox Code Playgroud)
覆盖对话框OnInitDialog,调用SubclassWindow子类按钮:
class TTTMainDialog: public CDialogImpl<CMainDialog>
{
public:
enum { IDD = IDD_MYDIALOG };
BEGIN_MSG_MAP(TTTMainDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
END_MSG_MAP()
TTTField fld;
LRESULT OnInitDialog(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
fld.SubclassWindow(GetDlgItem(IDC_BTN));
return 0;
}
};
Run Code Online (Sandbox Code Playgroud)
编辑,进行初始化
class TTTField : public CWindowImpl<TTTField , CButton>
{
public:
void Create(CWindow *wnd, int id)
{
SubclassWindow(wnd->GetDlgItem(id));
//add initialization here
}
...
}
Run Code Online (Sandbox Code Playgroud)
然后创建按钮:
//fld.SubclassWindow(GetDlgItem(IDC_BTN));
fld.Create(this, IDC_BTN); //<== use this instead
Run Code Online (Sandbox Code Playgroud)