Click here to Skip to main content
11,804,008 members (82,608 online)
Click here to Skip to main content

Tagged as

Mobile Development: Yet Another Kiosk Mode Library

, 3 Sep 2010 CPOL 11.9K 8
Rate this:
Please Sign up or sign in to vote.
How to disable StartMenu clicks and Win key for kiosk mode application using a library


Here is another kiosk mode library. It supports disabling clicks/taps on start menu icon and opening the Windows Mobile start menu using the win key (VKLWIN). Additionally there is a function to disable the whole StartMenu bar and one to make a window fullscreen without Done and Close button (uses SHFullScreen).

The functions are implemented in a DLL, so you can easily use them from C/C++, the .NET Compact Framework (CSharp or VB.NET), Java and so on.

Here is a list of the functions exported by the DLL:

void</span /> __stdcall</span /> LockStartMenu(); 	//</span /> this will install the hook 
</span />				//</span /> (subclass the taskbar window)
</span />void</span /> __stdcall</span /> UnlockStartMenu();   	//</span /> this will unhook TaskbarWindowProc from taskbar
</span />void</span /> __stdcall</span /> LockStartBar();  	//</span /> this disables the whole taskbar
</span />void</span /> __stdcall</span /> UnlockStartBar();    	//</span /> this enables the taskbar window
</span />bool</span /> __stdcall</span /> Lockdown(TCHAR*);    	//</span /> this will make the application with the 
</span />				//</span /> window title fullscreen, etc.
</span />bool</span /> __stdcall</span /> Unlockdown();    	//</span /> this will 'normalize' the fullscreen window</span />

I have included a demo application in C and .NET.

The left shows normal Windows CE window and the right the same window after pressing the [Lockdown window].

Usage and Function

LockStartMenu and UnlockStartMenu

To disable clicks on the StartMenu, you use the function LockStartMenu(). This function subclasses (hooks) the HHTaskbar window procedure.

void</span /> __stdcall</span /> LockStartMenu()
   taskbarhWnd = FindWindow(TEXT("</span />HHTaskBar"</span />), NULL);
   if</span /> (taskbarhWnd != NULL)
     WNDPROC p = TaskbarWindowProc;
     oldWindowProc = (WNDPROC)SetWindowLong(taskbarhWnd, GWL_WNDPROC, (long</span />)p);

Note about subclassing in Windows:

Subclassing a window means that your code gets executed on every message received by the original window. As you know, all windows have a central window procedure (wndproc). Every message to your window is going to this procedure. Normally you have a switch statement and case statements for the window messages you are interested to react on, like WM_CREATE, WM_PAINT, WM_LBUTTON, WM_KEYDOWN, WM_DESTROY etc. When you subclass a window, you install a new wndproc that is called before the original wndproc of the window. So you can manipulate things outside the original WndProc. You don't need the source code of the original window or application. Subclassing is used here to hook into the wndproc of HHTaskbar (the window class name of the window that is responsible for the windows mobile taskbar at the top of your screen).

The new window procedure checks the click coordinates for left button clicks (WMLBUTTONDWON). If the x and y values of the click location are within the height of the taskbar and up to 2/3 of the screen width, the click is not forwarded to the taskbar window. So HHTaskbar does not get notified about the click and will not open the StartMenu.

	(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  if</span /> (message == WM_LBUTTONDOWN)
        POINTS pts;
        pts.x = LOWORD(lParam);
        pts.y = HIWORD(lParam);
        //</span />the hot area of the StartMenu extends with the length of 
</span />        //</span />the current window title text
</span />        //</span />we get the actual screen width and then assume half the width as hot area
</span />        int</span /> screenwidth = GetSystemMetrics(SM_CXSCREEN);
        if</span />(screenwidth!=0)
           MAX_START_X = (int</span />)(screenwidth * 2</span /> / 3</span />);
        if</span /> (pts.y <</span /> MAX_START_Y && pts.x <</span />)
                       return</span /> TRUE;

The new Taskbar window procedure also checks, if the user has pressed the Win key. The win key (VKLWIN) would bring up the start menu too. The function TaskbarWindowProc therefore also checks for key messages and filters the VKLWIN keypress. So the user is not able to invoke the start menu by pressing the win key.

    if</span /> (message == WM_KEYDOWN && wParam == VK_LWIN && lParam == 1</span />)
       return</span /> TRUE;
   return</span /> CallWindowProc(oldWindowProc, hWnd, message, wParam, lParam);

Messages that are not filtered are forwarded to the original window procedure of HHTaskbar.

Why not just disable the whole taskbar? This is for applications that will not lock you down completely. If you disable the whole taskbar (see also LockStartBar()), you will not be able to click the connection, volume and close symbols on the taskbar.

Here is a screen shot of the .NET demo app with a long title. Only the area inside the red rectangle is blocked. The remainder of the taskbar is clickable.

As you see with the .NET demo app, you can lock the user from opening the startmenu, but you can launch an external app (like the calculator) and the startmenu is still blocked. In the external app, the user can still click the (X) to close (hide) the app and is back in our kiosk application demo.

The second function UnlockStartMenu() will restore the original WndProc of HHTaskbar and ‘unhook’ our window procedure. So the start menu will then work as usual.

void</span /> __stdcall</span /> UnlockStartMenu()
 if</span />(bStartmenuLocked){
   if</span /> (oldWindowProc!=NULL)
      oldWindowProc = (WNDPROC)SetWindowLong
	(taskbarhWnd, GWL_WNDPROC, (long</span />)oldWindowProc);
   oldWindowProc = NULL;

This function will restore the original window procedure and unhooks our new wndpro. So HHTaskbar should then behave normally.

LockStartBar and UnlockStartBar

The second pair of the DLL functions is called LockStartBar() and UnLockStartBar(). The first one looks for the window with the class name HHTaskbar and will then disable the window. Disabling a window prevents the window procedure from getting any more window messages. So HHTaskbar will not receive any clicks as long as the window is disabled.

void</span /> __stdcall</span /> LockStartBar()
 //</span />Disable the whole HHTaskbar window
</span /> if</span />(!bStartbarLocked){
   taskbarhWnd = FindWindow(TEXT("</span />HHTaskBar"</span />), NULL);  
   if</span /> (taskbarhWnd != NULL)
     EnableWindow(taskbarhWnd, false</span />);

This function and the UnlockStarBar() function are very simple.

void</span /> __stdcall</span /> UnlockStartBar()
 if</span /> (bStartbarLocked)
   taskbarhWnd = FindWindow(TEXT("</span />HHTaskBar"</span />), NULL);
   if</span /> (taskbarhWnd != NULL)
     EnableWindow(taskbarhWnd, true</span />);

But as some .NET and JAVA and other non-native programming languages don't have the essential windows functions like FindWindow, etc., I have included these functions in the DLL for easy use.

LockDown(Window Title) and UnLockDown()

The last pair of functions is using a combination of kiosk mode techniques I am aware of: LockDown(TCHAR*) and UnLockDown().

bool</span /> __stdcall</span /> Lockdown(TCHAR *windowText)
 //</span /> If the application is already locked down, don't attempt to lock it down again.
</span /> if</span /> (hWndLockdown)
   return</span /> TRUE;
 if</span />(!bLockedDown){
   HWND hWnd = 0</span />;
   TCHAR *str;
   str = (TCHAR*) malloc( MAX_PATH * sizeof</span />(TCHAR));  
   wcscpy (str, windowText);
   if</span /> ((!str) || (wcslen(str) <</span />= 0</span />))
     hWnd = FindRootWindowByFocus();
   else</span />
     hWnd = FindRootWindowByName(str);
   if</span /> (!hWnd)
     return</span /> FALSE;
   SetForegroundWindow(hWnd);     		//</span /> Required before SHFullScreen Calls
</span />   SHDoneButton(hWnd, SHDB_HIDE);
   MoveWindow(hWnd, 0</span />,0</span />, 240</span />,320</span />, TRUE);  	//</span /> Expand to use the entire screen 
</span /> 
   hWndLockdown = hWnd;
 return</span /> TRUE;

First the function tests, if the lockdown for the window with the given title text was already done. If not, it searches the window handle of a window with the title specified. If a window is found, it will be set to the foreground and then the Microsoft API calls to make a window fullscreen are invoked for the window handle. The window is also made fullscreen (with currently hardcoded screen dimensions, change this, if you need) and our LockStartMenu function is called.

The last function in our list tries to revert the function of LockDown and tries to restore the window to a normal state.

Why did I write these two LockDown functions? They make it very easy for .NET and JAVA programmers to make their Windows mobile application a fullscreen kiosk mode application by just calling LockDown(window title) with the title of the window to make fullscreen.

private</span /> void</span /> btn_LockDown_Click(object sender, EventArgs e)
 string title = this</span />.Text;
 if</span /> (!_bFullScreen)
   _bFullScreen = true</span />;
   label1.Text = "</span />Form made fullscreen"</span />;
 else</span />
     label1.Text = "</span />Form was already fullscreen"</span />;

(See also the video at

Doing fullscreen from Win32 native C is much easier than writing all the PInvokes you needed to get the same result.

<!-- Social Bookmarks BEGIN -->

<!-- Social Bookmarks END -->


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Germany Germany
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralMy vote of 5 Pin
Norzagaray29-Jan-12 19:00
memberNorzagaray29-Jan-12 19:00 
QuestionRemove dependency on Win CE? Pin
Claire Streb12-Dec-11 13:02
memberClaire Streb12-Dec-11 13:02 
AnswerRe: Remove dependency on Win CE? Pin
hjgode12-Dec-11 17:10
memberhjgode12-Dec-11 17:10 
GeneralRe: Remove dependency on Win CE? Pin
Claire Streb13-Dec-11 3:36
memberClaire Streb13-Dec-11 3:36 
GeneralRe: Remove dependency on Win CE? Pin
hjgode13-Dec-11 6:32
memberhjgode13-Dec-11 6:32 
GeneralLooks good... Pin
Sandeep Mewara3-Sep-10 22:46
mentorSandeep Mewara3-Sep-10 22:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.151002.1 | Last Updated 4 Sep 2010
Article Copyright 2010 by hjgode
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid