-
October 2nd, 2003, 02:09 PM
#1
dialog hierarchy from cdialog
I've read many posts related to this topic...I think I understand but wanted to clarify what I think I understand.
Here's my situation:
My class hierarchy is as follows:
SReviewInterestDlg(Dlg template: IDD_REVIEW_INTEREST_DLG)
SReviewDlg(Dlg Template: IDD_REVIEW_DLG)
SDialog
CDialog
SDialog derives from CDialog, SReviewDlg derives from SDialog, SReviewInterestDlg derives from SReviewDlg.
There is a dialog template associated with SReviewDlg and a different dialog template associated with SReviewInterestDlg. There is no dialog template associated with SDialog and of course CDialog.
My application will not have instances of SReviewDlg or SDialog. I will only be creating instances of SReveiwInterestDlg.
My questions:
1)Is it possible to do what I am attempting to do? ie is it possible to have two different dialog templates associated with two dialog classes which have a base class - derived class relationship?
2)Do I have to have any special processing so that the above hierarchy works. From the other posts that I have read, I think I need to make sure the contructors for all the derived dialogs pass the right dialog template.
Thanks very much for helping.
-MD
-
October 2nd, 2003, 03:10 PM
#2
Re: dialog hierarchy from cdialog
Originally posted by mddd
My application will not have instances of SReviewDlg or SDialog. I will only be creating instances of SReveiwInterestDlg.
-MD
If that is the case, why would you need a template for SReviewDlg ?
-
October 2nd, 2003, 04:03 PM
#3
I created a template for SReviewDlg(IDD_REVIEW_DLG) as this a base template for SReviewInterestDlg's template (IDD_REVIEWINTEREST_DLG)
There are going to be mulitple dialogs that will derive from SReviewDlg (like SReviewInvestmentDlg, SReviewBalancesDlg etc...)
SReviewDlg's template(IDD_REVIEW_DLG) is going to have the controls that are common to all the above child dialogs....I plan to inherit these common controls in my child dialogs and then each of the child dialogs will have their own unique controls.
Thanks,
MD
-
October 2nd, 2003, 07:48 PM
#4
Originally posted by mddd
I created a template for SReviewDlg(IDD_REVIEW_DLG) as this a base template for SReviewInterestDlg's template (IDD_REVIEWINTEREST_DLG)
There are going to be mulitple dialogs that will derive from SReviewDlg (like SReviewInvestmentDlg, SReviewBalancesDlg etc...)
SReviewDlg's template(IDD_REVIEW_DLG) is going to have the controls that are common to all the above child dialogs....I plan to inherit these common controls in my child dialogs and then each of the child dialogs will have their own unique controls.
Thanks,
MD
Unfortunately, you cannot inherit a dialog template resource in VC++. Because ultimately, you will have to call CDialog which only accepts one template.
Your next best bet is 'Import Copy...' (right click menu option from Dialog resource) so you can simulate a 'Save As..'. But even with that, it will still require you to save to a different language, i.e. it does not allow you to specify a new IDD_xx name. Or, you can create another dialog that looks exactly the same, and reuse the resource names (IDC_xx).
What I can suggest is build your logic in your SReviewDlg() class and do the following:
1. Create (unfortunately) the descendant dialog template, in this case, IDD_REVIEWINTEREST_DLG and reuse the IDC_xx ids from IDD_REVIEW_DLG.
2. Modify the constructor to accept a template from descendant:
From: SReviewDlg(CWnd* pParent = NULL);
To: SReviewDlg(UINT nTemplate, CWnd* pParent = NULL);
3. Change the value of enum {}. This step is optional. You can keep the reference to the original resource.
From: enum { IDD = IDD_REVIEW_DLG };
To: enum { IDD = 0 };
4. In the constructor definition of SReviewDlg (.cpp file)
From: SReviewDlg::SReviewDlg(CWnd* pParent /*= NULL*/)
: CDialog(SReviewDlg::IDD, pParent)
To: SReviewDlg::SReviewDlg(UINT nTemplate, CWnd* pParent /*= NULL*/)
: CDialog(nTemplate, pParent)
Having done those changes, you can now modify your SReviewInterestDlg constructor to call the SReviewDlg like this:
SReviewInterestDlg::SReviewInterestDlg(CWnd* pParent /*=NULL*/)
: SReviewDlg(SReviewInterestDlg::IDD, pParent)
Note: we are passing, the descendants dialog resource id.
In that way, at least you can have you common implementations in SReviewDlg class. But sadly, when there is a change in IDD_REVIEW_DLG, e.g. misspelled word, or change or label name, you will have to do the same in all the related dialog resource.
Good Luck.
_msd_
-
October 3rd, 2003, 08:56 PM
#5
Unfortunately MFC makes it difficult to do things like this. I have wanted to but have not been successful. It is possible to do this type of thing partially so sometimes we can be successful depending on what we need to do.
I think the main problem with what you are doing is that the ClassWizard does not understand a dialog that has a base class and a derived class. So you might be able to develop the base class as if it is a the main class then use that as a base class to derive from. That could work as long as you don't need to use the ClassWizard again for the base class.
See templates to replicate code for a thread I created. It probably won't help you much but there are ta least a couple of other articles it references that might help.
-
October 4th, 2003, 10:42 AM
#6
That is true. The PrintDlg ( and most common dialogs ) do it by having a dedicated child dialog area , so any dialog template that you supply will be a child of the main dialog. So, to add more controls to the base dialog, one would pass this child dialog template. But the way it is done is pretty complicated and highly undocumented and confusing enough to push people away.
-
October 17th, 2003, 12:45 PM
#7
I implemented the solution suggested by _msd_ and it works well for my purpose.
Thanks very much for everyone's help with this problem.
-MD
-
October 22nd, 2003, 06:51 PM
#8
Thanks for keeping us posted. I'm glad that worked well for you. In light of that, let me add another trick that might help copying of the IDD_REVIEW_DLG template, so that you won't have to create the related dialogs (e.g. IDD_REVIEWINTEREST_DLG) manually. This means manually editing your <projectname>.rc and resource.h files.
Caution: These files are maintained by APP Studio. So, be extra careful.
1. Exit VC++
2. Make a back up copy of you <projectname>.rc and resource.h files
3. Make sure they are checked out (if you are using VSS) so that they are not 'read-only'
<projectname>.rc
1. Open <projectname>.rc as a text file, e.g. NotePad
2. Look for the dialog definition block of IDD_REVIEW_DLG. It should look something like:
Code:
IDD_REVIEW_DLG DIALOG DISCARDABLE 0, 0, 241, 274
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Contract Properties"
FONT 8, "MS Sans Serif"
BEGIN
.
.
.
END
3. Copy the whole block and Paste the copy just underneath it. And, change the IDD_REVIEW_DLG to IDD_REVIEWINTEREST_DLG. After copying the file should look like this:
Code:
IDD_REVIEW_DLG DIALOG DISCARDABLE 0, 0, 241, 274
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Contract Properties"
FONT 8, "MS Sans Serif"
BEGIN
.
.
.
END
IDD_REVIEWINTEREST_DLG DIALOG DISCARDABLE 0, 0, 241, 274
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Contract Properties"
FONT 8, "MS Sans Serif"
BEGIN
.
.
.
END
4. Right underneath the series of dialog blocks you should see something like:
Code:
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_REVIEW_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 352
TOPMARGIN, 7
BOTTOMMARGIN, 311
END
END
#endif // APSTUDIO_INVOKED
Again, make a copy of IDD_REVIEW_DLG as IDD_REVIEWINTEREST_DLG. After copying you file should look like this:
Code:
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_REVIEW_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 352
TOPMARGIN, 7
BOTTOMMARGIN, 311
END
IDD_REVIEWINTEREST_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 352
TOPMARGIN, 7
BOTTOMMARGIN, 311
END
END
#endif // APSTUDIO_INVOKED
5. If you have some hard-coded initializations within the IDD_REVIEW_DLG, e.g. initial values on a Combo Box, you should find one more IDD_REVIEW_DLG block that looks like:
Code:
/////////////////////////////////////////////////////////////////////////////
//
// Dialog Info
//
IDD_REVIEW_DLG DLGINIT
BEGIN
.
.
.
END
Do a copy of it as well for IDD_REVIEWINTEREST_DLG.
6. Save and close <projectname>.rc
resource.h
1. Open it in NotePad. Go to the end of file and take note the value of _APS_NEXT_RESOURCE_VALUE, e.g.
Code:
#define _APS_NEXT_RESOURCE_VALUE 189
2. Increment that value by one (in this case 190)
3. Go back to top of file and insert a macro definition for IDD_REVIEWINTEREST_DLG, e.g.
Code:
#define IDD_REVIEWINTEREST_DLG 189
Please note that this file is not sorted by the macro name but by the macro numeric values so make sure 189 is inserted between 188 and 190. In short, IDD_REVIEW_DLG might not be right on top of IDD_REVIEWINTEREST_DLG.
4. Save and close resource.h
After doing all those changes, open your project in VC++. You should be able to see IDD_REVIEWINTEREST_DLG in the Dialog resource. You can use the dialog resource edit to add your controls and Class Wizard to add your dialog class.
Tip: After opening your project in VC++, go back to Windows Explorer and open <projectname>.clw. You should see that APP Studio has created a new ResourceXX for IDD_REVIEWINTEREST_DLG and a section [DLG:IDD_REVIEWINTEREST_DLG] with the entry Class=? to indicate to Class Wizard that there is no class associated to the dialog resource yet.
That's as close as we can get to copying a dialog resource.
_msd_
While memory is getting abundant, it is not an excuse for wasting it with bad programming design/practice.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|