4

I've written a simple launcher that looks up the actual program and then executes it. This works fine, but there is one issue: Windows displays the "pointer with hourglass" cursor for about give seconds. This does not happen if I launch the program directly.

I tried setting sinfo.dwFlags = STARTF_FORCEOFFFEEDBACK but this did not help. I guess that's because it's my program that somehow needs to disable the cursor and the program I start does that fine (it creates a proper window etc.).

This is the relevant code from my application. I do not have any threads or any other fancy stuff (the sole purpose of the program is to launch another program and pass on the exit code to its caller in case it cares about it):

STARTUPINFO sinfo = {0};
PROCESS_INFORMATION pinfo = {0};
if (!CreateProcess(program, buf, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {
    Fail("Could not launch Vim");
}
if (WaitForSingleObject(pinfo.hProcess, INFINITE) == WAIT_FAILED) {
    Fail("WaitForSingleObject");
}
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636

2 Answers2

4

Apparently Windows expects a Windows program to process messages and does not consider it fully started before that point, which is why it shows the appstarting cursor.

Adding the following code to process a single dummy message solved the problem:

MSG msg;
PostMessage(NULL, WM_NULL, 0, 0);
GetMessage(&msg, NULL, 0, 0);
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
2

Your program is showing the hour-glass icon because your UI thread is hanging as a result of being stalled on the WaitForSingleObject call. Remember, WaitForSingleObject does not return until after the child process exits. You could substitute the Wait call with a Sleep and get the same effect.

You have some options:

  1. Use MsgWaitForMultipleObjects instead of WaitForSingleObject. This is the more formal way to pump messages and wait at the same time instead of the PostMessage/GetMessage thing you suggest in your own answer.

  2. Do the Wait call on another thread. When the thread returns, it PostMessage something to your UI thread to indicate it is done.

In both of the above cases, the UI will become responsive to clicks and input events while the child process is still happening. You will need to code your UI thread to handle this as appropriate (if it's warranted).

selbie
  • 100,020
  • 15
  • 103
  • 173
  • The program has no UI. It's sole purpose it to start another program. The only reason why I don't terminate after launching the other program is to make other programs happy which want to check when the program they launched has exited. – ThiefMaster Dec 27 '13 at 02:59
  • If you compile your code as a "Win32 Console Application" project type rather than a normal "Win32 Application", replace "WinMain" with "main", then this problem will go away. You'll stil have a console window auto-generated for you, however. If you can't have your code run as a console application, then either of the two above solutions I outline will work just fine. – selbie Dec 27 '13 at 04:57
  • Yeah, I don't want that console window ;) – ThiefMaster Dec 27 '13 at 12:01