steva
asked on
Why does dialog box for calling program turn white?
I have an MFC program that calls another program with ShellExecuteEx() and I notice that the outline of the dialog box for the calling program turns white while waiting for the called program to exit. The call code is
ZeroMemory(&ShellExecuteIn fo, sizeof(ShellExecuteInfo));
str.Format("%d", daysLeft); // parameter to pass
ShellExecuteInfo.cbSize = sizeof(ShellExecuteInfo);
ShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShellExecuteInfo.hwnd = NULL; // NULL for local window
ShellExecuteInfo.lpVerb = "open";
ShellExecuteInfo.lpFile = lpFile; // file to call: Buy.exe
ShellExecuteInfo.lpParamet ers = str; // daysLeft parameter
ShellExecuteInfo.nShow = SW_SHOWNORMAL;
/*
Wait at 0% CPU utilization.
*/
WaitForSingleObject(ShellE xecuteInfo .hProcess, INFINITE); // infinite timeout
////////////////////////// ////////
Does anyone know what's going on here. I would like the calling program dialog box to remain visible while the called program executes.
Thanks,
steva
ZeroMemory(&ShellExecuteIn
str.Format("%d", daysLeft); // parameter to pass
ShellExecuteInfo.cbSize = sizeof(ShellExecuteInfo);
ShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShellExecuteInfo.hwnd = NULL; // NULL for local window
ShellExecuteInfo.lpVerb = "open";
ShellExecuteInfo.lpFile = lpFile; // file to call: Buy.exe
ShellExecuteInfo.lpParamet
ShellExecuteInfo.nShow = SW_SHOWNORMAL;
/*
Wait at 0% CPU utilization.
*/
WaitForSingleObject(ShellE
//////////////////////////
Does anyone know what's going on here. I would like the calling program dialog box to remain visible while the called program executes.
Thanks,
steva
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.
Funny, where have I seen that code before? Ah, I remember: http://search.experts-exchange.com/simpleSearch.jsp?q=ExecuteAndWaitForCompletion&TAFilterID=0&sfZoneID=-1
jkr - Is that the correct link?
Takes me to the "Search Results" page.
me as well.
ASKER
The CreateProcess code works ok. The problem seems to be with my
WaitForSingleObject(ShellE xecuteInfo .hProcess, INFINITE); // infinite timeout
If I have CreateProcess wait this way, I see the white dialog box again. And if I change my ShellExecute to wait with
WaitForSingleObject(ShellE
If I have CreateProcess wait this way, I see the white dialog box again. And if I change my ShellExecute to wait with
ASKER
I hit a tab by mistake and posted a partial comment above. Here's what I meant to say:
The CreateProcess code works ok. The problem of my calling dialog going white seems to be with my
WaitForSingleObject(ShellE xecuteInfo .hProcess, INFINITE);
after the calling code. If I have your CreateProcess wait this way, I see the white dialog box again until the called process exits. And if I change my ShellExecute to wait with
do {
GetExitCodeProcess(si.hPro cess, &ExitCode);
}
while(ExitCode == STILL_ACTIVE);
instead of WaitForSingleObject it works: I see the normal dialog box again while the called program runs.
Does that give us any clues about what's going on?
By the way, Andy, white is not the normal state of calling dialog when I switch focus by starting something like notepad. The dialog box stays colored and completely drawn.
Thanks for your help.
steva
The CreateProcess code works ok. The problem of my calling dialog going white seems to be with my
WaitForSingleObject(ShellE
after the calling code. If I have your CreateProcess wait this way, I see the white dialog box again until the called process exits. And if I change my ShellExecute to wait with
do {
GetExitCodeProcess(si.hPro
}
while(ExitCode == STILL_ACTIVE);
instead of WaitForSingleObject it works: I see the normal dialog box again while the called program runs.
Does that give us any clues about what's going on?
By the way, Andy, white is not the normal state of calling dialog when I switch focus by starting something like notepad. The dialog box stays colored and completely drawn.
Thanks for your help.
steva
Are you performing some drawing of the non-client (border) yourself in the dialog?
Have you customised the message routing in the dialog ?
Have you customised the message routing in the dialog ?
ASKER
No to both questions.
It seems that what's happening is that the dialog can't redraw itself when the application is in a WaitForSingleObject or WaitForMultipleObjects sleep. Let me provide a little more detail.
The calling dialog box gets overlaid by the window of the called program, which is a browser displaying an order form. When the form is submitted and accepted, a smaller "accepted" window replaces it which contains a license value. This smaller windows has xy coordinates and a size that allows it and the original calling dialog to be seen simultaneously on the screen. The user is then supposed to copy the license value in the accepted window and paste it into a field of the calling program's dialog in order to license the application permanently. My problem is that the calling dialog is white when the maxed order form windows closes so the user can't paste the license value into it.
As I was saying at the top of this, it seems that when the calling dialog is in a simple
WaitForSingleObject or WaitForMultipleObjects sleep it doesn't receive the messages to repaint itself when the maxed order form window closes and reveals the area where the calling dialog sits.
If I omit the
while ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage ( &msg);
}
}
from the CreateProcess code above I get the same white hole where my dialog should be when the orderform window closes.
So maybe we've solved it. I'll just add the Peek/Dispatch code. If you guys don't have anything more to add I'll wrap this up and split the points with you for having this conversation with me that led to a solution.
It seems that what's happening is that the dialog can't redraw itself when the application is in a WaitForSingleObject or WaitForMultipleObjects sleep. Let me provide a little more detail.
The calling dialog box gets overlaid by the window of the called program, which is a browser displaying an order form. When the form is submitted and accepted, a smaller "accepted" window replaces it which contains a license value. This smaller windows has xy coordinates and a size that allows it and the original calling dialog to be seen simultaneously on the screen. The user is then supposed to copy the license value in the accepted window and paste it into a field of the calling program's dialog in order to license the application permanently. My problem is that the calling dialog is white when the maxed order form windows closes so the user can't paste the license value into it.
As I was saying at the top of this, it seems that when the calling dialog is in a simple
WaitForSingleObject or WaitForMultipleObjects sleep it doesn't receive the messages to repaint itself when the maxed order form window closes and reveals the area where the calling dialog sits.
If I omit the
while ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage ( &msg);
}
}
from the CreateProcess code above I get the same white hole where my dialog should be when the orderform window closes.
So maybe we've solved it. I'll just add the Peek/Dispatch code. If you guys don't have anything more to add I'll wrap this up and split the points with you for having this conversation with me that led to a solution.
ASKER
Ah! I see the CreateProcess code above uses MsgWaitForMultipleObjects, not WaitForMultipleObjects, and that's the key. MsgWaitForMultipleObjects will return when "a system event requires the thread's action, such as foreground activation." That's what I need.
ASKER
Oh oh! While MsgWaitForMultipleObjects let's the user see the calling dialog now, he still can't paste into it until the called program exits. Is there something to pass along "write" requests while the dialog is waiting?