Link to home
Start Free TrialLog in
Avatar of cjm20
cjm20Flag for United States of America

asked on

Making an .exe modal when launched from another .exe in C++

I have a couple C++ apps.   One is coded with C++, using VC6.  The other app is also coded with C++, using VS2005.

Let's call them App_A and App_B, respectively.

Both of these apps contain a user interface.

I want to launch App_B from App_A.  And I want App_B to behave modally, in that, I want App_A's interface to be "disabled" while App_B is open.  Only When App_B is closed should App_A once again become enabled.

So far I can launch App_B successfully from App_A, using CreateProcess(....).  I also can get App_B to behave "modally" by calling WaitForSingleObject(pi.hProcess, INFINITE) immediately after launching it with CreateProcess(....).  However, I've found that if I click on the menu bar in App_A when App_B is open, then App_A displays the classic windows "(Not Responding)" message in its title bar, giving the appearance of a crash in progress (menu bar becomes white and menu text is obscured).

Any thoughts on how to tighten this up?  I feel like I'm 95% there.

Thanks very much.

Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Hide App_A (ShowWindow(HWND_ofMainWndHere, SW_HIDE)) whilst App_B is running then reshow afterwards - SW_SHOW in place of SW_HIDE.
Avatar of cjm20

ASKER

I would very much like to keep App_A in the background.  Sorry for not specifiying that in the initial question. The reason being is that there are graphics in App_A that are useful to see while using App_B.
Avatar of cjm20

ASKER

Perhaps instead of ShowWindow(...), I could use EnableWindow(HANDLE_App_A, FALSE)?
ASKER CERTIFIED SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland 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
SOLUTION
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
You could just try the EnableWindow call but you still might run into redrawing problems if you occlude part of App_A then show it again.
SOLUTION
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 cjm20

ASKER

Thanks to everyone for assisting.  I tried the above approaches, but finally decided to convert App_B from an .exe to a .dll.  This allows me to call the dll from App_A, and within the dll, call the dialog I need to display AS MODAL.  Thus, App_B now has all the normal modal functionality i'm looking for (App_A is disabled while using App_B, App_A is still visible while using App_B, etc).

To call App_B as a dll, I used the following approach (in case anyone is interested, this is the logic to call the dll from the calling application, aka App_A in my case -- i've omitted the error checking to make this concise):

m_hLibMyDll = LoadLibrary("MyDll.dll");

if (m_hLibMyDll != NULL)
{
m_lpfnMyDllFunction = (LPFNDLLFUNC)GetProcAddress(m_hLibMyDll , "MyDllExportedFunction");

int nOK = m_lpfnMyDllFunction ();

//process the dll return value, as necessary

}

As far as converting App_B to a dll, I simply created a new project in Visual Studio.   The new project is an "MFC Dll".  Then I added my preexisting files from my App_B project (which is an .exe) in the dll project.  Finally, as I've always had issues trying to copy / import dialogs and resources from one project to another, I recreated manually in the dll project the one and only dialog that exists in my App_B .exe project.  Once I had created (using the Class Wizard) a dialog class for it, I then copied the dialog code from App_B's MyDialog class into the dll's newly created MyDialog class.
Avatar of cjm20

ASKER

Just to clarify, when I said in the above comment "This allows me to call the dll from App_A, and within the dll, call the dialog I need to display AS MODAL", I meant this allows me to simply used the dlg.DoModal() functionality as provided by the CDialog class.  Thus, the dialog that was formerly inside App_B (but is now in a dll) can behave modally when called from App_A.