简体   繁体   中英

What's the correct way to create a subclass of a MFC control?

We layout dialogs using the resource editor. So say I have a RichEditCtrl called IDC_RICH. And I want to link it to an instance of a custom class CMyRichEditCtrl : CRichEditCtrl , without losing the ability to set properties on it in resource editor.

What's the right way? You can certainly get some functionality by creating a DDX-linked variable, and changing the type to CMyRichEditCtrl . But in some cases I see people calling code like:

m_Rich.SubclassDlgItem(IDC_RICH, this));

What's the difference?

EDIT: One problem I'm seeing is that when I override Create(Ex) methods, they don't get called. It's kind of like the control is already created by the time my object gets linked to the resource identifier, pehaps?

DDX_Control() does SubclassWindow() under the hood. SubclassDlgItem is a shortcut for SubclassWindow(GetDlgITem()) . Usually (broad generalisation here) the people using SubclassWindow are the ones who picked up that habit before DDX_Control existed (pre-1995 or so?) and never really got into MFC-mode, or people who copy and paste their programs together from blog snippets left and right.

So, use DDX_Control() for clarity, although it will technically not make a difference if you use SubclassDlgItem() .

The windows you put on a dialog with the resource editor are created using CreateWindow(Ex) with the first argument set to the class name that is specified in the .rc file. The DDX_ mechanism then associates this instantiated window with the dialog class member in DoDataExchange().

MFC is a layer over Win32 but MFC development doesn't completely shield you from Win32. It's more like a bunch of classes and methods that take away some of the drudgery of MFC and provide some form of object-orientedness. The methods of MFC object aren't the ones that are doing the real work, and much of the framework does things under the hood and doesn't notify the 'upper layer' (ie, MFC objects) unless that is explicitly hooked up. Create() is such a method that is only there if you want to manually create a control, it's not called by MFC when the object is created. (this is a generalization because sometimes it is, but that's outside of the scope of this discussion).

1> For controls that you put on a dialog with the resource editor, used DDX_Control:

class CMyDlg : public CDialogEx
{

protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

public:
    CRichEditCtrl m_Rich;
};

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_RICHEDIT1, m_Rich);
}

2> For controls that create manually:

CRichEditCtrl m_Rich; m_Rich.Create(...); m_Rich.SubclassDlgItem(IDC_RICH, this));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM