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

时间:2018-11-15 00:57:32

标签: c++ mfc custom-controls

使用Visual Studio 2013,我使用资源编辑器创建了一个对话框资源。它是一个无边框的子控件,只是单选按钮,按钮和静态文本的集合。我想将其转换为自定义控件,以便将其放置在几个不同的位置。我们称其为“面板”。

然后,我创建了一个常规对话框,并使用“自定义控件”工具箱为面板定义了一个区域。面板会自行注册并具有有效的窗口句柄。

我使用以下示例: 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)方法,因此Panel类具有这些方法,但它们为空。我没有任何自定义绘画内容,因为面板只包含常规按钮。

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

我还注意到,面板中没有实例化成员按钮,就像在对话框的DoDataExchange方法中通常会发生那样。相反,我不得不求助于在Panel的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()
}

当我已经在资源编辑器中定义/设计了Panel及其每个控件时,为什么需要这样做?

如果我未在PreSubclassWindow方法中执行此操作,则对话框中将不显示任何内容。

感谢您的帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

文章说,如果您想更改功能,请覆盖OnPaintOnEraseBkgnd。它并不表示您必须始终重写。

只需删除ON_WM_PAINTON_WM_ERASEBKGND,如果不需要,则删除OnPaintOnEraseBkgnd。或在不进行任何更改的情况下调用基类实现:

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

这将显示一个空白控件,其中没有任何控件,除非您像在_panel中那样向MyPanel:PreSubclassWindow添加一个子窗口

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

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

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

  

...对每个对话框元素都执行此操作???似乎有点过分...

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

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