Keeping a Windows application on top of other windows and in focus - always
I am creating a kiosk application and I want to ensure it is always, no matter what, on top of other Windows applications and the Windows task bar.
I am already blocking Windows keyboard commands (alt-tab, etc) but there are still situations that could cause an application to launch and steal the screen.
Is it possible to hook into Windows from .NET and continually test whether the application has focus and is on top, and if not then give it focus and make it on top开发者_如何学运维?
I've actually worked on a production kiosk (it was Windows 2000, however). The solution was to run our application as the shell. You accomplish this in part by replacing Explorer.exe with your application in the Shell value at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
See here for some more information.
Now, we did have a secret (err... obfuscated) way to shut down our app. Then we would bring up Task Manager (Ctrl-Shift-Esc) and select File/New Task to run Explorer.exe to bring up a shell right then and there.
As an aside, when you work on a system like this, you naturally become very very proficient with the keyboard and all that it means to use keyboard shortcuts in Windows because you will likely not have a convenient way or place to put a mouse.
You might be able to do this just by replacing the shell with your application.
Here's a superuser question about replacing the shell with IE: https://superuser.com/questions/108265/how-do-you-replace-the-logon-shell-with-iexplore
If you only want to do it for the current user I think the path is
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
In this scenario you can run your application in full screen with always your window on top. I use the following snippet in some of my opengl apps (from http://nehe.gamedev.net/). It is in win32 but I think you can use pinvoke or System.Management.ManagementClass("Win32_VideoController")
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL);
This will switch your app to full screen and get rid of taskbar and disallow use from doing something other than using your app.
You can use API calls. The snag is you have to keep checking if your app has lost focus. Depends on exactly why you want to do it but...
Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Boolean
is the API declaration. Then you just need the window handle :)
精彩评论