//======================================================================
// HelloSP - A simple application for the Smartphone
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h>                 // For all that Windows stuff
#include <commctrl.h>                // Command bar includes
#include <aygshell.h>                // Pocket PC includes
#include "hellosp.h"                 // Program-specific stuff
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT("HelloSP");
HINSTANCE hInst;                      // Program instance handle
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
  WM_CREATE, DoCreateMain,
  WM_PAINT, DoPaintMain,
  WM_COMMAND, DoCommandMain,
  WM_DESTROY, DoDestroyMain,
};
// Command Message dispatch for MainWindowProc
const struct decodeCMD MainCommandItems[] = {
  IDM_EXIT, DoMainCommandExit,
};
//======================================================================
// Program entry point
//
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPWSTR lpCmdLine, int nCmdShow) {
  MSG msg;
  int rc = 0;
  HWND hwndMain;
  // Initialize this instance.
  hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
  if (hwndMain == 0) return 0x10;
  // Application message loop
  while (GetMessage (&msg, NULL, 0, 0)) {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
  }
  // Instance cleanup
  return TermInstance (hInstance, msg.wParam);
}
//------------------------------------------------------------------
// InitInstance - Instance initialization
//
HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow) {
  WNDCLASS wc;
  HWND hWnd;
  // Save program instance handle in global variable.
  hInst = hInstance;
  // Allow only one instance of the application.
  hWnd = FindWindow (szAppName, NULL);
  if (hWnd) {
    SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));    
    return 0;
  }
  // Register application main window class.
  wc.style = CS_VREDRAW | CS_HREDRAW;       // Window style
  wc.lpfnWndProc = MainWndProc;             // Callback function
  wc.cbClsExtra = 0;                        // Extra class data
  wc.cbWndExtra = 0;                        // Extra window data
  wc.hInstance = hInstance;                 // Owner handle
  wc.hIcon = NULL,                          // Application icon
  wc.hCursor = LoadCursor (NULL, IDC_ARROW); // Default cursor
  wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  wc.lpszMenuName =  NULL;                  // Menu name
  wc.lpszClassName = szAppName;             // Window class name
  if (RegisterClass (&wc) == 0) return 0;
  // Create main window.
  hWnd = CreateWindow (szAppName,           // Window class
                       TEXT("Hello"),       // Window title
                       WS_VISIBLE,          // Style flags
                       CW_USEDEFAULT,       // x position
                       CW_USEDEFAULT,       // y position
                       CW_USEDEFAULT,       // Initial width
                       CW_USEDEFAULT,       // Initial height
                       NULL,                // Parent
                       NULL,                // Menu, must be null
                       hInstance,           // Application instance
                       NULL);               // Pointer to create
                                               // parameters
  if (!IsWindow (hWnd)) return 0;           // Fail if not created.
  // Standard show and update calls
  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);
  return hWnd;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermInstance (HINSTANCE hInstance, int nDefRC) {
  return nDefRC;
}
//======================================================================
// Message handling procedures for main window
//
//----------------------------------------------------------------------
// MainWndProc - Callback function for application window
//
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam, 
    LPARAM lParam) {
  INT i;
 
  //
  // Search message list to see if we need to handle this
  // message.  If in list, call procedure.
  //
  for (i = 0; i < dim(MainMessages); i++) {
    if (wMsg == MainMessages[i].Code)
      return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
  }
  return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
//----------------------------------------------------------------------
// DoCreateMain - Process WM_CREATE message for window.
//
LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam, 
    LPARAM lParam) {
  SHMENUBARINFO mbi;
  // Create a MenuBar.
  memset(&mbi, 0, sizeof(SHMENUBARINFO)); // Zero structure
  mbi.cbSize = sizeof(SHMENUBARINFO);     // Size field
  mbi.hwndParent = hWnd;                  // Parent window
  mbi.nToolBarId = ID_MENU;               // ID of toolbar resource
  mbi.hInstRes = hInst;                   // Inst handle of app
  // Create bar and check for errors.
  if (!SHCreateMenuBar(&mbi)) {
    MessageBox (hWnd, TEXT("Couldn\'t create menu bar"), 
        szAppName, MB_OK);
    DestroyWindow (hWnd);
  }
  // Size the window to fit above the MenuBar
  RECT rect, rectDesk;
  int cx, cy;
  GetWindowRect (mbi.hwndMB, &rect);
  GetWindowRect (GetDesktopWindow (), &rectDesk);
  cx = rectDesk.right-rectDesk.left;
  cy = (rectDesk.bottom - rectDesk.top) - (rect.bottom - rect.top);
  SetWindowPos (hWnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER);
  SHSetNavBarText (hWnd, TEXT("Hello"));
  return 0;
}
//----------------------------------------------------------------------
// DoCommandMain - Process WM_COMMAND message for window.
//
LRESULT DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam,
    LPARAM lParam) {
  WORD idItem, wNotifyCode;
  HWND hwndCtl;
  INT  i;
  // Parse the parameters.
  idItem = (WORD) LOWORD (wParam);
  wNotifyCode = (WORD) HIWORD (wParam);
  hwndCtl = (HWND) lParam;
  // Call routine to handle control message.
  for (i = 0; i < dim(MainCommandItems); i++) {
    if (idItem == MainCommandItems[i].Code)
      return (*MainCommandItems[i].Fxn)(hWnd, idItem, hwndCtl,
          wNotifyCode);
  }
  return 0;
}
//----------------------------------------------------------------------
// DoPaintMain - Process WM_PAINT message for window.
//
LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam, 
    LPARAM lParam) {
  PAINTSTRUCT ps;
  HPEN hPen, hOld;
  RECT rect;
  HDC hdc;
  hdc = BeginPaint (hWnd, &ps); 
  GetClientRect (hWnd, &rect);
  // Draw a red rectangle around the window.
  hPen = CreatePen (PS_SOLID, 1, RGB (255, 0, 0));
  hOld = (HPEN)SelectObject (hdc, hPen);
  Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom);
  SelectObject (hdc, hOld);
  DeleteObject (hPen);
  // Draw the standard hello text centered in the window.
  DrawText (hdc, TEXT ("Hello Smartphone!"), -1, &rect, 
      DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  EndPaint (hWnd, &ps); 
  return 0;
}
//----------------------------------------------------------------------
// DoDestroyMain - Process WM_DESTROY message for window.
//
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, 
    LPARAM lParam) {
  PostQuitMessage (0);
  return 0;
}
//======================================================================
// Command handler routines
//----------------------------------------------------------------------
// DoMainCommandExit - Process Program Exit command.
//
LPARAM DoMainCommandExit (HWND hWnd, WORD idItem, HWND hwndCtl,
    WORD wNotifyCode) {
  SendMessage (hWnd, WM_CLOSE, 0, 0);
  return 0;
}
       
       |