简体   繁体   中英

MFC Custom Control Not Appearing On Dialog

Using Visual Studio 2013, I created a dialog resource using the resource editor. 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.

I used the following example: https://www.codeproject.com/Articles/521/Creating-Custom-Controls

The parent's DDX gets hit and the _panel is properly instantiated:

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. 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()?

I also noticed that none of the member buttons are instantiated in the Panel like would normally happen in a dialog's DoDataExchange method. Instead, I've had to resort to dynamically creating each of the control's inside the Panel's PreSubclassWindow() method:

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.

Any help is appreciated. Thanks.

The article says override OnPaint and OnEraseBkgnd if you want to change the functionality. 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. 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

You are adding _groupBox to _panel . And you are adding _panel to the MyDialog .

MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)} is needed to invoke SubclassWindow for _panel . That in turn calls _groupBox.Create .

If MyPanel::OnPaint and MyPanel::PreSubclassWindow are not doing anything MyPanel appears as a blank control.

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

You can directly add _groupBox to the main dialog. But if you want to add specific controls within MyPanel then you have to do it manually.

You can also create a child dialog within a main dialog. For example that's how a tab control works.

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