我第一次尝试创建一个子类控件,但我觉得我做错了什么。控件是一个按钮,我放在设计器中。这是它的类:
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);
};
到目前为止没有什么特别的。
但是,我无法真正实现在这个控件中接收windows消息。这很糟糕,考虑到尝试对控件进行子类化的主要原因是这应该是一个具有可重用、自定义 Paint 行为的可重用类。我想覆盖某些消息处理程序,同时保留那些我没有明确要求的常规 CButton 例程。
如您所见,我实现了一个消息映射,但消息就是收不到。
这就是我尝试设置此类实例的方式:
TTTField fld;
是我的主对话框类的成员变量。在这个类中,我添加了以下 DDX_MAP:
BEGIN_DDX_MAP(TTTMainDialog)
DDX_CONTROL_HANDLE(IDC_BTN, fld)
END_DDX_MAP()
IDC_BTN 是设计器上按钮的 ID。
在 TTTField 的赋值运算符重载中,我有以下内容:
TTTField TTTField::operator=(const CWindow& btn)
{
Attach(btn);
return *this;
}
我觉得这个运算符过载可能是我问题的根源,但我就是无法找到一个网站来正确解释整个主题,而不使用似乎已经过时 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;
}
};
重写对话框的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;
}
};
编辑,用于初始化
class TTTField : public CWindowImpl<TTTField , CButton>
{
public:
void Create(CWindow *wnd, int id)
{
SubclassWindow(wnd->GetDlgItem(id));
//add initialization here
}
...
}
然后创建按钮:
//fld.SubclassWindow(GetDlgItem(IDC_BTN));
fld.Create(this, IDC_BTN); //<== use this instead
关于c++ - 我对 CButton 进行子类化的尝试有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39428266/