Solved

MFC, C++: continuing execution in a block of code that calls a dialog's DoModal(), without closing the dialog to the user

Posted on 2007-11-19
15
405 Views
Last Modified: 2013-12-14
I'm having a small MFC related problem I hoped one of you could help me with.

I'm writing a database front-end.

The first thing the user sees is an authentication dialog. This is done in my main application class:

BOOL MyApp::InitInstance()
{
      
      CAuthenticate Login;
start:
      Login.DoModal();
      if(Login.m_bTerminate) // if the user pressed cancel (actually, he'd still call OnOK(), but change this bool)
            return FALSE;

// (try/ catch block for database connectivity). if it fails, we goto "start".
      Login.DestroyWindow(); // we have our connection, lets destroy the dialog



How this appears to the user is:

1. He enters his authentication details.
2. He presses OK, and waits up to a few seconds without it being immediately evident that anything is happening - you can't see anything that relates to my application - not the authentication dialog, because it's OnOK() has been called, and not the main window (yet), because it has yet to be initialised.

I'd like to only have the authentication dialog disappear only when the database object has been successfully instantiated, so the user isn't left hanging for several seconds, wondering where the program has gone.

How can this be done?

I thought I could call  Login's OnOK() after the database connection was established, but I'm not aware of any way to make execution continue in the main application block without making the dialog disappear.

While the DB connection object is instantiated on the heap, I'd still rather do this within my main application class, because I've already implemented an assessor method within that class, which is already used extensively in many other views and dialogs.

What should I do?

Regards,
Sternocera
0
Comment
Question by:sternocera
  • 5
  • 5
  • 5
15 Comments
 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 20311871
The call should be like this:

if(myDlg.DoModal()==ID_OK)
{
..
..
}

Best Regards,
DeepuAbrahamK
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 20311925
First
Login.DestroyWindow(); // we have our connection, lets destroy the dialog

The DoModal will exit AND DESTROY THE DIALOG as part of that.  You probably have some artefact as the main dialog isn't yet shown in place of the other dialog.


The simplest is to launch your main dialog then the authenticate dialog.  After the authenticate dialog returns then start a timer and set some values.
In the OnTimer first kill the timer then check what is to be done and do it.
0
 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 20311926
f(Login.DoModal()==ID_CANCEL)
{
...
...
//Exit
}
else if(Login.DoModal()==ID_OK)
{
...
...
...
}

In CAuthenticate::OnOk you should handle the try catch of db connection rather than in the Initinstance here.

CAuthenticate::OnOk ()
{

/ /close the dialog only if you have the db conection
}

Best Regards,
Deepu Abraham K

0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 

Author Comment

by:sternocera
ID: 20312176
"The simplest is to launch your main dialog then the authenticate dialog.  After the authenticate dialog returns then start a timer and set some values.
In the OnTimer first kill the timer then check what is to be done and do it."

Andy,

Nice to hear from you again.

I'm not sure what you mean by this.

Because connecting to the database my happen almost immediately, or may take a few seconds, (depending on variables outside my control that cannot be predicted) I cannot know in advance how long it will take.

Here's an idea:

put the try/catch block through which database connectivity is established into a CMyApp bool member function, say, "MakeConnection".

do something like this within the dialog:
CMyApp* pApp = (CMyApp*) AfxGetApp();
if( pApp->MakeConnection())
    CDialog::OnOK()

Do you think this is a good idea?

Thanks

0
 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 20312212
Is it inside CAuthenticate::OnOk () then it should be alright?

Best Regards,
DeepuAbrahamK

0
 
LVL 11

Assisted Solution

by:DeepuAbrahamK
DeepuAbrahamK earned 100 total points
ID: 20312228
I mean it should be fine if you are calling  as follows:

CAuthenticate::OnOk ()
{
CMyApp* pApp = (CMyApp*) AfxGetApp();
if( pApp->MakeConnection())
    CDialog::OnOK()
else
  // do some thing

}

0
 
LVL 44

Accepted Solution

by:
AndyAinscow earned 400 total points
ID: 20312277
:-)
Your main dialog is not going to appear until after the OnInitDialog of that dialog has finished and exited.  The DoModal loop (authenticate dialog) when exited will destroy the window objects of that dialog.  So because you still see it on screen means that for some reason the screen has not yet been redrawn there - very likely because windows is waiting for the OnInitDialog to finish.
So, remove the lengthy (database interrogation) code from the OnInitDialog so that will finish, the main dialog is shown and then perform the actions that where in the onInitDialog that took time.  eg in response to a timer message.

Much neater however would be the following logic

authenticate dialog display
check results
main dialog display
0
 

Author Comment

by:sternocera
ID: 20312347
Andy,

You're right, it makes sense for database interrogation to actually occur within the authentication dialog, and no where else - you're also right about the database stuff delaying display of the main window (I understood that, but hoped to somehow put off the CDialog disapearing until the connection was established).

I should just instantiate it on the heap within the dialog, then copy a pointer to it to the main app object.

I'll let you know how I get on.

Thanks

and thank you DeepuAbrahamK
0
 

Author Comment

by:sternocera
ID: 20312440
Andy, DeepuAbrahamK,

That's gone nicely, thank you both very much.

I hope you'll consider the way I've aportioned points fair,

Regards,
Sternocera
0
 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 20312453
Cool all the best !
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 20312494
:-)
0
 

Author Comment

by:sternocera
ID: 20312519
One other follow-up question: Now my connect button appears "pushed-down" for as long as it takes to connect to the DB. Is it possible to have it "come up" before the db connection occurs, so it won't get stuck (If not, I'll live with it)?

Thanks,
Sternocera
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 20312734
If the button 'comes up' and the user sees nothing happening then often the button will be clicked again in desperation.
0
 

Author Comment

by:sternocera
ID: 20312759
Yeah, that's an interesting perspective. I was going to do a little "connecting..." animation, but perhaps what you've suggested in more consistent with the expectations of windows' users.

Thanks
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 20312801
An animation would of course reenforce that.
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Sed question 2 84
operator overload: incompatible type and too many params 5 76
passing data from one form to another form in c++ 27 79
Way to decrease size of apk file 9 65
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

786 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