创建MFC控件的子类的正确方法是什么?

5
我们使用资源编辑器来布局对话框。假设我有一个名为IDC_RICH的RichEditCtrl控件,并且我想将它链接到自定义类CMyRichEditCtrl :CRichEditCtrl的实例,同时又不失去在资源编辑器中设置属性的能力。
正确的方式是什么?您可以通过创建DDX链接变量并将其类型更改为CMyRichEditCtrl来获得一些功能。但在某些情况下,我看到人们调用如下代码:
m_Rich.SubclassDlgItem(IDC_RICH, this));

有什么区别吗?

编辑:我遇到的一个问题是,当我覆盖Create(Ex)方法时,它们不会被调用。这有点像在我的对象被链接到资源标识符时控件已经被创建了,也许是这样吗?

3个回答

7
DDX_Control()在底层执行SubclassWindow()SubclassDlgItemSubclassWindow(GetDlgItem())的快捷方式。通常情况下(这里是广义概括),使用SubclassWindow的人是那些在DDX_Control出现之前就养成了这个习惯(大约在1995年之前?)并且从未真正进入MFC模式,或者是从各种博客片段中复制和粘贴他们的程序的人。

因此,为了清晰明了,请使用DDX_Control(),尽管如果您使用SubclassDlgItem()也不会有太大区别。


4
使用资源编辑器放置在对话框上的窗口是通过使用CreateWindow(Ex)创建的,第一个参数设置为.rc文件中指定的类名。DDX_机制然后将此实例化的窗口与DoDataExchange()中的对话框类成员关联起来。
MFC是Win32的一层封装,但MFC开发并不能完全屏蔽Win32。它更像是一堆类和方法,可以减少MFC的繁琐工作,并提供某种形式的面向对象性。MFC对象的方法不是真正执行实际工作的方法,许多框架都在幕后执行操作,并且除非明确连接,否则不会通知“上层”(即MFC对象)。Create()是这样一种方法,仅在您想要手动创建控件时才存在,MFC在创建对象时不会调用它。(这是一般情况,因为有时会调用,但超出了本讨论的范围)。

你说的 class-name 是指 Window 类,而不是 C++ 类?如果我创建一个具有自己 Window 类名的自定义控件,它是否仍会允许我在资源编辑器中更改基本属性?或者只会显示为一个大灰色框? - Mr. Boy
是的,窗口类是CreateWindow()函数的第一个参数。如果没有编写显式支持代码,您无法将自定义控件放入资源编辑器中。这就是VS工具箱中“自定义控件”条目的作用。您可以设置一些属性,例如启用和标题,但这非常基本。(我所说的“自定义控件”是指“派生自CWnd”,而不是从另一个控件派生;如果您这样做,您可以在资源编辑器中设置属性,因为资源编辑器不会知道新控件或该控件的窗口类名)。 - Roel

2

1> 对于在资源编辑器上放置的控件,使用 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> 对于手动创建的控件:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接