Create a dialog-based application in Visual Studio 2019. Insert a new dialog in the resources. Place a control (or two) on that dialog that you will later (try to) hook up to a variable (eg an edit box to enter your name).
Prepare to add that control variable by creating a class for this second dialog. If you inherit from CDialogEx
(or perhaps other classes too - not tested), you can go on to add a variable for the control you added - easy, normal.
But if you had the "tab control" context from the title above in your mind, and chose to inherit from CMFCPropertyPage
instead, can you add a variable subsequently? No you cannot - the class added makes no reference to the ID of the dialog resource, and so the Add Variable process has no basis to find a class to add the variable to.
I think this is a bug in Visual Studio... but I'm not 100% sure because I have always found the documentation around property sheets and property pages somewhat confusing. Specifically:
I believe it's intended to be the former, but I can imagine that one uses a tab control because there are strong similarities between tab contents, and therefore potential benefits in implementing all the control variables in one place so as to avoid duplication. I just wish it was stated explicitly somewhere what the intention was.
Wider context: I'm trying to implement a dialog-based app with a tab control dominating that dialog. MS documentation says to implement a tab control using CPropertySheet
and CPropertyPage
to implement the tabbed dialog and tab contents. However, there is no (direct) way to create a dialog-based application whose main dialog inherits from CPropertySheet
. When you look for examples of tab controls at the application level, you readily find things that deviate from the documented path considerably - using neither CPropertySheet
nor CPropertyPage
and using the WM_LBUTTONDOWN
event instead of TCN_SELCHANGE
, both without obvious reasons.
Any tips on (a) how to repair the apparent Visual Studio bug and/or (b) how to inherit from CPropertySheet
for my application dialog and/or (c) where to find a clearer and more conventional example of tab control use at the top level would be greatly appreciated.
One time, I had made on application as such. I don't remember if I used the Visual Studio new project wizard. Most probably, I did. But I will assist you on how to do it if you can not reach how to do it via the assistant.
The essential things:
Define the main dialog in the resources and the respective class in its H and CPP files.
In the YourAppClass::InitInstance
you will need to have something like:
YourMainDlgClass dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } else if (nResponse == -1) { TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\\n"); TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\\n"); }
Insert a CMFCTabCtrl
element in your dialog for tabs, instead of using a CPropertySheet
.
Given that there appears to be no clear and consistent way of approaching this, if (like me) you think "how hard can it be?", you might naively set out to see if you can create a new dialog-based application based on CDialog
and manually convert it to CPropertyPage
. You might fare better; I quickly hit a weird problem with the app compiling but not running - it could not load the window caption from the resource ID, despite the caption literally being there in black and white. Due to the weirdness, this was a red flag, and so to my mind problem (b) seems to be not worth the effort.
Without a CPropertySheet
at the top level, there is no point having any kind of CPropertyPage
or CMFCPropertyPage
involved, making problem (a) pointless. That said, if you manually convert from (default) CDialogEx
to CPropertyPage
for your tab classes, it seems to have no problem compiling and running - the tabs just don't have any functionality that integrates with the main dialog.
Instead, I can now recommend working through the details of the video example even though it does strange things at first glance. You can achieve the desired result in more or less the same way as follows:
CDialogEx
throughout, and so provide all the tab switching/showing/hiding/control work yourself (which the example demonstrates).CDialog
-based classes from there.SetRectangle()
function)TCN_SELCHANGE
event instead of WM_LBUTTONDOWN
As noted, repositioning the tabs can be simplified to something like:
CRect tabRect;
m_tabControl.GetWindowRect( &tabRect );
for ( int i = 0; i < m_totalTabs; i++ )
{
m_pTabPage[ i ]->SetWindowPos( &wndTop, tabRect.left, tabRect.top, 0, 0,
i == m_currentTab? SWP_NOSIZE|SWP_SHOWWINDOW : SWP_NOSIZE|SWP_HIDEWINDOW );
}
Additional calls to ShowWindow()
for each tab shown in the example are redundant.
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.