Sample Windows-Based Application

Every Windows CE-based application must have WinMain as its entry point function. WinMain performs a number of tasks, including registering the window class for the main window and creating the main window. WinMain registers the main window class by calling the RegisterClass function and it creates the main window by calling the CreateWindowEx function. WinMain does not need to do these things itself; it can call other functions to perform any or all of these tasks.

The system does not automatically display the main window after creating it. Rather, the application's WinMain function uses the ShowWindow function to display the window.

Even the simplest Windows-based application has a message loop and a window procedure. The message loop, typically part of an application's WinMain function, enables your application to receive messages and to dispatch them to the appropriate window procedure. The window procedure is a function that processes the messages that the system sends to your window. The system calls your window procedure as a result of the messages that your message loop receives and dispatches. You usually do not call your window procedure directly from your application. Each window class specifies an initial window procedure.

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

  1. WinMain stashes the application-instance handle in a global variable. Because this handle is used in various places throughout a program, it is common to put 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 that calls the RegisterClass function to register the application's main window class. More complicated applications may need to register more window classes and to determine whether other instances of the application are running.
  3. WinMain calls the application-defined InitInstance function that 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 that causes the next call to 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, which is the default window procedure provided by the system. You should pass all messages to DefWindowProc that you do not process yourself; otherwise, your window may not function correctly.

#include <windows.h>
#define ZeroVar(v) \ memset(&v, 0, sizeof(v))

HINSTANCE g_hInstance;

const TCHAR* const pszMainWndClassName = TEXT("MainWndClass");

//Here is the application's window procedure.
LRESULT CALLBACK MainWndProc(
  HWND hwnd,
  UINT message,
  WPARAM wParam,
  LPARAM lParam
  )
{
  switch ( message )
   {
   case WM_CLOSE:
      DestroyWindow(hwnd);
      PostQuitMessage(0);
      return 0;
   }
   return DefWindowProc(hwnd, message, wParam, lParam);
}

BOOL InitInstance(void)
{
   BOOL    bRet = FALSE;
   HWND    hwndMain;

   hwndMain = CreateWindow(
         pszMainWndClassName,
         TEXT("Main"),
         WS_OVERLAPPED|WS_SYSMENU,
         CW_USEDEFAULT, CW_USEDEFAULT,
         CW_USEDEFAULT, CW_USEDEFAULT,
         NULL,
         NULL,
         g_hInstance,
         NULL
         );

   ShowWindow(hwndMain, SW_SHOW);
   UpdateWindow(hwndMain);

   bRet = TRUE;

   return bRet;
}

BOOL InitApplication(void)
{
   BOOL bRet = FALSE;
   WNDCLASS    wc;

   ZeroVar(wc);

   //    Set up information about the class.
   wc.style                 = 0;
   wc.lpfnWndProc           = MainWndProc;
   wc.cbClsExtra            = 0;
   wc.cbWndExtra            = 0;
   wc.hInstance             = g_hInstance;
   wc.hIcon                 = 0;
   wc.hCursor               = 0;
   wc.hbrBackground         = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wc.lpszMenuName          = NULL;
   wc.lpszClassName         = pszMainWndClassName;

   bRet = RegisterClass(&wc);
   return bRet;
}
int WINAPI WinMain (
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPTSTR     lpCmdLine,
   int nCmdShow
   )
{
   MSG msg;
   g_hInstance = hInstance;

   if ( !InitApplication() )
      { 
      goto leave;
      }

   if ( !InitInstance() )
      {
      goto leave;
   }


   while ( GetMessage(&msg, NULL, 0, 0) )
      {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      }

leave:
   return 0;
}