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
412 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
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!

 

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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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 …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

737 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