?
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
Medium Priority
?
419 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

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 400 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 1600 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: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
In this post we will learn different types of Android Layout and some basics of an Android App.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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.
Suggested Courses

752 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