Hi All,
I have a VC++ 6 app that stores Office documents. The user can select a document and select Launch which would launch the appropriate Office app (Word, Outlook, etc) for editing and wait for the Office app to exit before continuing. It does this by using CreateProcess to launch the Office app and monitoring the process handle returned with GetExitCodeProcess until the exit code is not STILL_ACTIVE. Outlook.exe is launched with the path to the file to open as a command line argument.
The problem I have is when the file is a .msg file. If Outlook is not running, this works as expected. However, if Outlook is running when the app does a launch, the first time GetExitCodeProcess is called immediately after CreateProcess, it returns STILL_ACTIVE. However after that it returns 0 for the exit code even though the Inspector is still open and therefore my app thinks the office app closed.
If I do WaitForInputIdle(procHandle, INFINITE) before calling GetExitCodeProcess, when WaitForInputIdle returns the exit code from GetExitCodeProcess is always 0. It seems that the process handle returned is not for the Inspector window, that it's an intermediate process that launches the Inspector. But I don't see anything in task manager for it.
Launching Outlook this way, the Inspector window caption is "Untitled - Message (HTML) " (note trailing space). I thought I could look for it with FindWindow(). At first I thought FindWindow wasn't finding the window. Then I discovered the trailing space in the caption. I'm initialling doing this for Outlook 2007. But it needs to work for 2010 and 2013 also. I'm not convinced the caption is exactly the same for all versions.
I thought about, but haven't tried yet, enumerating all windows and looking for part of the caption. But again, I'm not sure if I can look for the same text for all versions. If I could do this once and get some unique identifier like the process handle and do GetExitCodeProcess or WaitForSingleObject(which doesn't work either in this case for the same reason GetExitCodeProcess doesn't), that would be ok. But I haven't found a way to do that and to enumerate the windows each time for the check isn't efficient.
With the way Outlook is being launched, if I got the window handle once via enumeration or with FindWindow, calling IsWindow() may not be realiable since the app isn't directly creating the window and doesn't own it. Or would it be reliable since the app indirectly creates the Inspector and is waiting for that one to close?
Also, even though the FindWindow is done after the WaitForInputIdle after CreateProcess, Outlook gives a bad command line argument error. Sometimes. It doesn't happen if I step through the code nor if I don't do the FindWindow. However, if Outlook is running minimized when I do this, it's maximized when the error is put up. Although sometimes it works if Outlook is already running. This is what leads me to believe that the process handle from CreateProcess is an intermediate process that goes away after the Inspector comes up and not the one for the Inspector.
In the case of, for example Word, I can use /w to create a new instance. I have the process handle to that instance even if there is another instance of Word. I realize Outlook is different and there can be only one instance. At least I haven't found a switch to do a new instance anyway, which would really be what I want.
Anybody have any good ideas?
Thanks in advance.
Don Rosengrant