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
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.
c++ mfc custom-controls
add a comment |
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
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.
c++ mfc custom-controls
add a comment |
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
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.
c++ mfc custom-controls
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
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.
c++ mfc custom-controls
c++ mfc custom-controls
asked Nov 15 '18 at 0:57
jslmscajslmsca
5010
5010
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310979%2fmfc-custom-control-not-appearing-on-dialog%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
add a comment |
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.
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
add a comment |
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 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.
edited Nov 15 '18 at 9:52
IInspectable
26.2k54396
26.2k54396
answered Nov 15 '18 at 3:05
Barmak ShemiraniBarmak Shemirani
21.6k42246
21.6k42246
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
add a comment |
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
Thank you. I can get every element to be drawn through the PreSubclassWindow but your last comment "You can also create a child dialog within a main dialog" led me to an easier solution. I don't know why I thought I was limited to one dialog within a dialog but since I'm not, I can just make the Panel a dialog that can be used in various controls so long I create it dynamically in its parent OnInitDialog rather than rely on its parent DDX to instantiate it.
– jslmsca
Nov 15 '18 at 16:57
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310979%2fmfc-custom-control-not-appearing-on-dialog%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown