cjm20
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.hPr ocess, 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.
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.hPr
Any thoughts on how to tighten this up? I feel like I'm 95% there.
Thanks very much.
Hide App_A (ShowWindow(HWND_ofMainWnd Here, SW_HIDE)) whilst App_B is running then reshow afterwards - SW_SHOW in place of SW_HIDE.
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.
ASKER
Perhaps instead of ShowWindow(...), I could use EnableWindow(HANDLE_App_A, FALSE)?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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)GetProcAddres s(m_hLibMy Dll , "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.
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)GetProcAddres
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.
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.