IonicWind Software

Aurora Compiler => GUI => Topic started by: Bruce Peaslee on May 11, 2007, 09:08:32 AM

Title: Dialog "calling itself"
Post by: Bruce Peaslee on May 11, 2007, 09:08:32 AM
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.
Title: Re: Dialog "calling itself"
Post by: LarryMc on May 11, 2007, 11:28:42 AM
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.

Title: Re: Dialog "calling itself"
Post by: Rock Ridge Farm (Larry) on May 11, 2007, 12:49:13 PM
Any chance you would post the code for your Init program?
Title: Re: Dialog "calling itself"
Post by: LarryMc on May 11, 2007, 02:02:53 PM
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
Title: Re: Dialog "calling itself"
Post by: LarryMc on May 11, 2007, 02:57:58 PM
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
Title: Re: Dialog "calling itself"
Post by: Bruce Peaslee on May 16, 2007, 12:58:19 PM
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.
Title: Re: Dialog "calling itself"
Post by: sapero on May 16, 2007, 02:26:34 PM
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);
}
}
}
}
Title: Re: Dialog "calling itself"
Post by: Bruce Peaslee on May 16, 2007, 03:14:23 PM
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.
Title: Re: Dialog "calling itself"
Post by: Parker on May 16, 2007, 03:35:21 PM
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;
}
Title: Re: Dialog "calling itself"
Post by: Rock Ridge Farm (Larry) on May 17, 2007, 05:26:47 AM
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.
Title: Re: Dialog "calling itself"
Post by: Bruce Peaslee on May 17, 2007, 10:00:32 AM
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;
}
Title: Re: Dialog "calling itself"
Post by: Ionic Wind Support Team 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);
Title: Re: Dialog "calling itself"
Post by: Bruce Peaslee on May 17, 2007, 12:55:53 PM
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.
Title: Re: Dialog "calling itself"
Post by: Bruce Peaslee on May 17, 2007, 02:42:50 PM
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.
Title: Re: Dialog "calling itself"
Post by: John S on May 17, 2007, 02:57:50 PM
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;
}