MFC 自定义控件未出现在对话框中

MFC Custom Control Not Appearing On Dialog

使用Visual Studio 2013,我使用资源编辑器创建了一个对话框资源。它是一个没有边框的子控件,只是单选按钮、普通按钮和静态文本的集合。我想把它变成一个自定义控件,以便将它放在几个不同的位置。我们称其为 "Panel".

然后我创建了一个常规对话框并使用工具箱 "Custom Control",为面板定义了一个区域。 Panel 自行注册并具有有效的 window 句柄。

我用了下面的例子: https://www.codeproject.com/Articles/521/Creating-Custom-Controls

父级的 DDX 被击中并且 _panel 被正确实例化:

MyDialog::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX)
   DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)
}

我读到我需要覆盖 OnPaint() 和 OnEraseBkgnd(CDC* pDC) 方法,以便面板 class 具有这些方法,但它们是空的。我没有任何自定义绘画要做,因为面板只包含常规按钮。

我必须在 OnPaint() 中包含什么?

我还注意到 none 的成员按钮在面板中被实例化,就像通常在对话框的 DoDataExchange 方法中发生的那样。相反,我不得不求助于在面板的 PreSubclassWindow() 方法中动态创建每个控件:

void MyPanel:PreSubclassWindow()
{
   _groupBox.Create(_T("Options"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, CRect(11, 11, 112, 231), this, IDC_STATIC_GROUPBOX);

   //... do this for every dialog element??? seems like overkill...

   CWnd::PreSubclassWindow()
}

当我已经 defined/designed 资源编辑器中的面板及其每个控件时,为什么还需要这样做?

如果我在 PreSubclassWindow 方法中不这样做,对话框中将不会出现任何内容。

感谢任何帮助。谢谢

文章说如果您想更改功能,请覆盖 OnPaintOnEraseBkgnd。它并不是说你必须总是覆盖。

只需删除 ON_WM_PAINTON_WM_ERASEBKGND,如果不需要,请删除 OnPaintOnEraseBkgnd。或者,如果您不进行任何更改,则调用基础 class 实现:

void MyPanel::OnPaint() { CWnd::OnPaint(); }
BOOL MyPanel::OnEraseBkgnd(CDC* pDC) { return CWnd::OnEraseBkgnd(pDC); }

这将显示一个空白控件,其中没有任何内容,除非您像在 MyPanel:PreSubclassWindow

中那样将子项 window 添加到 _panel

您正在将 _groupBox 添加到 _panel。您正在将 _panel 添加到 MyDialog

需要

MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)} 才能为 _panel 调用 SubclassWindow。依次调用 _groupBox.Create.

如果 MyPanel::OnPaintMyPanel::PreSubclassWindow 没有做任何事情 MyPanel 显示为空白控件。

... do this for every dialog element??? seems like overkill...

您可以直接在主对话框中添加_groupBox。但是如果你想在 MyPanel 中添加特定的控件,那么你必须手动进行。

您还可以在主对话框中创建子对话框。例如,这就是选项卡控件的工作方式。