Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

open a new dialog in the existing frame.

Posted on 2007-10-15
32
Medium Priority
?
436 Views
Last Modified: 2013-11-20
an easy question but i cant find how to do it anywhere, imust be searching for the wrong thing.

basically i have an mfc app with a button on it when its click i want to open that window in the existing window rather than opening a new one using the following code.

CAddDlg addDlg = new CAddDlg;
long ret = addDlg->DoModal();

how can i do this please??
0
Comment
Question by:flynny
  • 12
  • 10
  • 8
  • +2
32 Comments
 

Expert Comment

by:amitrsharma
ID: 20078814
when its click i want to open that window in the existing window rather than opening a new one using the following code.
can u please explain more on this. what do u mean by that...

0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20078816
The problem is how to show one window instead of two after the click. Two ways:
1. Use addDlg->Create method. Set parent value to 'this'.
2. Before DoMOdal() call, set the current window invisible ( use this->ShowWindow(FALSE);)

Let me know if you have any doubt.
0
 

Author Comment

by:flynny
ID: 20078942
hi james, ok easiest way seems to be seting the parent how would i do this?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 20078984
If that is the window you are hooking (and I assume it is), you need to create a CWnd instance from the handle using

CWnd* pWnd = CWnd::FromHandlePermanent(hWndMain);
CAddDlg addDlg = new CAddDlg(IDR_ADDDLG,pWnd); // set parent
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20078998
In my opinion the simplest was the other one. :)
All you need to do is to put this code :

this->ShowWindow(SW_HIDE);
dlg->doModal();
this->ShowWindow(SW_SHOW);

if you want to implement the create method:

virtual BOOL Create(
   CWnd* pParentWnd,
   UINT nIDTemplate,
   UINT nStyle,
   UINT nID
);

here in place of parent, you need to pass 'this',
templateID is the resourceID. ( you can get it from the .h file of the dialog class. it says IDD=resourceid)
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20079004
I would suggest you to implement the first one:
this->ShowWindow(SW_HIDE);
dlg->doModal();
this->ShowWindow(SW_SHOW);

least code changes and easy to implement.
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20079067
let me know if you have any doubt.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20079935
>>>> i want to open that window in the existing window rather than opening a new one

Hmmm, do you mean you want to exchange all current controls (including the button where you clicked on) by the controls of the new dialog? If so, you should be aware that this is a unusual behavior for a  MFC app. Assume the user made a double-click instead of a single-click. Then the second click may be recognized by the second dialog (assume there is a button as well).

Normally multiple dialogs are managed in a CPropertySheet, each of the dialogs has CPropertySheet as baseclass (not CDialog). Then the CPropertySheet handles switching between dialog pages what is a much more usual approach.

Regards, Alex
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20083372
If you have already prepared functionality and the issue is just this one scenario....between these two dialogs then that code change can be more cost-time effective.

but if you are in mid way of development and have several dialogs to be shown one after another, you can make use of CPropertySheet.
For More info on CPropertySheet check out:
http://www.dotnetheaven.com/Uploadfile/bulentozkir/pp_wizard04212005064904AM/pp_wizard.aspx

Above link shows cpropertysheet usage (dont go in name as its in dotnetheaven !!). Let me know if you have any issues.
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20091423
let me know if you have any doubts
0
 

Author Comment

by:flynny
ID: 20092151
thanks for the comments guys.

>> If that is the window you are hooking (and I assume it is)
it is related to the program yes but this is a simply mfc app i have created to test my hooks, (similar to spy++ but more specific), here i have a window with some info in, however rather than open a new window when the use clicks a button which diapys more details, i want to load a seperate dialog.

CPropertyPage looks to be perfect. a couple of questions though. My dialogs already extend CSizingDialog (an extended class i downloaded to handle resizing and repositioning windows). Just to check before i break everything, (using th provided link), i assue  will have to change my CSizingDialog to extend CPropertyPage rather than CDialog (coudl this have any effect on the program?) .
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20092179
No it should not affect. C++ supports multiple inheritances. Inherit your dialog from both CSizingdlg and CPropertyPage.

In order to bind these pages with one another (so that one will come after other, you can term it as sequencing), you also need to create a cpropertysheet which would be a sort of wizard with each dialog as its page.

OR
If you have only 2 dialogs to play with then a quick solution would be to switch dialogs' visibility accordingly. I have already stated it as well in my previous comments.
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 2000 total points
ID: 20092659
>>>> C++ supports multiple inheritances.
C++ yes but MFC no.

MFC makes a cast on the CWnd pointer when sending messages to derived classes. That cast will fail in case of multiple inheritance and a derived class having a different (virtual) pointer than the CWnd baseclass. Multiple inheritance only works with MFC if all MFC classes are in the main branch of the inheritance tree, i. e. the MFC class is always the first class you are deriving from.

>>>> My dialogs already extend CSizingDialog
You might consider deriving CSizingDialog from CPropertyPage. CPropertyPage is a CDialog with a few members to support paging within a CPropertySheet.

If you need CSizingDialog somewhere outside of a CPropertySheet you may try to use it like that. I can't think of really essential reasons why you shouldn't be able to use it as single dialog. But if you experience some assertions or unresolved constructors you may consider a class definition like that:

class CSizingDialog
#ifndef WITH_PROPERTYSHEET
        : public CDialog
#else
        : public CPropertyPage
#endif
{
         ....
};

Regards, Alex
0
 

Author Comment

by:flynny
ID: 20092888
ok great i've worked through changing the CDialog to CPropertyPage no i get the error

error C2664: '__thiscall CPropertyPage::CPropertyPage(unsigned int,unsigned int)' : cannot convert parameter 2 from 'class CWnd *' to 'uns
igned int'

where i  have

CSizingDialog::CSizingDialog(
      UINT nIDTemplate, CWnd* pParentWnd /*= NULL*/,
      LPCTSTR lpszSection /*= _T("Placement")*/,
      LPCTSTR lpszEntry /*= _T("MainDialog")*/)
      : CPropertyPage(nIDTemplate, pParentWnd)
      , m_lpszSection(lpszSection)
      , m_lpszEntry(lpszEntry)
      , m_bEnableRWP(TRUE)
      , m_bErase(TRUE)
{
}

any ideas?

thanks matt.
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20092942
you should pass 'this' (any pointer of type CWnd*) for pParentWnd parameter.
Plz tell what value you have passed for this parameter.
0
 

Author Comment

by:flynny
ID: 20093012
//////////////////////////////////////////////////////////////////////////
// SizingDialog.h

#pragma once

#include "SizingSP.h"


//////////////////////////////////////////////////////////////////////////
// CSizingDialog dialog

class CSizingDialog : public CPropertyPage
{
      DECLARE_SIZING_SUPPORT()

// Constructors
public:
      CSizingDialog(LPCTSTR lpszSection = NULL, LPCTSTR lpszEntry = NULL);
      explicit CSizingDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL,
            LPCTSTR lpszSection = _T("Placement"), LPCTSTR lpszEntry = _T("MainDialog"));

// Implementation
protected:
      afx_msg void OnPaint();
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
      afx_msg void OnSize(UINT nType, int cx, int cy);
      afx_msg BOOL OnEraseBkgnd(CDC* pDC);
      afx_msg void OnTimer(UINT nIDEvent);
      afx_msg void OnDestroy();
      afx_msg UINT OnNcHitTest(CPoint point);
      DECLARE_MESSAGE_MAP()

// Data
private:
      LPCTSTR                  m_lpszSection;
      LPCTSTR                  m_lpszEntry;
      BOOL                  m_bEnableRWP;            // Enable to restore the window placement
      BOOL                  m_bErase;                  // Enable erase background
};

class CSizingFormView : public CFormView
{
};
this is the header file if it helps.
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20093060
I feel the pointer is not getting casted properly to CWnd type
The problem should be where you are creating an object of CSizingDialog.
The value you are passing in to the constructor are not going fine.
Plz let me know of those statement(s) where you ar creating an object of CSizingDialog class.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20093172
The constructor of CPropertyPage expects two id numbers, first is the dialog id (what is correct), second is a caption id for the text to display at the tab (button). The parent window is not an argument (as it is with CDialog) cause a CPropertyPage expects to be a child of a CPropertySheet being added by a call to CPropertySheet::AddPage. That member would set the parent window of the CDialog (it takes the 'this' of the CPropertySheet). If you need the CSizingDlg a single dialog you may change the constructor like that:

CSizingDialog::CSizingDialog(
      UINT nIDTemplate, CWnd* pParentWnd /*= NULL*/,
      LPCTSTR lpszSection /*= _T("Placement")*/,
      LPCTSTR lpszEntry /*= _T("MainDialog")*/)
      : CPropertyPage(nIDTemplate, 0)
      , m_lpszSection(lpszSection)
      , m_lpszEntry(lpszEntry)
      , m_bEnableRWP(TRUE)
      , m_bErase(TRUE)
{
     if (pParentWnd != NULL)
         SetParent(pParentWnd);
}

In case of a property sheet you would construct it without supplying a parent window. In case of a single dialog you may pass the parent window (or NULL) if it is the top level dialog. However, I've seen some sequences in MFC dlgprop.cpp where the window retrieved with GetParent() was 'down_casted' to a CPropertySheet, so I wouldn't bet that the single page mode will work.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20093456
>>>> I wouldn't bet that the single page mode will work.
It looks not so bad: It seems there are only 2 down-casts of the parent pointer. One, when the page was made active. If the down-cast failed, it would call OnSetActive what makes a UpdateData(FALSE), i. e. it fills the screen from members, what seems ok. Second, is in the CPropertyPage::EndDialog where failing of the down-cast would prevent from calling pParent->EndDialog(nID); what means that the dialog wouldn't end. But EndDialog never was called from members of CPropertyPage, so it is only an issue if you call EndDialog from OnOK or OnCancel. If so (or do it for any case), you should provide a CSizingDialog::EndDialog what would call CDialog::EndDialog in single page mode and CPropertyPage::EndDialog else. To make that easy you might add a bool member which tells what mode you in:

   void CSizingDialog::EndDialog(int id)
   {
          if (m_bSingleMode)
                CDialog::EndDialog(id);
         else
                CPropertyPage::EndDialog(id);
   }
0
 

Author Comment

by:flynny
ID: 20129873
ok thanks for all your help itsme its compiling now. (i ran it to see what happened and it works however the close window button in the top right of the window doesn't work, i assume this is to do with your second point itsme).

ok so by deriving this class from CPropertyPage i then when initialising my dialog need to create a CProperttSheet, create an instance of the two dialogs i want to add and add them. is this correct?

I do this by

CPropertySheet dlg("Test Title", this, 0);

however it says it cannot convert parameter 1 from char[11] to unsigned int. from looking on the msdn library this seems correct though.

0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20129888
>>however it says it cannot convert parameter 1 from char[11] to unsigned int. from >>looking on the msdn library this seems correct though.

thats becoz it expects you to say a pointer instead of the char array.

try _T("Test Title") instead of "Test Title".

Hope this helps.
0
 

Author Comment

by:flynny
ID: 20129910
sorry james, i tried this too and i just get the same error.
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20129925
okies....
it may not able to convert it into a pointer.

try using LPTSTR.

for more info on LPTSTR:
http://www.experts-exchange.com/Programming/Languages/C/Q_21153785.html

and on LPCTSTR:
http://www.codeguru.com/forum/archive/index.php/t-78509.html
0
 
LVL 7

Expert Comment

by:lucky_james
ID: 20129947
do revert back in case if it still doesnt work.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20130078
>>>> CPropertySheet dlg("Test Title", this, 0);

parameter 1 is "Test Title". That is a 'const char*' or LPCSTR.

CPropertySheet has two constructors, only differing in parameter 1.

The first takes a UINT (unsigned int) for an id of a text caption. That is why you get the error message "cannot convert parameter 1 from char[11] to unsigned int" cause if the first argument in the call cannot be recognized, the error message refres to the first constructor only.

The second constructor takes a  LPCTSTR what is a 'const char*' or LPCSTR if _UNICODE is not defined or a 'const wchar_t*' or LPCWSTR in case _UNICODE is defined for your project.

I would assume - same as lucky_james - that you have _UNICODE defined cause otherwise the second constructor should have compiled as "Test Title" would have been a valid ANSI string.

If we were right, the following should compile:

   CPropertySheet dlg(_T("Test Title"), this, 0);

cause the _T macro makes it a wide string in case of UNICODE.

Regards, Alex
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20130121
You also can add a string resource in your resource view and call the constructor like

CPropertySheet dlg(IDS_PROPERTYSHEET_TITLE, this, 1);

That should resolve the problem.

>>>> however the close window button in the top right of the window doesn't work
Add the

      ON_WM_CLOSE()

macro to the message map entries of your dialog (between BEGIN_MESSAGE_MAP and END_MESSAGE_MAP) and add the member function

         afx_msg void OnClose( );

to your dialog class and implement it like

 afx_msg void CSizingDialog::OnClose( )
 {
       EndDialog(IDOK);
 }

Note, you also have to add the CSizingDialog::EndDialog like I posted above.


 

0
 

Author Comment

by:flynny
ID: 20130353
hi ok the resource has worke thanks itsme.

now i get the following for the second parameter

error C2664: '__thiscall CPropertySheet::CPropertySheet(unsigned int,class CWnd *,unsigned int)' : cannot convert parameter 2 from
'class CConfigApp *const ' to 'class CWnd *'
0
 

Author Comment

by:flynny
ID: 20130493
ok i'm getting there now (sorry the CConfigApp extence CWinApp) so by using the following i have it compiled and loading

      CPropertySheet dlg(IDS_PROPERTYSHEET_TITLE,m_pActiveWnd,0);

      CConfigDlg page1;
      CButtonDlg page2;

      dlg.AddPage(&page1);
      dlg.AddPage(&page2);

      dlg.DoModal();

ok however, i'm doing something slightly wrong as the program i loading ok however i cannot resize the main wndow as i could before. however the property page insid the tab window i can (to a certain extent as i cannot resize the main window. how would i change this?

do i need to CSizingDialog extend propertysheet rather than page?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20130575
>>>> CPropertySheet dlg(IDS_PROPERTYSHEET_TITLE,m_pActiveWnd,0);

try

    CPropertySheet dlg(IDS_PROPERTYSHEET_TITLE, AfxGetMainWnd(), 0);

and tell whether it solves your problem. If not, you may explain what kind of windows and frames you currently have.
0
 

Author Comment

by:flynny
ID: 20130873
no sorry itsme that didnt work it doing the same thing.

ok, let me run through this for you, i run the program which is running in a CWinApp

i create the Property Sheet as above and add each dialog, each of which extends the CSizingDialog, which in turn extend the PropertyPage class.

So i assume i will have to create an extension of the propertysheet class that will include the resizing function?
0
 

Author Comment

by:flynny
ID: 20130887
the other thing i have noticed is that now i am using a CPropertySheet my file menu has disappeared? am i able to add this to a CPropertySheet?
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 20312159
>>>> the other thing i have noticed is that now i am using a
>>>> CPropertySheet my file menu has disappeared? am i
>>>> able to add this to a CPropertySheet?

All functionality like menus, handling sizing messages now have to been made by CPropertySheet rather than by one of the current dialog pages. You may derive from CPropertySheet to add the menu and the appropriate handlers.

Regards, Alex
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question