简体   繁体   English

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

[英]MFC Custom Control Not Appearing On Dialog

Using Visual Studio 2013, I created a dialog resource using the resource editor.使用 Visual Studio 2013,我使用资源编辑器创建了一个对话框资源。 It is a child control with no border and is just a collection of radio buttons, push buttons, and static text.它是一个没有边框的子控件,只是单选按钮、按钮和静态文本的集合。 I want to turn this into a custom control in order to place this in several different locations.我想把它变成一个自定义控件,以便将它放在几个不同的位置。 Let's call this a "Panel".我们称之为“面板”。

I then created a regular dialog and using the Toolbox "Custom Control", defined an area for the Panel.然后我创建了一个常规对话框并使用工具箱“自定义控件”为面板定义了一个区域。 The Panel registers itself and has a valid window handle. Panel 注册自己并有一个有效的窗口句柄。

I used the following example: https://www.codeproject.com/Articles/521/Creating-Custom-Controls我使用了以下示例: https : //www.codeproject.com/Articles/521/Creating-Custom-Controls

The parent's DDX gets hit and the _panel is properly instantiated:父级的 DDX 被命中并且 _panel 被正确实例化:

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

I read that I need to override the OnPaint() and OnEraseBkgnd(CDC* pDC) methods so the Panel class has these but they are empty.我读到我需要覆盖 OnPaint() 和 OnEraseBkgnd(CDC* pDC) 方法,因此 Panel 类具有这些但它们是空的。 I do not have any custom painting to do as the Panel contains nothing but regular buttons.我没有任何自定义绘画要做,因为面板只包含常规按钮。

What do I have to include in OnPaint()?我必须在 OnPaint() 中包含什么?

I also noticed that none of the member buttons are instantiated in the Panel like would normally happen in a dialog's DoDataExchange method.我还注意到,没有像通常在对话框的 DoDataExchange 方法中那样在面板中实例化任何成员按钮。 Instead, I've had to resort to dynamically creating each of the control's inside the Panel's PreSubclassWindow() method:相反,我不得不求助于在面板的 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()
}

Why do I need to do this when I've already defined/designed the Panel and each of its controls in the resource editor?当我已经在资源编辑器中定义/设计了面板及其每个控件时,为什么还需要这样做?

If I do not do this in the PreSubclassWindow method, nothing will appear on the dialog.如果我不在 PreSubclassWindow 方法中执行此操作,则对话框中将不显示任何内容。

Any help is appreciated.任何帮助表示赞赏。 Thanks.谢谢。

The article says override OnPaint and OnEraseBkgnd if you want to change the functionality.文章说如果您想更改功能,请覆盖OnPaintOnEraseBkgnd It doesn't say you have to override always.这并不是说您必须始终覆盖。

Just remove ON_WM_PAINT and ON_WM_ERASEBKGND , remove OnPaint and OnEraseBkgnd if you don't need them.只需删除ON_WM_PAINTON_WM_ERASEBKGND ,如果不需要它们,请删除OnPaintOnEraseBkgnd Or call the base class implementations if you are not making any changes:或者,如果您没有进行任何更改,则调用基类实现:

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

This will show a blank control with nothing in it, unless you add a child window to _panel as you have done in MyPanel:PreSubclassWindow这将显示一个没有任何内容的空白控件,除非您像在MyPanel:PreSubclassWindow所做的那样将子窗口添加到_panel

You are adding _groupBox to _panel .您正在将_groupBox添加到_panel And you are adding _panel to the MyDialog .您正在将_panel添加到MyDialog

MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)} is needed to invoke SubclassWindow for _panel . MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)}需要为_panel调用SubclassWindow That in turn calls _groupBox.Create .这反过来调用_groupBox.Create

If MyPanel::OnPaint and MyPanel::PreSubclassWindow are not doing anything MyPanel appears as a blank control.如果MyPanel::OnPaintMyPanel::PreSubclassWindow未执行任何操作,则MyPanel显示为空白控件。

... do this for every dialog element??? ...对每个对话框元素都这样做??? seems like overkill...好像有点矫枉过正……

You can directly add _groupBox to the main dialog.您可以直接将_groupBox添加到主对话框中。 But if you want to add specific controls within MyPanel then you have to do it manually.但是,如果您想在MyPanel添加特定控件,则必须手动进行。

You can also create a child dialog within a main dialog.您还可以在主对话框中创建子对话框。 For example that's how a tab control works.例如,这就是选项卡控件的工作方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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