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.