Is there a way to force a Windows application to always be on top?
-
We would call this a system modal situation, but there is a twist - I have no source code for the application in question (so, no ::SetWindowPos). The big picture - my application is running, and it's full screen. Think of a kiosk like application... no window manager, no task bar, no keyboard. Should the user choose to, they can invoke a calibration utility for the touchscreen. When calibration is complete, the utility helpfully posts an AfxMessageBox("Calibration complete"). Here's where my woe begins... If the user is careful, they can press the acknowledge box and the utility terminates. Choose poorly, and the application pops up over the dialog, effectively causing a blocking window inversion. I think I can work around this by not blocking with the CreateProcess call, but I haven't tried it yet. So, any other ideas? I'm going to write the oem for a variation on the utility, but I don't have much hope there. thanks
Charlie Gilley Stuck in a dysfunctional matrix from which I must escape... "Where liberty dwells, there is my country." B. Franklin, 1783 “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
-
We would call this a system modal situation, but there is a twist - I have no source code for the application in question (so, no ::SetWindowPos). The big picture - my application is running, and it's full screen. Think of a kiosk like application... no window manager, no task bar, no keyboard. Should the user choose to, they can invoke a calibration utility for the touchscreen. When calibration is complete, the utility helpfully posts an AfxMessageBox("Calibration complete"). Here's where my woe begins... If the user is careful, they can press the acknowledge box and the utility terminates. Choose poorly, and the application pops up over the dialog, effectively causing a blocking window inversion. I think I can work around this by not blocking with the CreateProcess call, but I haven't tried it yet. So, any other ideas? I'm going to write the oem for a variation on the utility, but I don't have much hope there. thanks
Charlie Gilley Stuck in a dysfunctional matrix from which I must escape... "Where liberty dwells, there is my country." B. Franklin, 1783 “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
You can still use
SetWindowPos
. You just need to get the handle to the message box.FindWindow
will get you this handle. The best way would be to install a shell hook usingSetWindowsHookEx
which will then give you a notification when the message box pops up and also its handle. You could then useSetWindowPos
on the handle to make it top most. It is for you to decide if it is worth installing the shell hook because it will effect the entire system.«_Superman_» _I love work. It gives me something to do between weekends.
_Microsoft MVP (Visual C++) (October 2009 - September 2013)
-
You can still use
SetWindowPos
. You just need to get the handle to the message box.FindWindow
will get you this handle. The best way would be to install a shell hook usingSetWindowsHookEx
which will then give you a notification when the message box pops up and also its handle. You could then useSetWindowPos
on the handle to make it top most. It is for you to decide if it is worth installing the shell hook because it will effect the entire system.«_Superman_» _I love work. It gives me something to do between weekends.
_Microsoft MVP (Visual C++) (October 2009 - September 2013)
Ah, I understand now. Thanks.
Charlie Gilley Stuck in a dysfunctional matrix from which I must escape... "Where liberty dwells, there is my country." B. Franklin, 1783 “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
-
We would call this a system modal situation, but there is a twist - I have no source code for the application in question (so, no ::SetWindowPos). The big picture - my application is running, and it's full screen. Think of a kiosk like application... no window manager, no task bar, no keyboard. Should the user choose to, they can invoke a calibration utility for the touchscreen. When calibration is complete, the utility helpfully posts an AfxMessageBox("Calibration complete"). Here's where my woe begins... If the user is careful, they can press the acknowledge box and the utility terminates. Choose poorly, and the application pops up over the dialog, effectively causing a blocking window inversion. I think I can work around this by not blocking with the CreateProcess call, but I haven't tried it yet. So, any other ideas? I'm going to write the oem for a variation on the utility, but I don't have much hope there. thanks
Charlie Gilley Stuck in a dysfunctional matrix from which I must escape... "Where liberty dwells, there is my country." B. Franklin, 1783 “They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
You could do your own calibration or have vendor remove dialog box. Failing that, when the calibration utility is started, you could have a thread monitor windows ans when that window pops up, either force it to the foreground or just close it yourself. Where it gets tricky is that only the current active, foreground application can make another application the foreground and despite appearances, who is this application isn't always straightforward. To get around this for one project, I ended up writing the following (The W is the prefix for my personal, but in-the-public-domain, library:
bool WSetAppToForeground(LPCWSTR pWindowName)
{
HWND hWnd = FindWindow(NULL, pWindowName);
if (!hWnd)
return false;WSetAppToForeground(hWnd); return true;
}
void WSetAppToForeground(HWND hWnd, bool showMax, bool setFocus)
{
#ifndef _WIN32_WCE
DWORD foregroundProcessId = GetWindowThreadProcessId(::GetForegroundWindow(), NULL);
DWORD curThreadId = GetCurrentThreadId();
AttachThreadInput(foregroundProcessId, curThreadId, TRUE);
#endifShowWindow(hWnd, showMax ? SW\_SHOWMAXIMIZED : SW\_SHOW); BringWindowToTop(hWnd); SetActiveWindow(hWnd); SetForegroundWindow(hWnd); if (setFocus) SetFocus(hWnd);
#ifndef _WIN32_WCE
AttachThreadInput(foregroundProcessId, curThreadId, FALSE);
#endif
}