Many, maybe even most, Windows CE devices are single purpose devices that have an application that fills the entire screen. So of course setting the application to entirely fill the display is important. In this article we will explore setting an application to display full screen using C/C++.
My plan is to create a simple application that fills the screen with white and displays two buttons, exit and explore. Those may be odd buttons for a kiosk application, but they will come in handy while working on this application. The exit button will exit the application and the explore button will start the Explorer shell and then exit the application.
Working in Visual Studio 2005, I started by creating a new C++ Win32 Smart Device Application and let the wizard create the starting source code. I then deleted the code for the menu and the about dialog since I don’t need them. If we run the application now we will find two things about it; we can’t exit (now you know why I am going to add the exit button) and the Explorer shell’s task bar is filling part of the screen.
The application almost fills the screen. This is because the CreateWindow() call that was added by Visual Studio set the location and size using CW_USEDEFAULT. This causes the application size to be full screen, minus the task bar area.
Next let’s add the exit button. To do that, I added a global HWND and create the button with CreateWindow() in InitInstance():
 
HWND ExitButton;
 …
      ExitButton = CreateWindow(TEXT("Button"),TEXT("Exit"),
            BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,
            20,20,100,40,hWnd,(HMENU)IDM_FILE_EXIT,g_hInst,0);   
      if( ExitButton == NULL )
      {
            DWORD Error = GetLastError();
            RETAILMSG( 1, (TEXT("ExitButton failed %d\r\n"), Error));
            return FALSE;
                }
                              DestroyWindow(ExitButton);
 
Note that the button size and location are hardcoded, we will look at that later. When the button is pressed, the existing action for closing the application will be called, with the edition of a call to DestroyWindow() for the button. If you test the application now, the exit button will be placed in the top left corner and pressing the button will exit the application.
Let’s step back for little bit, this application is going to run in kiosk mode. That is the application will be full screen and we don’t need the Explorer shell. I discussed how to do this in a previous article, Windows CE: Starting an Application when the System Boots. My next step is to add the application to the OS and change the registry so that the Explorer shell doesn’t start and instead this applciation does start. The effect of this change is that the applciation now is full screen. We must add a call to SignalStarted():
      if( lpCmdLine )
            SignalStarted( _wtol(lpCmdLine) );
 
My work here is done. But I will continue.
Now if we test the application by pressing the Exit button, what we will find is that the application stops, but it doesn’t look like it stops because there is nothing to draw on the display. Since we don’t expect this condition in the real world, I am not going to do anything about it. But what I would like to do is start the explorer shell for testing and debugging purposes. To do that lets’s add the Explore button now. The explore button is similar to the exit button, but we will need to add more handling code to support it.
HWND ExplorerShellButton;
      ExplorerShellButton = CreateWindow(TEXT("Button"),TEXT("Explore"),
            BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,
            20 + 10 + 100,20,100,40,hWnd,(HMENU)IDM_EXPLORER_BUTTON,g_hInst,0);    
      if( ExplorerShellButton == NULL )
      {
            DWORD Error = GetLastError();
            RETAILMSG( 1, (TEXT("ExplorerShellButton failed %d\r\n"), Error));
            return FALSE;
      }
      case IDM_EXPLORER_BUTTON:
      {
            TCHAR *AppName = TEXT("Explorer.exe");
            TCHAR *CommandLine = NULL;
            PROCESS_INFORMATION pi;
 
            if( CreateProcess( AppName, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi))
            {
                  CloseHandle(pi.hProcess);
                  CloseHandle(pi.hThread);
            }
            else
            {
                  RETAILMSG( 1, (TEXT("Failed to start app: %s error %d\n"), AppName, GetLastError() ));
            }
      }
      //Fall through and exit
      DestroyWindow(ExplorerShellButton);
 
And in resource.h:
#define IDM_EXPLORER_BUTTON                   40003
Now when we test the application, the exit button works like it did before, but we can now use the Explore button to start up the Explorer shell before exiting. If you are testing with the Explorer shell already running, you will find that Windows Explorer starts.
Some of you are problably thinking that for some reason or another you need the Explorer shell running under your application. So you need the application to run full screen even when the task bar is available. To solve this, modify InitInstance() to find out the dimensions of the display and set the application to be top most and use the dimension of the display. The application can find the dimensions of the display using GetDeviceCaps(), and then use the dimensions in a call to SetWindowPosition():
      HDC hDC;
      DWORD Width;
      DWORD Height;
      hDC = GetDC(NULL);
      Width = GetDeviceCaps( hDC, HORZRES );
      Height = GetDeviceCaps( hDC, VERTRES );
 
                SetWindowPos(hWnd, HWND_TOPMOST,0, 0, Width, Height, 0 );
Now that we have the screen dimensions, I can move the buttons down to the bottom right where I think that they will be better placed:
      ExitButton = CreateWindow(TEXT("Button"),TEXT("Exit"),
            BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,
            Width - 200 - 20 - 10, Height - 40 - 20,100,40,hWnd,(HMENU)IDM_FILE_EXIT,g_hInst,0);
      ExplorerShellButton = CreateWindow(TEXT("Button"),TEXT("Explore"),
            BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE ,
            Width - 100 - 20, Height - 40 - 20,100,40,hWnd,(HMENU)IDM_EXPLORER_BUTTON,g_hInst,0);
     
Now we have an application that displays full screen. 
 
As you test the application with the Explorer shell still running, you will find that there is still a problem if the user has a full keyboard and can use hot keys like the Windows key. I would strongly urge you to consider running your kiosk application without the Explorer shell, so I won’t go into solving that problem now. If your application isn’t a kiosk application, but needs to be full screen, then you should consider leaving support for the hot keys, but I do know that sometimes that isn’t practical.
 
 
Copyright © 2010 – Bruce Eitman
All Rights Reserved