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
408 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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

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: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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

Suggested Solutions

Title # Comments Views Activity
Thin secure Windows 10 5 102
Add values of each row in an array 3 64
Making an alias 7 101
"Black Box" Testing of Control System Software 2 72
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

830 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