previous page
next page

The Structure of a Windows Application

A standard Windows application consists of several well-known elements:

  • The entry point, _tWinMain, which provides the HINSTANCE of the application, the command-line arguments and the flag indicating how to show the main window

  • A call to RegisterClass to register the main window class

  • A call to CreateWindow(Ex) to create the main window

  • A call to ShowWindow and UpdateWindow to show the main window

  • A message loop to dispatch messages

  • A procedure to handle the main window's messages

  • A set of message handlers for messages that the main window is interested in handling

  • A call to DefWindowProc to let Windows handle messages that the main window is not interested in

  • A call to PostQuitMessage after the main window has been destroyed

A bare-bones example follows:

#include "stdafx.h" // Includes windows.h and tchar.h
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// Entry point
int APIENTRY _tWinMain(HINSTANCE hinst,
                       HINSTANCE /*hinstPrev*/,
                       LPTSTR    pszCmdLine,
                       int       nCmdShow) {
  // Register the main window class
  LPCTSTR     pszMainWndClass = __T("WindowsApp");
  WNDCLASSEX  wc = { sizeof(WNDCLASSEX) };
  wc.style         = CS_HREDRAW | CS_VREDRAW;
  wc.hInstance     = hinst;
  wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
  wc.hCursor       = LoadCursor(0, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wc.lpszClassName = pszMainWndClass;
  wc.lpfnWndProc   = WndProc;
  if( !RegisterClassEx(&wc) ) return -1;

  // Create the main window
  HWND    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
                                pszMainWndClass,
                                __T("Windows Application"),
                                WS_OVERLAPPEDWINDOW,
                                CW_USEDEFAULT, 0,
                                CW_USEDEFAULT, 0,
                                0, 0, hinst, 0);
  if( !hwnd ) return -1;

  // Show the main window
  ShowWindow(hwnd, nCmdShow);
  UpdateWindow(hwnd);

  // Main message loop
  MSG msg;
  while( GetMessage(&msg, 0, 0, 0) ) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return msg.wParam;
}

// Windows procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT nMsg, WPARAM wparam,
  LPARAM lparam) {
  switch( nMsg ) {
  // Message handlers for messages we're interested in
  case WM_PAINT: {
    PAINTSTRUCT ps;
    HDC         hdc = BeginPaint(hwnd, &ps);
    RECT        rect; GetClientRect(hwnd, &rect);
    DrawText(hdc, __T("Hello, Windows"), -1, &rect,
             DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    EndPaint(hwnd, &ps);
  }
  break;

  // Post the quit message when main window is destroyed
  case WM_DESTROY:
    PostQuitMessage(0);
  break;

  // Let Windows handle messages we don't want
  default:
    return DefWindowProc(hwnd, nMsg, wparam, lparam);
  break;
  }

  return 0;
}

All Windows applications have similar requirements. These requirements can be expressed in procedural Win32 calls, as the example just showed. However, when procedural calls model an underlying object model, C++ programmers feel compelled to wrap those calls behind member functions. The Windowing part of the Win32 API (often called User32) is clearly implementing an underlying object model consisting of Window classes (represented by the WNDCLASSEX structure), Window objects (represented by the HWND), and member function invocation (represented by calls to the WndProc). For the C++ programmer adverse to the schism between a preferred object model and that of User32, ATL provides a small set of windowing classes, as shown in Figure 10.1.

Figure 10.1. UML diagram of ATL window classes


The classes in bold, CWindow, CWindowImpl, CWinTraits, CWinTraitsOR, CDialogImpl, CSimpleDialog and, CContainedWindowT, are the most important. The others, CWindowImplRoot, CWindowImplBaseT, and CDialogImplBaseT, are helper classes to separate parameterized code from invariant code. This separation helps to reduce template-related code bloat, but these classes are not a fundamental part of the ATL windowing classes. The former classes form the discussion for the bulk of the rest of this chapter.


previous page
next page
Converted from CHM to HTML with chm2web Pro 2.75 (unicode)