I have a dialog. I want to add a control that, when clicked, will open another dialog that is exactly the same as the first. There would be minor differences in how the second operates, OnInitDialog() for example, but it would look the same. I'm trying to avoid a second large dialog creation routine.
Any ideas? Thanks.
couldn't you put the dialog creation routine in a sub routine of it's own and just pass it the different handles.
In EB I use an Init routine to build all my dialogs one time at the beginning of my program.
Any chance you would post the code for your Init program?
Really nothing to it.
I've got to go pick my g-dau up at school.
I'll share what I do when I get back.
Nothing to it really.
Larry
Remember, this is what I do in EB:
1st I always use projects when I'm going to have a bunch of dialogs:
In main source file:
I declare all the handles to all my windows and dialogs and make them GLOBAL
I create my main window.
I call my InitDlg() routine.(in the main source file)
sub InitDlg()
InitD1()
InitD2()
...etc
return
endsub
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each dialog usually is in its own source file but doesn't have to be. It would look like this:
sub InitDlg1()
CREATEDIALOG dlg1,0,0,317,255,0x80C80080,0,"Dialog1",&dlg1handler
'rest of controls etc...
return
endsub
sub dlg1handler()
stuff....
return
endsub
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hope that makes sense; if not, just ask.
Larry
In Aurora I'm trying something like this but it won't compile:
class MyDialog
{
MyDialog m_dlg;
}
As I said, I want to be able to open a dialog identical to the one I am in.
Have a look at CDialogList::CreateDialog - it allocates dynamically a dialog, creates it and shows. All dialogs created by this method are identical.
#define STATIC_1 1
#define GROUP_3 3
#define BUTTON_2 2
#define BUTTON_4 4
class CDialogList : CPointerList
{
int count;
declare CDialogList() {Create(); count=0;}
declare CreateDialog(int x,int y);
}
class CDlg:CDialog
{
declare virtual OnInitDialog();
declare virtual OnClose();
declare virtual OnDestroy();
declare virtual OnControl(int nID, int nNotifyCode, unsigned int hControl);
CDialogList *list;
}
sub main(),int
{
CDialogList dialogs;
for (int a=0; a<5; a++)
{
dialogs.CreateDialog( rnd(700), rnd(500) );
}
while (dialogs.count) {wait();}
dialogs.RemoveAll(true);
MessageBox(0, "all dialogs closed", "");
return 0;
}
CDialogList::CreateDialog(int x,int y)
{
CDlg *pDlg = new(CDlg, 1);
if (pDlg)
{
// save the new class
Add(pDlg);
pDlg->list = this;
count++;
pDlg->Create(x,y,300,202,0x80CA0080,0,"MultiDlg",0);
pDlg->AddControl(CTSTATIC,"Static",26,10,70,20,0x5000010B,0x0,STATIC_1);
pDlg->AddControl(CTGROUPBOX,"Group",121,11,70,60,0x50000007,0x0,GROUP_3);
pDlg->AddControl(CTBUTTON,"Close Me",34,133,89,33,0x50010000,0x0,BUTTON_2);
pDlg->AddControl(CTBUTTON,"Close All",155,133,89,33,0x50010000,0x0,BUTTON_4);
pDlg->ShowDialog();
pDlg->SetSize(x,y,300,202);
}
}
CDlg::OnClose()
{
CloseDialog(1);
}
CDlg::OnDestroy()
{
list->count--;
}
CDlg::OnInitDialog()
{
/* Initialize any controls here */
CenterWindow();
}
CDlg::OnControl(int nID, int nNotifyCode, unsigned int hControl)
{
if (!nNotifyCode)
{
switch (nID)
{
case BUTTON_2:
CloseDialog(0);
case BUTTON_4:
pointer pos = list->GetFirst();
while (pos)
{
CDlg *pDlg = list->GetData(pos);
pDlg->CloseDialog(0);
pos = list->GetNext(pos);
}
}
}
}
Close. But a new dialog doesn't open as the result of a click on the previous one. I would want to replace the "Close All" button with something like "Open My Twin". It's given me an idea so I'll experiment some more.
You can't contain a MyDialog in a MyDialog, because it would nest infinitely (MyDialog contains a MyDialog which contains a MyDialog which contains...). You have to use pointers in this case. Try
class MyDialog : CDialog
{
MyDialog *dialog;
}
Can you build a dialog template and assign a pointer to it as needed.
I know you would need to allocate the dialog somehow.
Like instances of a structure.
By combining the two techniques shown above, I can now get a dialog to call itself. I cannot, however, set the parent in the child dialog and it is not modal. I will try a little longer and then post my results one way or the other.
Thanks for the help to this point.
Edit: here it is. Do FILE|OPEN to get started.
#AutoDefine "Off"
//#include "cds_winAPI.inc"
//#include "cds_WinConstants.inc"
//#include "cds_WinStructures.inc"
declare import, GetSysColor(
index as int
), int;
const DS_MODALFRAME = 0x80;
int g_nCaption;
class TestDialog:CDialog
{
// member variables
TestDialog *p_dlgTest;
string m_sCaption;
unsigned int m_hParent;
// Overridden Methods
declare OnControl(int nID, int nNotifyCode, unsigned int hControl), int;
declare OnDestroy(), int;
declare OnInitDialog();
//Other Methods
declare CreateDialog();
declare SetCaption(string sCaption) {m_sCaption = sCaption;}
declare SetTheParent(unsigned int hParent) {m_hParent = hParent;}
}
TestDialog::CreateDialog()
{
// The parent is set to null because anything else I try fails :<(
Create(0,0,300,202,AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,0,NumToStr(g_nCaption),null);
AddControl(CTBUTTON,"OK",115,139,70,20,0x5000000B,0,1);
}
TestDialog::OnInitDialog()
{
CenterWindow();
return;
}
TestDialog::OnControl(int nID, int nNotifyCode, unsigned int hControl), int
{
p_dlgTest = new(TestDialog, 1);
g_nCaption++;
p_dlgTest->SetCaption(NumToStr(g_nCaption));
p_dlgTest->SetTheParent(this);
p_dlgTest->CreateDialog();
p_dlgTest->DoModal();
}
TestDialog::OnDestroy(), int
{
return 0;
}
//=============================================================================
class MainWindow:CWindow
{
enum WinMenuConstants
{
FILE_NEW,
FILE_OPEN,
FILE_SAVE,
FILE_EXIT,
EDIT_CUT,
EDIT_COPY,
EDIT_PASTE,
HELP_ABOUT,
HELP_HELP
}
// Constructor/Destructor
declare MainWindow();
declare _MainWindow();
// Overridden Methods
declare virtual OnClose(), int;
declare virtual OnCreate(), int;
declare virtual OnMenuInit(unsigned int hMenu), int;
declare virtual OnMenuPick(int nID), int;
// Other Methods
// Member Variables
TestDialog m_dlgTest;
}
MainWindow::MainWindow()
{
g_nCaption = 1;
return;
}
MainWindow::_MainWindow()
{
}
MainWindow::OnClose(), int
{
Destroy();
return 0;
}
MainWindow::OnCreate(), int
{
CenterWindow();
return 0;
}
MainWindow::OnMenuInit(unsigned int hMenu), int
{
return 0;
}
MainWindow::OnMenuPick(int nID), int
{
select nID
{
case FILE_OPEN:
m_dlgTest.SetTheParent(this); // an attempt, currently ignored
m_dlgTest.CreateDialog();
m_dlgTest.DoModal();
case FILE_SAVE:
case FILE_EXIT:
OnClose();
case HELP_ABOUT:
MessageBox(this,
"Skeleton\n" +
"ÂÃ,© 2007 Campanile Data Systems\n" +
"All Rights Reserved",
"About",
MB_ICONINFORMATION);
}
}
// *****************************************************************************
// * MAIN SUBROUTINE *
// *****************************************************************************
global sub main()
{
MainWindow wMain;
CMenu m;
m.BeginMenu();
m.MenuTitle("&File");
m.MenuItem("&New", AMF_GRAYED, FILE_NEW);
m.Separator();
m.MenuItem("&Open", AMF_ENABLED, FILE_OPEN);
m.MenuItem("&Save", AMF_GRAYED, FILE_SAVE);
m.Separator();
m.MenuItem("E&xit", AMF_ENABLED, FILE_EXIT);
m.MenuTitle("&Edit");
m.MenuItem("Cut\tCtrl+X", AMF_GRAYED, EDIT_CUT);
m.MenuItem("Copy\tCtrl+C", AMF_GRAYED, EDIT_COPY);
m.MenuItem("Paste\tCtrl+V", AMF_GRAYED, EDIT_PASTE);
m.MenuTitle("&Tools");
m.MenuTitle("&Help");
m.MenuItem("&About...", AMF_ENABLED, HELP_ABOUT);
m.Separator();
m.MenuItem("&Help", AMF_GRAYED, HELP_HELP);
m.EndMenu();
wMain.Create(0,0,700,450,
AWS_CAPTION|AWS_VISIBLE|AWS_BORDER|AWS_SYSMENU|AWS_SIZE|AWS_MINIMIZEBOX|AWS_AUTODRAW,
0,"Test",NULL);
wMain.SetMenu(m.Detach());
wMain.SetWindowColor(GetSysColor(15));
// message loop
do
{
wait();
}until wMain.isValid() == false;
return 0;
}
Create(0,0,300,202,AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,0,NumToStr(g_nCaption),this);
Quote from: Paul Turley on May 17, 2007, 12:23:25 PM
Create(0,0,300,202,AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,0,NumToStr(g_nCaption),this);
Not there yet. I'm looking for the feature of DoModal() that requires one to close the child dialog before the parent will accept focus.
Got it. A rookie error :P . I was using the wrong type when trying to send the parent into the child dialog class. Here is the corrected version.
#AutoDefine "Off"
//#include "cds_winAPI.inc"
//#include "cds_WinConstants.inc"
//#include "cds_WinStructures.inc"
declare import, GetSysColor(
index as int
), int;
const DS_MODALFRAME = 0x80;
int g_nCaption;
class TestDialog:CDialog
{
// member variables
TestDialog *p_dlgTest;
string m_sCaption;
CWindow *m_pParent;
// Overridden Methods
declare OnControl(int nID, int nNotifyCode, unsigned int hControl), int;
declare OnDestroy(), int;
declare OnInitDialog();
//Other Methods
declare CreateDialog();
declare SetCaption(string sCaption) {m_sCaption = sCaption;}
declare SetTheParent(CWindow *Parent) {m_pParent = Parent;}
}
TestDialog::CreateDialog()
{
// The parent is set to null because anything else I try fails :<(
Create(0,0,300,202,AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,0,NumToStr(g_nCaption),m_pParent);
AddControl(CTBUTTON,"OK",115,139,70,20,0x5000000B,0,1);
}
TestDialog::OnInitDialog()
{
CenterWindow();
return;
}
TestDialog::OnControl(int nID, int nNotifyCode, unsigned int hControl), int
{
p_dlgTest = new(TestDialog, 1);
g_nCaption++;
p_dlgTest->SetCaption(NumToStr(g_nCaption));
p_dlgTest->SetTheParent(this);
p_dlgTest->CreateDialog();
p_dlgTest->DoModal();
}
TestDialog::OnDestroy(), int
{
return 0;
}
//=============================================================================
class MainWindow:CWindow
{
enum WinMenuConstants
{
FILE_NEW,
FILE_OPEN,
FILE_SAVE,
FILE_EXIT,
EDIT_CUT,
EDIT_COPY,
EDIT_PASTE,
HELP_ABOUT,
HELP_HELP
}
// Constructor/Destructor
declare MainWindow();
declare _MainWindow();
// Overridden Methods
declare virtual OnClose(), int;
declare virtual OnCreate(), int;
declare virtual OnMenuInit(unsigned int hMenu), int;
declare virtual OnMenuPick(int nID), int;
// Other Methods
// Member Variables
TestDialog m_dlgTest;
}
MainWindow::MainWindow()
{
g_nCaption = 1;
return;
}
MainWindow::_MainWindow()
{
}
MainWindow::OnClose(), int
{
Destroy();
return 0;
}
MainWindow::OnCreate(), int
{
CenterWindow();
return 0;
}
MainWindow::OnMenuInit(unsigned int hMenu), int
{
return 0;
}
MainWindow::OnMenuPick(int nID), int
{
select nID
{
case FILE_OPEN:
m_dlgTest.SetTheParent(this); // an attempt, currently ignored
m_dlgTest.CreateDialog();
m_dlgTest.DoModal();
case FILE_SAVE:
case FILE_EXIT:
OnClose();
case HELP_ABOUT:
MessageBox(this,
"Skeleton\n" +
"ÂÃ,© 2007 Campanile Data Systems\n" +
"All Rights Reserved",
"About",
MB_ICONINFORMATION);
}
}
// *****************************************************************************
// * MAIN SUBROUTINE *
// *****************************************************************************
global sub main()
{
MainWindow wMain;
CMenu m;
m.BeginMenu();
m.MenuTitle("&File");
m.MenuItem("&New", AMF_GRAYED, FILE_NEW);
m.Separator();
m.MenuItem("&Open", AMF_ENABLED, FILE_OPEN);
m.MenuItem("&Save", AMF_GRAYED, FILE_SAVE);
m.Separator();
m.MenuItem("E&xit", AMF_ENABLED, FILE_EXIT);
m.MenuTitle("&Edit");
m.MenuItem("Cut\tCtrl+X", AMF_GRAYED, EDIT_CUT);
m.MenuItem("Copy\tCtrl+C", AMF_GRAYED, EDIT_COPY);
m.MenuItem("Paste\tCtrl+V", AMF_GRAYED, EDIT_PASTE);
m.MenuTitle("&Tools");
m.MenuTitle("&Help");
m.MenuItem("&About...", AMF_ENABLED, HELP_ABOUT);
m.Separator();
m.MenuItem("&Help", AMF_GRAYED, HELP_HELP);
m.EndMenu();
wMain.Create(0,0,700,450,
AWS_CAPTION|AWS_VISIBLE|AWS_BORDER|AWS_SYSMENU|AWS_SIZE|AWS_MINIMIZEBOX|AWS_AUTODRAW,
0,"Test",NULL);
wMain.SetMenu(m.Detach());
wMain.SetWindowColor(GetSysColor(15));
// message loop
do
{
wait();
}until wMain.isValid() == false;
return 0;
}
Again, thanks for all the help.
Quote from: Paul Turley on May 17, 2007, 12:23:25 PM
Create(0,0,300,202,AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,0,NumToStr(g_nCaption),this);
Paul's offering with "this" works too. I added this little bit to decrement the counter. I tried to delete the pointer, but it didn't work.
TestDialog::OnDestroy(), int
{
if ( g_nCaption>1 ) { g_nCaption--; } // decrement counter
return 0;
}