views:

146

answers:

5

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?

A: 

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: http://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

ho1
A: 

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.

ferosekhanj
A: 

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 :)

El Ronnoco
A: 

The way I've done this in the past is to use Flash to take hold of the whole screen. But then you'll have to use ActionScript...

MonkeyWrench
This answer doesn't answer the question. It instead suggests using a completely different technology.
automatic
+2  A: 

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: http://technet.microsoft.com/en-us/library/cc939851.aspx

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.

Chris Gomez
Obfuscated way? It should probably involve a username and password :-)
Vincent McNabb
I don't want to pretend our method was fully secure. But at the same time I recognize that our solution to shut down the app and bring up Explorer to work on the kiosk is out of the scope of the question. But I pointed it out specifically to reinforce your point that you should think about this carefully and do better than we did.
Chris Gomez