|
|
Hi,
In our Project we have one Main window which is menu and two dialog boxes. They are separate windows.But I want all of them in same window as tabs.What should I do?
Rekha.
|
|
|
|
|
I'm assuming you're using MFC here.
Create the two dialog boxes with its border style set to none and visible property to false.
Create 2 objects representing the dialogs.
Call .Create on the objects with the tab control as its parent.
Set the size of the dialogs to the size of the client area of the tab.
Set the dialog that is initially shown to visible.
Then in the tab change notification, hide and show the relevant dialogs.
«_Superman_»
|
|
|
|
|
Hello there... I am a newbie here but am trying exactly what hemlat has asked. I hope it is ok to carry on with this thread rather than starting a new one. Please let me know otherwise.
I read your answers (many thanks) and gave it a go, but am struggling, since I am (unfortuantely) lacking the indepth knowledge.
May I ask you for your help, please?
I am using VC++ 6.0 and want to create a very simple dialog-box-based (no SDI or MDI) program utilizing the MFC.
Using the resource editor I have created two dialogs "IDD_PAGE_TestPage1" and "IDD_PAGE_TestPage2".
Using the class wizard I have then created two classes derived from CPropertyPage:
CTestPage1::CTestPage1() : CPropertyPage(CTestPage1::IDD) and CTestPage2::CTestPage2() : CPropertyPage(CTestPage2::IDD).
In my main window (the dialog-box-based program that I created using the wizard) I have created a tab control element, which I would like to somehow "link" to the two dialogs as described above.
I tried achieving this by creating the following objects:
CPropertySheet myPropertySheet;
CTestPage1 myPage1;
CTestPage2 myPage2;
... and then I tried all sorts of things (including ...DoModal, ....ShowWindow(), ..etc. to get my dialogs displayed as part of the tab control, but in vain.
FYI: Although I did some programming in C and C++ many, many years ago (mainly embedded stuff) and even started once to do some WIN32API and MFC programming, ...I have to admit that I am at this stage still lacking some of the (crucial, I know...) Windows concepts (in terms of parent/child relationship, event handling, etc.
I would greatly appreciate any feed back to my questions/problem.
Thanks !
modified on Sunday, February 8, 2009 1:22 AM
|
|
|
|
|
Hi,
Please see my reply to hemlat.
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
Thanks Rajesh, that is an interesting link/example, but I am not "there yet".
In order to learn the MFC basics properly and also not to complicate things for me at this stage (I am a novice), I would really like to get this relatively simple task (at least that's what I thought it would be), ...to be done with the standard MFC functionality.
I studied the help file etc. and my thinking was that using the CPropertySheet and ...page classes should do the trick, but rather than displaying the content of the individual dialogs in the appropriate tab pages, they are being displayed on top of the whole main dialog window and I need to close them to get to the actual (main) window).
I am sure this can be done, but I seem to be missing an important little step to implement it properly.
Maybe I must not call the individual dialogs as modal ones (with .DoModal(), but have to somehow, make them non-modal child of the tab control?
Even if that is the case, my problem is, that I don't have a clue how to do it.
Any help is most appreciated. Thanks.
modified on Sunday, February 8, 2009 3:53 AM
|
|
|
|
|
The problem is that your're not linking the property pages to the property sheet.
Try the following code in the main dialog class.
myPropertySheet.AddPage(&myPage1);
myPropertySheet.AddPage(&myPage2);
myPropertySheet.DoModal();
«_Superman_»
|
|
|
|
|
Thanks for your message,
As one of my many attempts, I had actually tried what you suggest, already. That is how it looks.
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CPropertySheet myPropertySheet;
CTestPage1 myPage1;
CTestPage2 myPage2;
myPropertySheet.AddPage(&myPage1);
myPropertySheet.AddPage(&myPage2);
myPropertySheet.DoModal();
If I do this, the application does actually call the tab control (consisting of these two test pages). And it even comes fully equiped with OK CANCEL APPLY and HELP button in that dialog.
However it is not a 'child' (hope this term is right) of my actual main window, but sits on top of the main window instead. Once I hit OK or CANCEL this tab control dialog (which contains the correct tab contents, by the way) disappears and I can see my actual main window. But no way to get the tab control dialoga within my main window.
I think I am still missing an important step.
Maybe I shouldn't call the
myPropertySheet.AddPage(&myPage1);
myPropertySheet.AddPage(&myPage2);
in the OnInitDialog() function? What where else?
Heeeeeeeeelllllllp
|
|
|
|
|
I understand that you want the property sheet to be your main dialog.
You can remove the DoModal that is already there in the InitInstance method and replace it with the following code -
CPropertySheet myPropertySheet;
CTestPage1 myPage1;
CTestPage2 myPage2;
myPropertySheet.AddPage(&myPage1);
myPropertySheet.AddPage(&myPage2);
myPropertySheet.DoModal();
«_Superman_»
|
|
|
|
|
Thanks for your help and patience and please excuse my ignorance, but I don't know what you mean by "InitInstance "...I don't think I have that in my code.
To create my main window I just ran the AppWzeard and let it create most of my dialog box based program.
So far I have only added a few buttons which call some message boxes.
I am really at the beginning of the program. No fancy functionality yet.
Yes you are right my main window, which contains a few control elements (including the tab control, which I want to display the individual dialogs CTestpage1 and CTestpage2) is supposed to be the one and only dialog.
So on start up of the program I would like the tab control having the focus on the first of my dialog pages (CTestPage1).
|
|
|
|
|
Search through all the .cpp files.
You will see a method called InitInstance .
In that you will see a call to the DoModal function.
«_Superman_»
|
|
|
|
|
Hi,
thanks for your replays. I am able to create wizards by using CPropertyPage and CPropertySheet.But how can I communicate between different windows?
In one of my window I am having one button.If I click on that button it should show another window.
Rekha.
|
|
|
|
|
Thanks. Of course you were right and sure enough, I have found the appropriate InitInstance function.
I then did what you suggested and put the code in (instead of the .DoModal() of the main app window.
And thanks for pointing it out, as while studying this particular *.cpp file and the header file, I have straight away learnt something new about the main app and how it gets instanciated. So that was interesting and worth-while.
However, ...and sorry to be a pain... I am still not quite satisfied:
1) ...because Windows killed my program upon exiting it. It first displays the tabs perfectly fine and I can hop between the individual tabs and so on, but when closing it (via the OK or CANCEL button) it indeed closes the application, but then the WINDOWS OS comes with a message telling that it had to terminate the program, which could not be closed properly (you know, ..the old "Do you want to send a report to Microssoft" error dialog.
2) ...well and secondly, because that is still not quite the behaviour that I want from my little test application.
I try to summarize what I need:
i) When the program (dialog box-based) starts, the a main window with a handful controls appears.
ii) Beside some buttons and static text controls, one of the controls is a tab control which will later contain a whole range of tabs for different things (obviously, as this is what a tab control is for - to group different entities of parameters/data...). After start up the focus should be on the first tab (but I guess I can suss that out later)
iii) I want the tab control to display some dialogs, which I have previously designed with the resource editor. So they exist as individual dialogs - for this purpose I have derived classes from CPropertyPage and an instance of CPropertySheet:
CPropertySheet myPropertySheet;
CTestPage1 myPage1;
CTestPage2 myPage2;
--> In other words, I want one main window which contains a tab control that shows different content (depending which tab you select) and besides this tab control it will have other elements, too. I don't want the tab control to overlay the whole window (sitting on top). I want the individual dialogs (myPage1 and myPage2 to be just in the tab.
And I have seen some fancy workarounds in this great forum to achieve simialr things; some really interesting looking self-made classes, which I am also keen to study - but at a later stage of my "programming career". For now I want to make this work with MFC, ....and sure there must be a way. I have seen a lot of applications out there, that do exactly that.
I hope all this makes sense. Thanks for your help...
modified on Monday, February 9, 2009 6:12 AM
|
|
|
|
|
For your requirement you do not need to use the CPropertySheet or CPropertyPage classes.
You simply create a class inherited from CDialog for each dialog to be shown in tabs.
Make sure the Visible property of all classes are set to false.
Call the Create method of the dialog class setting the tab control as its parent.
Handle the tab change notification of the tab control.
In the notification handler, show the dialog to be shown and hide all the other dialogs.
«_Superman_»
|
|
|
|
|
Many thanks, I think I get a better idea with every message you post. I appreciate your help! Even with the actual problem not quite being solved yet, I have learnt heaps already.
If I understand it correctly the CPropertySheet and CPropertyPage classes are for dialogs, that are actually meant to be on top (as individual dialogs, which the user then confirms via OK, CANCEL, (ESC ENTER) etc., so for that you actually don't use the Tab Control elelement from the toolbar, correct?
And the Tab Control is if you want to use it WITHIN an application, where you can also have other control elements, but all of these will still stay within the main window. Would that roughly summarize the difference between PropertySheets/Pages and a stnadard Tab Control?
Thanks in advance for your comments/answers to confirm this.
O.k. I have disregarded the PropSheet stuff for now and tried what you had described with the .Create function.
Well, I think I start to understand the concept, but unfortunately I can't quite get it to work.
I tried putting the
CTest_Tab_Dialog myTestTab;
myTestTab.Create(IDD_PAGE_TestPage3, NULL);
in the OnInitDialog() function, but the compiler doesn't like it: error C2065 undeclared variable
Then I put it in the OnSelchange notification handler function, like this:
void CTestDlg::OnSelchangeTabMenus(NMHDR* pNMHDR, LRESULT* pResult)
{
CTest_Tab_Dialog myTestTab;
myTestTab.Create(IDD_PAGE_TestPage3, NULL);
switch (m_cTab.GetCurSel())
{
case 0: myTestTab.ShowWindow(SW_SHOW);
break; ;
}
*pResult = 0;
}
...now I can compile and run the program. So far so good.
However, my dialog doesn't get called, I mean it is not visible.
Please note, that despite your hint I have not worked yet on the scaling/sizing that you have mentioned in your previous post. But I thought I can sort that out later. I am not worried too much, if the ta content dialog is a bit too small. I first want to see this stupid dialog.
I am not sure what parameter to call the .Create() function with. Maybe you can explain that to me. Just to make it compilable, I have added a NULL, not really knowing what exactly that does; but perhaps that is wrong, too?!
One thing I noticed is that if I very rapidly change between the tabs of my tab control, I can briefly see the content of the dialog. So it appears that Windows is actually drawing it, but only for a very short moment and then it gets overwritten again.
Maybe that helps you to ...help me Thanks for shedding more light on this.
modified on Tuesday, February 10, 2009 4:05 AM
|
|
|
|
|
Try changing
myTestTab.Create(IDD_PAGE_TestPage3, NULL); to
myTestTab.Create(IDD_PAGE_TestPage3, &m_cTab);
«_Superman_»
|
|
|
|
|
Thanks, but that doesn't work either - same behaviour as with NULL.
Remember when I said, that by changing the tabs rapidly I can (very briefly) see a flicker of the dialog, but it gets overwritten instantaneously?
Well, for debug purposes only I did a little trick to force the program to halt, using a simple message box as shown below...
void CTestDlg::OnSelchangeTabMenus(NMHDR* pNMHDR, LRESULT* pResult)
{
CTest_Tab_Dialog myTestTab;
myTestTab.Create(IDD_PAGE_TestPage3, &m_cTab);
switch (m_cTab.GetCurSel())
{
case 0:
MessageBox("Tab 1 is selected!");
myTestTab.ShowWindow(SW_SHOW);
break;
}
Now, when changing the tab control to this nasty Test Tab 1, the program has to stop (waiting for the MessagaBox to be closed) and - like magic - I can finally see my stupid test tab dialog (IDD_PAGE_TestPage3 .
However, as soon as I OK the MessageBox, the content of the tab disapppears again. I assume it gets overwritten again by the tab contrl itself.
Any idea? ... I think we are almost there
|
|
|
|
|
To zero in on the problem, I would suggest you create a new workspace with only a tab and the dialogs to show on it. And get it right here before moving it into your main workspace.
«_Superman_»
|
|
|
|
|
I have done exactly that.
I am trying all this with a pretty clean workspace.
In fact I only ran the appwizard to create a dialog box based frame and all I have on the main window, is this Tab Control, which I want to display the dialog, just as per the snippets of code that I have posted.
There is nothing else than just the frame that the appwizard has created.
So if you want to give it a go, it would be very quick and easy to come to the same point.
Any other ideas/hints?
Do you think it is the right thing to create the object in the ONSELCHANGE function?
I mean I tried it in the OnInitDialog(), but the compiler didn't like it.
What else can I try... crazy this can't be so difficult. How many thousands of applications are out there that use something like this.
Please help
|
|
|
|
|
Hello out there, ... I just thought I post a last message to this case to let anyone who ever happens to read this thread by accident (or intention) know, that I have now managed to get things going.
My child dialogs are now working (almost) perfectly as contents of the individual pages of a tab control. Just some cosmetics that I have to tidy up.
While getting more and more frustrated, that I couldn't get something simple like a tab control going the way I wanted, I almost gave up.
The ultimate break-through was not until I came across the article from Andrew Lawrence ("Tabbed Dialog without Property Sheets"). I found this article just fabulous!!! It answered my question a hundred percent, and - while studying it - I learnt heaps more.
For the beginner of VC++ this is a highly recommended article!!!
I would like to take the opportunity to thank Andrew very much.
Many thanks also to you Superman for your patience and attempt to help. You were on the right track with your advice, but my ignorance about basic concepts prevented me from actually putting things right.
Keep up the good work
|
|
|
|
|
Read this[^] for starters.
p.s: something you should pay attention to, be sure to override the OnOK and OnCancel (or whatever you want to hook WM_COMMAND with IDOK and IDCANCEL to) methods otherwise when the user hits ENTER ot ESC while the focus is in one of your child-dialogs, the dialog will disappear...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
|
Hi,
Is there any machenism using Shell or anything else to calculate the size of a folder?
|
|
|
|
|
|
Is there any API like when window context menu propprty method?
As windows calculates size very fast, there should be any API like this.
|
|
|
|
|