views:

1206

answers:

4

I have an application that manages patient demographic information. Along with this data a user can scan a picture of a patient and assign that picture to a patient. When the user clicks the scan button a separate application is opened as a dialog in order to scan the image. When running this on XP everything worked fine. The imaging application loaded up fine and gained focus. On Vista however occasionally the imaging application will not gain focus and will popup behind the main application. When running full screen or through 2008 Application Server you cannot see the application, you only get a locked screen and it appears nothing has happened. Is there any way to change the window focus management on Vista to work the way XP did? I'm looking for a way to solve this without making changes to the actual application if possible.

A: 

You could iterate through all top level HWNDs and identify the scanning application via its window class, then send an appropriate message to raise the window.

David Schmitt
+1  A: 

I think you will have to make changes to your application to allow the imaging application to take the focus. I'm going to assume that your application launches the imaging application through ShellExecute or CreateProcess. If so, you can get the process handle of the launched process either through SHELLEXECUTEINFO.hProcess (for ShellExecute) or PROCESS_INFORMATION.hProcess (for CreateProcess). Immediately after launching the imaging application call the AllowSetForegroundWindow API:

AllowSetForegroundWindow(GetProcessId(hProcess));

This will allow the imaging application to place its main window/dialog in the foreground when it's starting up.

Bradley Grainger
+1  A: 

You could try the following steps:
1. Right Click on the exe
2. Select Properties
3. Select the Compatibility Tab
4. Check the Run this program in campatibility mode for:
5. Select Windows XP (Service Pack 2)

PersistenceOfVision
I am unable to do this because this application must be able to run from a network drive and you cannot enable compatibility mode on applications stored on a network drive.
John Chuckran
A: 

I don't believe this is Vista vs XP related. I think that simply this imaging app takes longer to start on Vista. Since Windows 2000, the window manager has prevented background applications stealing the foreground. When an application is launched, it has a window of opportunity to create and show a window that will take the foreground. If it takes too long, the window manager thinks that the current window should keep the foreground, and inhibits the other app taking the foreground when it does finally launch.

I can't think of any specific way to avoid this... other than using FindWindow to search for the other apps window after launching the app. When you eventually find it, call SetForegroundWindow on it to bring it to the foreground.

Chris Becke
Since the main window thread is locked when the Imaging App is opened it should not prevent the stealing of focus. This was true in XP so it does not happen at all on XP. Vista's DWM is generally better than XP because it treats windows as containers, it just causes problems in this scenario.
John Chuckran
I have no idea what you mean by "locked" in this context. The window manager doesnt care if the thread that owns the foreground is pumping messages. The no-steal-foreground does not rely on the current foreground window owning thread pumping messages to inhibit foreground theft.
Chris Becke
Sorry I meant to use the word "Blocked". As in the window does not accept any input until the dialog is closed.
John Chuckran
You have disabled the application window before launching the imaging application? Disabled windows cannot have foreground activation, so disabling the window will cause the window manager to try and find another window to give the foreground to - a random enabled top level window will be chosen.
Chris Becke
Create a dialog with no controls just showing the text "Launching Imaging..." on it. Create this dialog modally when launching imaging - it will disable your main frame window, but keep foreground activation on the current thread so the launched app should retain the ability to take foreground.
Chris Becke