Link to home
Start Free TrialLog in
Avatar of SGyves
SGyves

asked on

Calling DoModal() and getting -1

Hello again. I am setting up a Dialog based application. I am using the applications Main Dialog to display the introduction and title of the program, then when the user presses OK...I set up my property sheet and display the page..the problem is...when I go to DoModal for that page...I am not having successful results. Can someone tell me why? Here is the code snippet:

BOOL CAlchemyIntTestApp::InitInstance()
{
      // InitCommonControls() is required on Windows XP if an application
      // manifest specifies use of ComCtl32.dll version 6 or later to enable
      // visual styles.  Otherwise, any window creation will fail.
      InitCommonControls();

      CWinApp::InitInstance();

      // Standard initialization
      // If you are not using these features and wish to reduce the size
      // of your final executable, you should remove from the following
      // the specific initialization routines you do not need
      // Change the registry key under which our settings are stored
      // TODO: You should modify this string to be something appropriate
      // such as the name of your company or organization
      SetRegistryKey(_T("Local AppWizard-Generated Applications"));

      CAlchemyIntTestDlg dlg;
      m_pMainWnd = &dlg;
      INT_PTR nResponse = dlg.DoModal();
      if (nResponse == IDOK)
      {
            CCheckExpPage cePage;
            CImportFormPage ifPage;
            CTestInfoPage tstinfPage;
            CVerifyFilesPage vfPage;
            CVerifyTFPage vtfPage;

            //Begin Wizard Sequence
            CPropertySheet prpshtMain;
            prpshtMain.AddPage(&tstinfPage);
            prpshtMain.AddPage(&vtfPage);
            prpshtMain.AddPage(&vfPage);
            prpshtMain.AddPage(&cePage);
            prpshtMain.AddPage(&ifPage);

            prpshtMain.SetWizardMode();
            prpshtMain.DoModal();    ///Getting -1 here
            
      }
      else if (nResponse == IDCANCEL)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with Cancel
      }

      // Since the dialog has been closed, return FALSE so that we exit the
      //  application, rather than start the application's message pump.
      return FALSE;
}
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

You don't have to invoke DoModal inside of InitInstance, because it will stop the application's initilization process. Normally a modeless dialog is used. If you want to make your dialog to lauch another dialog, use a 3rd button (not IDOK or IDCANCEL) and control the WM_COMMAND message inside your dialog.
ASKER CERTIFIED SOLUTION
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SGyves
SGyves

ASKER

I also find that it does work if I comment out m_pMainWnd = &dlg...but then only the first page of my PropSheet displays...after hitting the Next button....the app fails again
Avatar of SGyves

ASKER

Ok...I am setting it up now...I will let you knwo how it goes.
>I also find that it does work if I comment out m_pMainWnd = &dlg...but then only the first page of my PropSheet displays...after hitting the Next button....the app fails again

That's because you application has not properly initialized, and some MFC internal context variables are still pointing to NULL. It is a bad trick.
Avatar of SGyves

ASKER

If I do it like that...then the original window is still open somewhere...I do not want that. I at the very least do not want it visible.
Avatar of SGyves

ASKER

Also...I am still getting invalid address messages when I hit Next on the first property page.
>I at the very least do not want it visible.
You can reposition main dialog (outside the screen) before calling Property Sheet, with SetWindowPos(), I dont recommend you to hide dialog because PropertySheet can disappear, but I am not sure about that (if you dont make it main dialog's child).
Avatar of SGyves

ASKER

I invoke OnOK() in the Continue handler...and that seems to get rid of the Original dialog. But for some reason...only the first page of my propertysheet list appears. As soon as I hit Next...I get Access Violations:

First-chance exception at 0x77f1850d in AlchemyIntTest.exe: 0xC0000005: Access violation writing location 0x00434d74.
First-chance exception at 0x00000030 in AlchemyIntTest.exe: 0xC0000005: Access violation reading location 0x00000030.
Unhandled exception at 0x00000030 in AlchemyIntTest.exe: 0xC0000005: Access violation reading location 0x00000030.
You have to invoke OnOk() AFTER PropertyDialog has closed, becuase you have created propertyPages within dialog, if you destroy main dialog, you destroy propertyPages objects.
Avatar of SGyves

ASKER

Ok....I had something major wrong with my stuff...I had to go back and redo all of my inheriting for my property pages. They were all inheriting from OlePropertyPage. OOOOppssss. So I deleted those classes and redid them...now all is well. You answered my original question so that is cool. I just wish I could get rid of the original window in a neater way.
Avatar of SGyves

ASKER

What is wrong with doing this???

BOOL CAlchemyIntTestApp::InitInstance()
{
      // InitCommonControls() is required on Windows XP if an application
      // manifest specifies use of ComCtl32.dll version 6 or later to enable
      // visual styles.  Otherwise, any window creation will fail.
      InitCommonControls();

      CWinApp::InitInstance();

      // Standard initialization
      // If you are not using these features and wish to reduce the size
      // of your final executable, you should remove from the following
      // the specific initialization routines you do not need
      // Change the registry key under which our settings are stored
      // TODO: You should modify this string to be something appropriate
      // such as the name of your company or organization
      SetRegistryKey(_T("Local AppWizard-Generated Applications"));

      

      CAlchemyIntTestDlg dlg;
      
      
      INT_PTR nResponse = dlg.DoModal();
      if (nResponse == IDOK)
      {
            CCheckExpPage cePage;
            CImportPage ifPage;
            CTestInfoPage tstinfPage;
            CVerifyFilesPage vfPage;
            CVerifyTFPage vtfPage;

            //Begin Wizard Sequence
            CPropertySheet prpshtMain;
      
            prpshtMain.AddPage(&tstinfPage);
            prpshtMain.AddPage(&vtfPage);
            prpshtMain.AddPage(&vfPage);
            prpshtMain.AddPage(&cePage);
            prpshtMain.AddPage(&ifPage);

            prpshtMain.SetWizardMode();
            m_pMainWnd = &prpshtMain;
            prpshtMain.DoModal();
            
      }
      else if (nResponse == IDCANCEL)
      {
            // TODO: Place code here to handle when the dialog is
            //  dismissed with Cancel
      }

      // Since the dialog has been closed, return FALSE so that we exit the
      //  application, rather than start the application's message pump.
      return FALSE;
}
> So I deleted those classes and redid them...now all is well.
Yes! Good choice! Most members refuse to start again the job, but they don't realize sometimes it is the best decision. In spanish we say something like: "Lazy man works twice".
Thanks,
Jaime.
I think this way could work, very interesting...
could be better if you leave PropertyDialog as modeless.
I can't examine all MFC internals but as documented, you have to return TRUE "soon" to start your app correctly. CWinApp::InitInstances does nothing, just return TRUE.
Avatar of SGyves

ASKER

Well...if it is just a Dialog app...once InitInstance is done...I don't want to do anything else. Because all of my stuff will have been completed by the time Initinstance is done.