Creating a Sample Application

This section contains a code example used to create a simple Windows CE–based application. This sample application demonstrates the basic framework common to all Windows CE–based applications. It begins executing with the WinMain function, which performs the following tasks:

  1. WinMain places the application-instance handle in a global variable. Because this handle is used in various places throughout an application, it is common to place it in a global variable that is accessible to all functions. The smallest possible interval a timer can measure is the system-tick interval.
  2. WinMain calls the application-defined InitApplication function, which then calls the RegisterClass function to register the application's main window class. More complicated applications might need to register more window classes and determine if other instances of the application are running.
  3. WinMain calls the application-defined InitInstance function, which then calls the CreateWindow function to create a window. CreateWindow returns a window handle identifying the new window. This handle is used to refer to the window in subsequent function calls.
  4. WinMain creates the message loop by calling the GetMessage, TranslateMessage, and DispatchMessage functions in the format displayed in the sample application. This loop receives messages and dispatches them to the window procedures.

Note that the application does not directly call the window procedure, MainWndProc. The system calls this function as the message loop receives and dispatches messages. In this application, MainWndProc processes only the WM_CLOSE message that tells the window to close. When the window receives a WM_CLOSE message, it calls the PostQuitMessage function, which then calls GetMessage to return FALSE. This, in turn, causes the message loop to terminate and the application to exit.

Windows CE sends many other messages to the window besides WM_CLOSE. MainWndProc passes all other messages to the DefWindowProc function, the default window procedure provided by the system. Pass all messages to DefWindowProc that you do not process yourself; otherwise, your window might not function correctly. The following code example shows a framework for creating a Windows CE–based application.

#include <windows.h>

HINSTANCE g_hInst = NULL;     // Handle to the application instance
HWND g_hwndMain = NULL;       // Handle to the application main window
TCHAR g_szTitle[80] = TEXT ("Main Window"),    
                              // Application main window name
      g_szClassName[80] = TEXT ("Main window class");  
                              // Main window class name
                
/***********************************************************************

FUNCTION: 
  WndProc

PURPOSE: 
  The callback function for the main window. It processes messages sent
  to the main window.

***********************************************************************/
LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg, WPARAM wParam, 
                          LPARAM lParam)
{
  switch (umsg)
  {
    // Add cases such as WM_CREATE, WM_COMMAND, WM_PAINT if you don't 
    // want to pass these messages along for default processing.

    case WM_CLOSE:
      DestroyWindow (hwnd);
      return 0;

    case WM_DESTROY:
      PostQuitMessage (0);
      return 0;
  }

  return DefWindowProc (hwnd, umsg, wParam, lParam);
}

/***********************************************************************

FUNCTION: 
  InitInstance

PURPOSE: 
  Create and display the main window.

***********************************************************************/
BOOL InitInstance (HINSTANCE hInstance, int iCmdShow)
{

  g_hInst = hInstance;
  
  g_hwndMain = CreateWindow (
                  g_szClassName,  // Registered class name         
                  g_szTitle,      // Application window name
                  WS_OVERLAPPED,  // Window style
                  0,              // Horizontal position of the window
                  0,              // Vertical position of the window
                  CW_USEDEFAULT,  // Window width
                  CW_USEDEFAULT,  // Window height
                  NULL,           // Handle to the parent window
                  NULL,           // Handle to the menu the identifier
                  hInstance,      // Handle to the application instance
                  NULL);          // Pointer to the window-creation data

  // If it failed to create the window, return FALSE.
  if (!g_hwndMain)
    return FALSE;

  ShowWindow (g_hwndMain, iCmdShow);
  UpdateWindow (g_hwndMain);
  return TRUE;
}

/***********************************************************************

FUNCTION: 
  InitApplication

PURPOSE:
  Declare the window class structure, assign values to the window class
  structure members, and register the window class.

***********************************************************************/
BOOL InitApplication (HINSTANCE hInstance)
{
  WNDCLASS wndclass;

  wndclass.style = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc = (WNDPROC)WndProc;
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hIcon = NULL;
  wndclass.hInstance = hInstance;
  wndclass.hCursor = NULL;
  wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = g_szClassName;
  
  return RegisterClass (&wndclass);
}

/***********************************************************************

FUNCTION: 
  WinMain

PURPOSE: 
  The WinMain function of the application. It is called by the system as
  the initial entry point for this Windows CE-based application.

***********************************************************************/
int WINAPI WinMain (
               HINSTANCE hInstance,     // Handle to the current instance
               HINSTANCE hPrevInstance, // Handle to the previous instance
               LPWSTR lpCmdLine,        // Pointer to the command line
               int iCmdShow)            // Shows the state of the window
{
  MSG msg;                             // Message structure
  HACCEL hAccel;                       // Handle of the accelerator 
                                      // table
    
  if (!hPrevInstance)
  {
    if (!InitApplication (hInstance))
      return FALSE; 
  }

  if (!InitInstance (hInstance, iCmdShow))
    return FALSE;
  
  // Insert code here to load the accelerator table.
  // hAccel = LoadAccelerators (...);
  
  while (GetMessage (&msg, NULL, 0, 0))
  {
    if (!TranslateAccelerator (
                    g_hwndMain,     // Handle to the destination window
                    hAccel,         // Handle to the accelerator table
                    &msg))          // Address of the message data
    {
      TranslateMessage (&msg);
      DispatchMessage (&msg);
    }
  }
  
  return msg.wParam;
}