我对CButton进行子类化的尝试有什么问题?

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年的代码.

我在这做错了什么?我现在真的迷路了.

Bar*_*ani 6

按钮类应定义如下:

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)