Programming Microsoft Windows Ce Net 3Rd [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming Microsoft Windows Ce Net 3Rd [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید






The DlgDemo Example Program

The DlgDemo program demonstrates basic dialog boxes, modeless dialog boxes, property sheets, and common dialogs. When you start DlgDemo, it displays a window that shows the WM_COMMAND and WM_NOTIFY messages sent by the various controls in the dialogs, similar to the right side of the CtlView window. The different dialogs can be opened using the various menu items. Figure 6-4 shows the Dialog Demo window with the property sheet dialog displayed.


Figure 6-4: The Dialog Demo window

The basic dialog box is a simple "about box" launched by selecting the Help About menu. The property sheet is launched by selecting the File Property Sheet menu. The property sheet dialog contains five pages corresponding to the different windows in the CtlView example. The common dialog boxes are launched from the File Open, File Save, File Color, and File Print menu items. The DlgDemo source code is shown in Listing 6-1.

Listing 6-1: The DlgDemo program







DlgDemo.rc
//======================================================================
// Resource file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include "windows.h"
#include "DlgDemo.h" // Program-specific stuff
#include "commctrl.h"
//----------------------------------------------------------------------
// Icons and bitmaps
//
ID_ICON ICON "DlgDemo.ico" // Program icon
IDI_BTNICON ICON "btnicon.ico" // Bitmap used in owner-draw button
statbmp BITMAP "statbmp.bmp" // Bitmap used in static window
//----------------------------------------------------------------------
// Menu, the RC data resource is needed by the menu bar
//
ID_MENU RCDATA MOVEABLE PURE
BEGIN
ID_MENU, 2,
-2, 100, TBSTATE_ENABLED, TBSTYLE_DROPDOWN|TBSTYLE_AUTOSIZE,5,0,0,
-2, 101, TBSTATE_ENABLED, TBSTYLE_DROPDOWN|TBSTYLE_AUTOSIZE,3,0,1
END
ID_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "Open...", IDM_OPEN
MENUITEM "Save...", IDM_SAVE
MENUITEM SEPARATOR
MENUITEM "Color...", IDM_COLOR
MENUITEM "Print...", IDM_PRINT
MENUITEM SEPARATOR
MENUITEM "Property Sheet", IDM_SHOWPROPSHEET
MENUITEM "Modeless Dialog", IDM_SHOWMODELESS
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About...", IDM_ABOUT
END
END
//----------------------------------------------------------------------
// Property page templates
//
ID_BTNPAGE DIALOG discardable 0, 0, 125, 90
CAPTION "Buttons"
BEGIN
PUSHBUTTON "Button 1", IDC_PUSHBTN, 5, 5, 80, 12,
WS_TABSTOP | BS_NOTIFY
CHECKBOX "Check Box", IDC_CHKBOX, 5, 20, 80, 12,
WS_TABSTOP | BS_NOTIFY
AUTOCHECKBOX "Auto check box" IDC_ACHKBOX, 5, 35, 80, 12,
WS_TABSTOP
AUTO3STATE "Auto 3-state box", IDC_A3STBOX, 5, 50, 80, 12,
WS_TABSTOP
AUTORADIOBUTTON "Auto radio button 1",
IDC_RADIO1, 5, 65, 80, 12,
WS_TABSTOP | WS_GROUP
AUTORADIOBUTTON "Auto radio button 2",
IDC_RADIO2, 5, 75, 80, 12
PUSHBUTTON ", IDC_OWNRDRAW, 95, 5, 30, 30,
BS_OWNERDRAW
END
ID_EDITPAGE DIALOG discardable 0, 0, 80, 80
CAPTION "Edit"
BEGIN
EDITTEXT IDC_SINGLELINE, 5, 5, 70, 12,
WS_TABSTOP
EDITTEXT IDC_MULTILINE, 5, 20, 70, 40,
WS_TABSTOP | ES_MULTILINE
EDITTEXT IDC_PASSBOX, 5, 65, 70, 12,
WS_TABSTOP | ES_PASSWORD
END
ID_LISTPAGE DIALOG discardable 0, 0, 125, 80
CAPTION "List"
BEGIN
COMBOBOX IDC_COMBOBOX, 5, 5, 70, 60,
WS_TABSTOP | CBS_DROPDOWN
LISTBOX IDC_SNGLELIST, 5, 20, 50, 60,
WS_TABSTOP
LISTBOX IDC_MULTILIST, 60, 20, 50, 60,
WS_TABSTOP | LBS_EXTENDEDSEL
END
ID_STATPAGE DIALOG discardable 0, 0, 130, 80
CAPTION "Static"
BEGIN
LTEXT "Left text", IDC_LEFTTEXT, 5, 5, 70, 20
RTEXT "Right text", IDC_RIGHTTEXT, 5, 30, 70, 20
CTEXT "Center text", IDC_CENTERTEXT, 5, 55, 70, 20,
WS_BORDER
ICON IDI_BTNICON IDC_ICONCTL, 95, 5, 32, 32
CONTROL "statbmp", IDC_BITMAPCTL, "static", SS_BITMAP,
95, 40, 32, 32
END
ID_SCROLLPAGE DIALOG discardable 0, 0, 60, 80
CAPTION "Scroll"
BEGIN
SCROLLBAR IDC_LRSCROLL, 5, 5, 70, 12,
WS_TABSTOP
SCROLLBAR IDC_UDSCROLL, 80, 5, 12, 70,
WS_TABSTOP | SBS_VERT
END
//----------------------------------------------------------------------
// Clear list; modeless dialog box template.
//
Clearbox DIALOG discardable 60, 10, 70, 30
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME
CAPTION "Clear"
BEGIN
DEFPUSHBUTTON "Clear Listbox"
IDD_CLEAR, 5, 5, 60, 20
END
//----------------------------------------------------------------------
// About box dialog box template
//
aboutbox DIALOG discardable 10, 10, 132, 40
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER |
DS_MODALFRAME
CAPTION "About"
BEGIN
ICON ID_ICON -1, 5, 5, 0, 0
LTEXT "DlgDemo - Written for the book Programming Windows CE Copyright 2001 Douglas Boling"
-1, 28, 5, 100, 30
END


DlgDemo.h
//======================================================================
// Header file
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
// Returns number of elements
#define dim(x) (sizeof(x) / sizeof(x[0]))
//----------------------------------------------------------------------
// Generic defines and data types
//
struct decodeUINT { // Structure associates
UINT Code; // messages
// with a function.
LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};
struct decodeCMD { // Structure associates
UINT Code; // menu IDs with a
LRESULT (*Fxn)(HWND, WORD, HWND, WORD); // function.
};
//----------------------------------------------------------------------
// Generic defines used by application
#define IDC_CMDBAR 1 // Command bar ID
#define IDC_RPTLIST 2 // ID for report list box
#define ID_ICON 10 // Icon resource ID
#define ID_MENU 11 // Main menu resource ID
#define IDM_OPEN 100 // Menu item IDs
#define IDM_SAVE 101
#define IDM_COLOR 102
#define IDM_PRINT 103
#define IDM_SHOWPROPSHEET 104
#define IDM_SHOWMODELESS 105
#define IDM_EXIT 106
#define IDM_ABOUT 110
#define IDI_BTNICON 120
// Identifiers for the property page resources
#define ID_BTNPAGE 50
#define ID_EDITPAGE 51
#define ID_LISTPAGE 52
#define ID_STATPAGE 53
#define ID_SCROLLPAGE 54
#define IDC_PUSHBTN 200 // Button defines
#define IDC_CHKBOX 201
#define IDC_ACHKBOX 202
#define IDC_A3STBOX 203
#define IDC_RADIO1 204
#define IDC_RADIO2 205
#define IDC_OWNRDRAW 206
#define IDC_SINGLELINE 210 // Edit defines
#define IDC_MULTILINE 211
#define IDC_PASSBOX 212
#define IDC_COMBOBOX 220 // List box defines
#define IDC_SNGLELIST 221
#define IDC_MULTILIST 222
#define IDC_LEFTTEXT 230 // Static defines
#define IDC_RIGHTTEXT 231
#define IDC_CENTERTEXT 232
#define IDC_ICONCTL 233
#define IDC_BITMAPCTL 234
#define IDC_LRSCROLL 240 // Scroll bar defines
#define IDC_UDSCROLL 241
// Control IDs for modeless dialog box
#define IDD_CLEAR 500
// User-defined message to add a line to the window
#define MYMSG_ADDLINE (WM_USER + 10)
//----------------------------------------------------------------------
// Program-specific structures
//
typedef struct {
TCHAR *pszLabel;
DWORD wNotification;
} NOTELABELS, *PNOTELABELS;
//----------------------------------------------------------------------
// Function prototypes
//
HWND InitInstance (HINSTANCE, LPWSTR, int);
int TermInstance (HINSTANCE, int);
// Window procedures
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);
// Message handlers
LRESULT DoCreateMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoCommandMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoAddLineMain (HWND, UINT, WPARAM, LPARAM);
LRESULT DoDestroyMain (HWND, UINT, WPARAM, LPARAM);
// Command functions
LPARAM DoMainCommandOpen (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandSave (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandColor (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandPrint (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandShowProp (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandModeless (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandExit (HWND, WORD, HWND, WORD);
LPARAM DoMainCommandAbout (HWND, WORD, HWND, WORD);
// Dialog box procedures
BOOL CALLBACK BtnDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK EditDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK ListDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK StaticDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK ScrollDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK ModelessDlgProc (HWND, UINT, WPARAM, LPARAM);


DlgDemo.cpp
//======================================================================
// DlgDemo - Dialog box demonstration
//
// 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 <commdlg.h> // Common dialog box includes
#include <prsht.h> // Property sheet includes
#include "DlgDemo.h" // Program-specific stuff
#if defined(WIN32_PLATFORM_PSPC)
#include <aygshell.h> // Add Pocket PC includes
#pragma comment( lib, "aygshell" ) // Link Pocket PC lib for menu bar
#endif
//----------------------------------------------------------------------
// Global data
//
const TCHAR szAppName[] = TEXT ("DlgDemo");
HINSTANCE hInst; // Program instance handle
HWND g_hwndMlDlg = 0; // Handle to modeless dialog box
HINSTANCE hLib = 0; // Handle to CommDlg lib
typedef BOOL (APIENTRY* LFCHOOSECOLORPROC) (LPCHOOSECOLOR );
#ifndef WIN32_PLATFORM_PSPC
typedef BOOL (APIENTRY* LFPAGESETUPDLG)( LPPAGESETUPDLGW );
LFPAGESETUPDLG lpfnPrintDlg = 0; // Ptr to print common dialog fn
#else
typedef BOOL (APIENTRY* LFPRINTDLG) (LPPRINTDLG lppsd);
LFPRINTDLG lpfnPrintDlg = 0; // Ptr to print common dialog fn
#endif
LFCHOOSECOLORPROC lpfnChooseColor = 0; // Ptr to color common dialog fn
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
WM_CREATE, DoCreateMain,
WM_COMMAND, DoCommandMain,
MYMSG_ADDLINE, DoAddLineMain,
WM_DESTROY, DoDestroyMain,
};
// Command message dispatch for MainWindowProc
const struct decodeCMD MainCommandItems[] = {
IDM_OPEN, DoMainCommandOpen,
IDM_SAVE, DoMainCommandSave,
IDM_SHOWPROPSHEET, DoMainCommandShowProp,
IDM_SHOWMODELESS, DoMainCommandModeless,
IDM_COLOR, DoMainCommandColor,
IDM_PRINT, DoMainCommandPrint,
IDM_EXIT, DoMainCommandExit,
IDM_ABOUT, DoMainCommandAbout,
};
//
// Labels for WM_NOTIFY notifications
//
NOTELABELS nlPropPage[] = {{TEXT ("PSN_SETACTIVE "), (PSN_FIRST-0)},
{TEXT ("PSN_KILLACTIVE "), (PSN_FIRST-1)},
{TEXT ("PSN_APPLY "), (PSN_FIRST-2)},
{TEXT ("PSN_RESET "), (PSN_FIRST-3)},
{TEXT ("PSN_HASHELP "), (PSN_FIRST-4)},
{TEXT ("PSN_HELP "), (PSN_FIRST-5)},
{TEXT ("PSN_WIZBACK "), (PSN_FIRST-6)},
{TEXT ("PSN_WIZNEXT "), (PSN_FIRST-7)},
{TEXT ("PSN_WIZFINISH "), (PSN_FIRST-8)},
{TEXT ("PSN_QUERYCANCEL"), (PSN_FIRST-9)},
};
int nPropPageSize = dim(nlPropPage);
// Labels for the property pages
TCHAR *szPages[] = {TEXT ("Btn "),
TEXT ("Edit"),
TEXT ("List"),
TEXT ("Stat"),
TEXT ("Scrl"),
};
//======================================================================
// Program entry point
//
HWND hwndMain;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow) {
MSG msg;
int rc = 0;
// Initialize application.
hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
if (hwndMain == 0) return 0x10;
// Application message loop
while (GetMessage (&msg, NULL, 0, 0)) {
// If modeless dialog box is created, let it have
// the first crack at the message.
if ((g_hwndMlDlg == 0) ||
(!IsDialogMessage (g_hwndMlDlg, &msg))) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
// Instance cleanup
return TermInstance (hInstance, msg.wParam);
}
//----------------------------------------------------------------------
// InitInstance - Instance initialization
//
HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine,
int nCmdShow) {
HWND hWnd;
WNDCLASS wc;
// Save program instance handle in global variable.
hInst = hInstance;
#if defined(WIN32_PLATFORM_PSPC)
// If Pocket PC, allow only one instance of the application.
hWnd = FindWindow (szAppName, NULL);
if (hWnd) {
SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
return 0;
}
#endif
// Register application main window class.
wc.style = 0; // 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;
// Get the Color and print dialog function pointers.
hLib = LoadLibrary (TEXT ("COMMDLG.DLL"));
if (hLib) {
lpfnChooseColor = (LFCHOOSECOLORPROC)GetProcAddress (hLib,
TEXT ("ChooseColor"));#if defined(WIN32_PLATFORM_PSPC)
lpfnPrintDlg = (LFPRINTDLG) GetProcAddress (hLib, TEXT ("PrintDlg"));
#else
lpfnPrintDlg = (LFPAGESETUPDLG)GetProcAddress (hLib,
TEXT ("PageSetupDlgW"));
#endif
}
// Create main window.
hWnd = CreateWindow (szAppName, TEXT ("Dialog Demo"), WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
// Return fail code if window not created.
if (!IsWindow (hWnd)) return 0;
// Standard show and update calls
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return hWnd;
}
//----------------------------------------------------------------------
// TermInstance - Program cleanup
//
int TermInstance (HINSTANCE hInstance, int nDefRC) {
if (hLib)
FreeLibrary (hLib);
return nDefRC;
}
//======================================================================
// Message-handling procedures for MainWindow
//
//----------------------------------------------------------------------
// 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) {
HWND hwndChild;
INT i, nHeight = 0;
LPCREATESTRUCT lpcs;
HMENU hMenu;
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
SHMENUBARINFO mbi; // For Pocket PC, create
memset(&mbi, 0, sizeof(SHMENUBARINFO)); // menu bar so that we
mbi.cbSize = sizeof(SHMENUBARINFO); // have a sip button
mbi.hwndParent = hWnd;
mbi.nToolBarId = ID_MENU;
mbi.hInstRes = hInst;
SHCreateMenuBar(&mbi);
hMenu = (HMENU)SendMessage(mbi.hwndMB, SHCMBM_GETSUBMENU, 0, 100);
#else
// Create a command bar. Add a menu and an exit button.
HWND hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);
CommandBar_InsertMenubar (hwndCB, hInst, ID_MENU, 0);
CommandBar_AddAdornments (hwndCB, 0, 0);
nHeight = CommandBar_Height (hwndCB);
hMenu = CommandBar_GetMenu (hwndCB, 0);
#endif
// Convert lParam to pointer to create structure.
lpcs = (LPCREATESTRUCT) lParam;
// See color and print functions not found; disable menus.
if (!lpfnChooseColor)
EnableMenuItem (hMenu, IDM_COLOR, MF_BYCOMMAND | MF_GRAYED);
if (!lpfnPrintDlg)
EnableMenuItem (hMenu, IDM_PRINT, MF_BYCOMMAND | MF_GRAYED);
//
// Create report window. Size it so that it fits under
// the command bar and fills the remaining client area.
//
hwndChild = CreateWindowEx (0, TEXT ("listbox"),
TEXT ("), WS_VISIBLE | WS_CHILD | WS_VSCROLL |
LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT, 0,
nHeight, lpcs->cx, lpcs->cy - nHeight,
hWnd, (HMENU)IDC_RPTLIST, lpcs->hInstance, NULL);
// Destroy frame if window not created.
if (!IsWindow (hwndChild)) {
DestroyWindow (hWnd);
return 0;
}
// Initialize tab stops for display list box.
i = 8;
SendMessage (hwndChild, LB_SETTABSTOPS, 1, (LPARAM)&i);
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;
}
//----------------------------------------------------------------------
// DoAddLineMain - Process MYMSG_ADDLINE message for window.
//
LRESULT DoAddLineMain (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
INT i;
// If nothing in wParam, just fill in spaces.
if (wParam == -1) {
// Print message only.
lstrcpy (szOut, (LPTSTR)lParam);
} else {
// If no ID val, ignore that field.
if (LOWORD (wParam) == 0xffff)
// Print prop page and message.
wsprintf (szOut, TEXT ("%s \t %s"),
szPages[HIWORD (wParam) - ID_BTNPAGE],
(LPTSTR)lParam);
else
// Print property page, control ID, and message.
wsprintf (szOut, TEXT ("%s \tid:%3d \t%s"),
szPages[HIWORD (wParam) - ID_BTNPAGE],
LOWORD (wParam), (LPTSTR)lParam);
}
i = SendDlgItemMessage (hWnd, IDC_RPTLIST, LB_ADDSTRING, 0,
(LPARAM)(LPCTSTR)szOut);
if (i != LB_ERR)
SendDlgItemMessage (hWnd, IDC_RPTLIST, LB_SETTOPINDEX, i,
(LPARAM)(LPCTSTR)szOut);
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
//----------------------------------------------------------------------
// DoMainCommandOpen - Process File Open command
//
LPARAM DoMainCommandOpen (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
OPENFILENAME of;
TCHAR szFileName [MAX_PATH] = {0};
const LPTSTR pszOpenFilter = TEXT ("All Documents (*.*)\0*.*\0\0");
TCHAR szOut[128];
INT rc;
szFileName[0] = '\0'; // Initialize filename.
memset (&of, 0, sizeof (of)); // Initialize File Open structure.
of.lStructSize = sizeof (of);
of.hwndOwner = hWnd;
of.lpstrFile = szFileName;
of.nMaxFile = dim(szFileName);
of.lpstrFilter = pszOpenFilter;
of.Flags = 0;
rc = GetOpenFileName (&of);
wsprintf (szOut,
TEXT ("GetOpenFileName returned: %x, filename: %s"),
rc, szFileName);
SendMessage (hWnd, MYMSG_ADDLINE, -1, (LPARAM)szOut);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandSave - Process File Save command.
//
LPARAM DoMainCommandSave (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
OPENFILENAME of;
TCHAR szFileName [MAX_PATH] = {0};
const LPTSTR pszOpenFilter = TEXT ("All Documents (*.*)\0*.*\0\0");
TCHAR szOut[128];
INT rc;
szFileName[0] = '\0'; // Initialize filename.
memset (&of, 0, sizeof (of)); // Initialize File Open structure.
of.lStructSize = sizeof (of);
of.hwndOwner = hWnd;
of.lpstrFile = szFileName;
of.nMaxFile = dim(szFileName);
of.lpstrFilter = pszOpenFilter;
of.Flags = 0;
rc = GetSaveFileName (&of);
wsprintf (szOut,
TEXT ("GetSaveFileName returned: %x, filename: %s"),
rc, szFileName);
SendMessage (hWnd, MYMSG_ADDLINE, -1, (LPARAM)szOut);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandColor - Process File Color command.
//
LPARAM DoMainCommandColor (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
CHOOSECOLOR cc;
static COLORREF cr[16];
TCHAR szOut[128];
INT rc;
// Initialize color structure.
memset (&cc, 0, sizeof (cc));
memset (&cr, 0, sizeof (cr));
cc.lStructSize = sizeof (cc);
cc.hwndOwner = hWnd;
cc.hInstance = hInst;
cc.rgbResult = RGB (0, 0, 0);
cc.lpCustColors = cr;
cc.Flags = CC_ANYCOLOR;
rc = (lpfnChooseColor) (&cc);
wsprintf (szOut, TEXT ("Choose Color returned: %x, color: %x"),
rc, cc.rgbResult);
SendMessage (hWnd, MYMSG_ADDLINE, -1, (LPARAM)szOut);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandPrint - Process File Print command.
//
LPARAM DoMainCommandPrint (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
TCHAR szOut[128];
INT rc;
#ifndef WIN32_PLATFORM_PSPC
PAGESETUPDLG psd;
// Initialize print structure.
memset (&psd, 0, sizeof (psd));
psd.lStructSize = sizeof (psd);
psd.hwndOwner = hWnd;
rc = (lpfnPrintDlg) (&psd);
#else
PRINTDLG pd;
// Initialize print structure.
memset (&pd, 0, sizeof (pd));
pd.cbStruct = sizeof (pd);
pd.hwndOwner = hWnd;
pd.dwFlags = PD_SELECTALLPAGES;
rc = (lpfnPrintDlg) (&pd);
#endif // ifndef WIN32_PLATFORM_PSPC
wsprintf (szOut, TEXT ("PrintDlg returned: %x, : %x"),
rc, GetLastError());
SendMessage (hWnd, MYMSG_ADDLINE, -1, (LPARAM)szOut);
return 0;
}
//----------------------------------------------------------------------
// PropSheetProc - Function called when Property sheet created
//
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) {
if (uMsg == PSCB_INITIALIZED) {
// Get tab control.
HWND hwndTabs = GetDlgItem (hwndDlg, 0x3020);
DWORD dwStyle = GetWindowLong (hwndTabs, GWL_STYLE);
SetWindowLong (hwndTabs, GWL_STYLE, dwStyle | TCS_BOTTOM);
} else if (uMsg == PSCB_GETVERSION)
return COMCTL32_VERSION;
// Add a hyperlink line below the tabs.
else if (uMsg == PSCB_GETLINKTEXT) {
lstrcpy ((LPTSTR)lParam, TEXT ("Launch the calculator by ")
TEXT("tapping <file:\\windows\\calc.exe{here}>."));
return 0;
}
return 1;
}
#endif //defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
//----------------------------------------------------------------------
// DoMainCommandShowProp - Process show property sheet command.
//
LPARAM DoMainCommandShowProp(HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
PROPSHEETPAGE psp[5];
PROPSHEETHEADER psh;
INT i;
// Zero all the property page structures.
memset (&psp, 0, sizeof (psp));
// Fill in default values in property page structures.
for (i = 0; i < dim(psp); i++) {
psp[i].dwSize = sizeof (PROPSHEETPAGE);
psp[i].dwFlags = PSP_DEFAULT;
psp[i].hInstance = hInst;
psp[i].lParam = (LPARAM)hWnd;
}
// Set the dialog box templates for each page.
psp[0].pszTemplate = MAKEINTRESOURCE (ID_BTNPAGE);
psp[1].pszTemplate = MAKEINTRESOURCE (ID_EDITPAGE);
psp[2].pszTemplate = MAKEINTRESOURCE (ID_LISTPAGE);
psp[3].pszTemplate = MAKEINTRESOURCE (ID_STATPAGE);
psp[4].pszTemplate = MAKEINTRESOURCE (ID_SCROLLPAGE);
// Set the dialog box procedures for each page.
psp[0].pfnDlgProc = BtnDlgProc;
psp[1].pfnDlgProc = EditDlgProc;
psp[2].pfnDlgProc = ListDlgProc;
psp[3].pfnDlgProc = StaticDlgProc;
psp[4].pfnDlgProc = ScrollDlgProc;
// Initialize property sheet structure.
psh.dwSize = sizeof (PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE;
psh.hwndParent = hWnd;
psh.hInstance = hInst;
psh.pszCaption = TEXT ("Property Sheet Demo");
psh.nPages = dim(psp);
psh.nStartPage = 0;
psh.ppsp = psp;
// On Pocket PC, make property sheets full screen.
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
psh.pfnCallback = PropSheetProc;
psh.dwFlags |= PSH_USECALLBACK | PSH_MAXIMIZE;
#else
psh.pfnCallback = 0;
#endif //defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
// Create and display property sheet.
PropertySheet (&psh);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandModelessDlg - Process the File Modeless menu command.
//
LPARAM DoMainCommandModeless(HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
// Create dialog box only if not already created.
if (g_hwndMlDlg == 0)
// Use CreateDialog to create modeless dialog box.
g_hwndMlDlg = CreateDialog (hInst, TEXT ("Clearbox"), hWnd,
ModelessDlgProc);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandExit - Process Program Exit command.
//
LPARAM DoMainCommandExit (HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
SendMessage (hWnd, WM_CLOSE, 0, 0);
return 0;
}
//----------------------------------------------------------------------
// DoMainCommandAbout - Process the Help About menu command.
//
LPARAM DoMainCommandAbout(HWND hWnd, WORD idItem, HWND hwndCtl,
WORD wNotifyCode) {
// Use DialogBox to create modal dialog box.
DialogBox (hInst, TEXT ("aboutbox"), hWnd, AboutDlgProc);
return 0;
}
//======================================================================
// Modeless ClearList dialog box procedure
//
BOOL CALLBACK ModelessDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
switch (wMsg) {
case WM_COMMAND:
switch (LOWORD (wParam)) {
case IDD_CLEAR:
// Send message to list box to clear it.
SendDlgItemMessage (GetWindow (hWnd, GW_OWNER),
IDC_RPTLIST,
LB_RESETCONTENT, 0, 0);
return TRUE;
case IDOK:
case IDCANCEL:
// Modeless dialog boxes can't use EndDialog.
DestroyWindow (hWnd);
g_hwndMlDlg = 0; // 0 means dlg destroyed.
return TRUE;
}
break;
}
return FALSE;
}
//======================================================================
// About dialog box procedure
//
BOOL CALLBACK AboutDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
switch (wMsg) {
case WM_COMMAND:
switch (LOWORD (wParam)) {
case IDOK:
case IDCANCEL:
EndDialog (hWnd, 0);
return TRUE;
}
break;
}
return FALSE;
}


BtnDlg.cpp
//======================================================================
// BtnDlg - Button dialog box window code
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <prsht.h> // Property sheet includes
#include "DlgDemo.h" // Program-specific stuff
extern HINSTANCE hInst;
LRESULT DrawButton (HWND hWnd, LPDRAWITEMSTRUCT pdi);
//----------------------------------------------------------------------
// Global data
//
// Identification strings for various WM_COMMAND notifications
NOTELABELS nlBtn[] = {{TEXT ("BN_CLICKED "), 0},
{TEXT ("BN_PAINT "), 1},
{TEXT ("BN_HILITE "), 2},
{TEXT ("BN_UNHILITE"), 3},
{TEXT ("BN_DISABLE "), 4},
{TEXT ("BN_DOUBLECLICKED"), 5},
{TEXT ("BN_SETFOCUS "), 6},
{TEXT ("BN_KILLFOCUS"), 7}
};
extern NOTELABELS nlPropPage[];
extern int nPropPageSize;
// Handle for icon used in owner-draw icon
HICON hIcon = 0;
//======================================================================
// BtnDlgProc - Button page dialog box procedure
//
BOOL CALLBACK BtnDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
HWND hwndMain;
INT i;
switch (wMsg) {
case WM_INITDIALOG:
// The generic parameter contains the
// top-level window handle.
hwndMain = (HWND)((LPPROPSHEETPAGE)lParam)->lParam;
// Save the window handle in the window structure.
SetWindowLong (hWnd, DWL_USER, (LONG)hwndMain);
// Load icon for owner-draw window.
hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_BTNICON));
// We need to set the initial state of the radio buttons.
CheckRadioButton (hWnd, IDC_RADIO1, IDC_RADIO2, IDC_RADIO1);
return TRUE;
//
// Reflect WM_COMMAND messages to main window.
//
case WM_COMMAND:
// Since the check box is not an auto check box, the button
// has to be set manually.
if ((LOWORD (wParam) == IDC_CHKBOX) &&
(HIWORD (wParam) == BN_CLICKED)) {
// Get the current state, complement, and set.
i = SendDlgItemMessage (hWnd, IDC_CHKBOX, BM_GETCHECK,
0, 0);
if (i)
SendDlgItemMessage (hWnd, IDC_CHKBOX, BM_SETCHECK,
0, 0);
else
SendDlgItemMessage (hWnd, IDC_CHKBOX, BM_SETCHECK,
1, 0);
}
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up button notification.
lstrcpy (szOut, TEXT ("WM_COMMAND: "));
for (i = 0; i < dim(nlBtn); i++) {
if (HIWORD (wParam) == nlBtn[i].wNotification) {
lstrcat (szOut, nlBtn[i].pszLabel);
break;
}
}
if (i == dim(nlBtn))
wsprintf (szOut, TEXT ("WM_COMMAND notification: %x"),
HIWORD (wParam));
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (LOWORD (wParam),ID_BTNPAGE),
(LPARAM)szOut);
return TRUE;
//
// Reflect notify message.
//
case WM_NOTIFY:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up notify message.
for (i = 0; i < nPropPageSize; i++) {
if (((NMHDR *)lParam)->code ==
nlPropPage[i].wNotification) {
lstrcpy (szOut, nlPropPage[i].pszLabel);
break;
}
}
if (i == nPropPageSize)
wsprintf (szOut, TEXT ("Notify code:%d"),
((NMHDR *)lParam)->code);
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (-1,ID_BTNPAGE), (LPARAM)szOut);
return FALSE; // Return false to force default processing.
case WM_DRAWITEM:
DrawButton (hWnd, (LPDRAWITEMSTRUCT)lParam);
return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------
// DrawButton - Draws an owner-draw button.
//
LRESULT DrawButton (HWND hWnd, LPDRAWITEMSTRUCT pdi) {
HPEN hPenShadow, hPenLight, hPenDkShadow, hOldPen;
POINT ptOut[3], ptIn[3];
HBRUSH hBr, hOldBr;
TCHAR szOut[128];
HWND hwndMain;
LOGPEN lpen;
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Reflect the messages to the report window.
wsprintf (szOut, TEXT ("WM_DRAWITEM Act:%x State:%x"),
pdi->itemAction, pdi->itemState);
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (pdi->CtlID, ID_BTNPAGE),
(LPARAM)szOut);
// Create pens for drawing.
lpen.lopnStyle = PS_SOLID;
lpen.lopnWidth.x = 3;
lpen.lopnWidth.y = 3;
lpen.lopnColor = GetSysColor (COLOR_3DSHADOW);
hPenShadow = CreatePenIndirect (&lpen);
lpen.lopnWidth.x = 1;
lpen.lopnWidth.y = 1;
lpen.lopnColor = GetSysColor (COLOR_3DLIGHT);
hPenLight = CreatePenIndirect (&lpen);
lpen.lopnColor = GetSysColor (COLOR_3DDKSHADOW);
hPenDkShadow = CreatePenIndirect (&lpen);
// Create a brush for the face of the button.
hBr = CreateSolidBrush (GetSysColor (COLOR_3DFACE));
// Draw a rectangle with a thick outside border to start the
// frame drawing.
hOldPen = (HPEN)SelectObject (pdi->hDC, hPenShadow);
hOldBr = (HBRUSH)SelectObject (pdi->hDC, hBr);
Rectangle (pdi->hDC, pdi->rcItem.left, pdi->rcItem.top,
pdi->rcItem.right, pdi->rcItem.bottom);
// Draw the upper left inside line.
ptIn[0].x = pdi->rcItem.left + 1;
ptIn[0].y = pdi->rcItem.bottom - 3;
ptIn[1].x = pdi->rcItem.left + 1;
ptIn[1].y = pdi->rcItem.top + 1;
ptIn[2].x = pdi->rcItem.right - 3;
ptIn[2].y = pdi->rcItem.top + 1;
// Select a pen to draw shadow or light side of button.
if (pdi->itemState & ODS_SELECTED) {
SelectObject (pdi->hDC, hPenDkShadow);
} else {
SelectObject (pdi->hDC, hPenLight);
}
Polyline (pdi->hDC, ptIn, 3);
// If selected, also draw a bright line inside the lower
// right corner.
if (pdi->itemState & ODS_SELECTED) {
SelectObject (pdi->hDC, hPenLight);
ptIn[1].x = pdi->rcItem.right - 3;
ptIn[1].y = pdi->rcItem.bottom - 3;
Polyline (pdi->hDC, ptIn, 3);
}
// Now draw the black outside line on either the upper left or the
// lower right corner.
ptOut[0].x = pdi->rcItem.left;
ptOut[0].y = pdi->rcItem.bottom - 1;
ptOut[2].x = pdi->rcItem.right - 1;
ptOut[2].y = pdi->rcItem.top;
SelectObject (pdi->hDC, hPenDkShadow);
if (pdi->itemState & ODS_SELECTED) {
ptOut[1].x = pdi->rcItem.left;
ptOut[1].y = pdi->rcItem.top;
} else {
ptOut[1].x = pdi->rcItem.right - 1;
ptOut[1].y = pdi->rcItem.bottom - 1;
}
Polyline (pdi->hDC, ptOut, 3);
// Draw the icon.
if (hIcon) {
ptIn[0].x = (pdi->rcItem.right - pdi->rcItem.left)/2 -
GetSystemMetrics (SM_CXICON)/2 - 2;
ptIn[0].y = (pdi->rcItem.bottom - pdi->rcItem.top)/2 -
GetSystemMetrics (SM_CYICON)/2 - 2;
// If pressed, shift image down one pel to simulate the press.
if (pdi->itemState & ODS_SELECTED) {
ptOut[1].x += 2;
ptOut[1].y += 2;
}
DrawIcon (pdi->hDC, ptIn[0].x, ptIn[0].y, hIcon);
}
// If button has the focus, draw the dotted rect inside the button.
if (pdi->itemState & ODS_FOCUS) {
pdi->rcItem.left += 3;
pdi->rcItem.top += 3;
pdi->rcItem.right -= 4;
pdi->rcItem.bottom -= 4;
DrawFocusRect (pdi->hDC, &pdi->rcItem);
}
// Clean up. First select the original brush and pen into the DC.
SelectObject (pdi->hDC, hOldBr);
SelectObject (pdi->hDC, hOldPen);
// Now delete the brushes and pens created.
DeleteObject (hBr);
DeleteObject (hPenShadow);
DeleteObject (hPenDkShadow);
DeleteObject (hPenLight);
return 0;
}


EditDlg.cpp
//======================================================================
// EditDlg – Edit dialog box window code
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <prsht.h> // Property sheet includes
#include "DlgDemo.h" // Program-specific stuff
extern HINSTANCE hInst;
//----------------------------------------------------------------------
// Global data
//
// Identification strings for various WM_COMMAND notifications
NOTELABELS nlEdit[] = {{TEXT ("EN_SETFOCUS "), 0x0100},
{TEXT ("EN_KILLFOCUS"), 0x0200},
{TEXT ("EN_CHANGE "), 0x0300},
{TEXT ("EN_UPDATE "), 0x0400},
{TEXT ("EN_ERRSPACE "), 0x0500},
{TEXT ("EN_MAXTEXT "), 0x0501},
{TEXT ("EN_HSCROLL "), 0x0601},
{TEXT ("EN_VSCROLL "), 0x0602},
};
extern NOTELABELS nlPropPage[];
extern int nPropPageSize;
//======================================================================
// EditDlgProc – Edit box page dialog box procedure
//
BOOL CALLBACK EditDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
HWND hwndMain;
INT i;
switch (wMsg) {
case WM_INITDIALOG:
// The generic parameter contains the
// top-level window handle.
hwndMain = (HWND)((LPPROPSHEETPAGE)lParam)->lParam;
// Save the window handle in the window structure.
SetWindowLong (hWnd, DWL_USER, (LONG)hwndMain);
return TRUE;
//
// Reflect WM_COMMAND messages to main window.
//
case WM_COMMAND:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up button notification.
lstrcpy (szOut, TEXT ("WM_COMMAND: "));
for (i = 0; i < dim(nlEdit); i++) {
if (HIWORD (wParam) == nlEdit[i].wNotification) {
lstrcat (szOut, nlEdit[i].pszLabel);
break;
}
}
if (i == dim(nlEdit))
wsprintf (szOut, TEXT ("WM_COMMAND notification: %x"),
HIWORD (wParam));
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (LOWORD (wParam),ID_EDITPAGE),
(LPARAM)szOut);
return TRUE;
//
// Reflect notify message.
//
case WM_NOTIFY:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up notify message.
for (i = 0; i < nPropPageSize; i++) {
if (((NMHDR *)lParam)->code ==
nlPropPage[i].wNotification) {
lstrcpy (szOut, nlPropPage[i].pszLabel);
break;
}
}
if (i == nPropPageSize)
wsprintf (szOut, TEXT ("Notify code:%d"),
((NMHDR *)lParam)->code);
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (-1,ID_EDITPAGE), (LPARAM)szOut);
return FALSE; // Return false to force default processing.
}
return FALSE;
}


ListDlg.cpp
//======================================================================
// ListDlg – List box dialog window code
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <prsht.h> // Property sheet includes
#include "DlgDemo.h" // Program-specific stuff
extern HINSTANCE hInst;
//----------------------------------------------------------------------
// Global data
//
NOTELABELS nlList[] = {{TEXT ("LBN_ERRSPACE "), (-2)},
{TEXT ("LBN_SELCHANGE"), 1},
{TEXT ("LBN_DBLCLK "), 2},
{TEXT ("LBN_SELCANCEL"), 3},
{TEXT ("LBN_SETFOCUS "), 4},
{TEXT ("LBN_KILLFOCUS"), 5},
};
NOTELABELS nlCombo[] = {{TEXT ("CBN_ERRSPACE "), (-1)},
{TEXT ("CBN_SELCHANGE "), 1},
{TEXT ("CBN_DBLCLK "), 2},
{TEXT ("CBN_SETFOCUS "), 3},
{TEXT ("CBN_KILLFOCUS "), 4},
{TEXT ("CBN_EDITCHANGE "), 5},
{TEXT ("CBN_EDITUPDATE "), 6},
{TEXT ("CBN_DROPDOWN "), 7},
{TEXT ("CBN_CLOSEUP "), 8},
{TEXT ("CBN_SELENDOK "), 9},
{TEXT ("CBN_SELENDCANCEL"), 10},
};
extern NOTELABELS nlPropPage[];
extern int nPropPageSize;
//======================================================================
// ListDlgProc – List box page dialog box procedure
//
BOOL CALLBACK ListDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
HWND hwndMain;
INT i;
switch (wMsg) {
case WM_INITDIALOG:
// The generic parameter contains the
// top-level window handle.
hwndMain = (HWND)((LPPROPSHEETPAGE)lParam)->lParam;
// Save the window handle in the window structure.
SetWindowLong (hWnd, DWL_USER, (LONG)hwndMain);
// Fill the list and combo boxes.
for (i = 0; i < 20; i++) {
wsprintf (szOut, TEXT ("Item %d"), i);
SendDlgItemMessage (hWnd, IDC_SNGLELIST, LB_ADDSTRING,
0, (LPARAM)szOut);
SendDlgItemMessage (hWnd, IDC_MULTILIST, LB_ADDSTRING,
0, (LPARAM)szOut);
SendDlgItemMessage (hWnd, IDC_COMBOBOX, CB_ADDSTRING,
0, (LPARAM)szOut);
}
// Provide default selection for the combo box.
SendDlgItemMessage (hWnd, IDC_COMBOBOX, CB_SETCURSEL, 0, 0);
return TRUE;
//
// Reflect WM_COMMAND messages to main window.
//
case WM_COMMAND:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Report the WM_COMMAND messages.
lstrcpy (szOut, TEXT ("WM_COMMAND: "));
if (LOWORD (wParam) == IDC_COMBOBOX) {
for (i = 0; i < dim(nlCombo); i++) {
if (HIWORD (wParam) == nlCombo[i].wNotification) {
lstrcat (szOut, nlCombo[i].pszLabel);
break;
}
}
if (i == dim(nlCombo))
wsprintf (szOut,
TEXT ("WM_COMMAND notification: %x"),
HIWORD (wParam));
} else {
for (i = 0; i < dim(nlList); i++) {
if (HIWORD (wParam) == nlList[i].wNotification) {
lstrcat (szOut, nlList[i].pszLabel);
break;
}
}
if (i == dim(nlList))
wsprintf (szOut,
TEXT ("WM_COMMAND notification: %x"),
HIWORD (wParam));
}
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (LOWORD (wParam),ID_LISTPAGE),
(LPARAM)szOut);
return TRUE;
//
// Reflect notify message.
//
case WM_NOTIFY:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up notify message.
for (i = 0; i < nPropPageSize; i++) {
if (((NMHDR *)lParam)->code ==
nlPropPage[i].wNotification) {
lstrcpy (szOut, nlPropPage[i].pszLabel);
break;
}
}
if (i == nPropPageSize)
wsprintf (szOut, TEXT ("Notify code:%d"),
((NMHDR *)lParam)->code);
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (-1,ID_LISTPAGE),
(LPARAM)szOut);
return FALSE; // Return false to force default processing.
}
return FALSE;
}


StaticDlg.cpp
//======================================================================
// StaticDlg – Static control dialog box window code
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <prsht.h> // Property sheet includes
#include "DlgDemo.h" // Program-specific stuff
extern HINSTANCE hInst;
//----------------------------------------------------------------------
// Global data
//
// Identification strings for various WM_COMMAND notifications
NOTELABELS nlStatic[] = {{TEXT ("STN_CLICKED"), 0},
{TEXT ("STN_ENABLE "), 2},
{TEXT ("STN_DISABLE"), 3},
};
extern NOTELABELS nlPropPage[];
extern int nPropPageSize;
//======================================================================
// StaticDlgProc - Static control dialog box procedure
//
BOOL CALLBACK StaticDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
HWND hwndMain;
INT i;
switch (wMsg) {
case WM_INITDIALOG:
// The generic parameter contains the
// top-level window handle.
hwndMain = (HWND)((LPPROPSHEETPAGE)lParam)->lParam;
// Save the window handle in the window structure.
SetWindowLong (hWnd, DWL_USER, (LONG)hwndMain);
return TRUE;
//
// Reflect WM_COMMAND messages to main window.
//
case WM_COMMAND:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up button notification.
lstrcpy (szOut, TEXT ("WM_COMMAND: "));
for (i = 0; i < dim(nlStatic); i++) {
if (HIWORD (wParam) == nlStatic[i].wNotification) {
lstrcat (szOut, nlStatic[i].pszLabel);
break;
}
}
if (i == dim(nlStatic))
wsprintf (szOut, TEXT ("WM_COMMAND notification: %x"),
HIWORD (wParam));
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (LOWORD (wParam),ID_STATPAGE),
(LPARAM)szOut);
return TRUE;
//
// Reflect notify message.
//
case WM_NOTIFY:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up notify message.
for (i = 0; i < nPropPageSize; i++) {
if (((NMHDR *)lParam)->code ==
nlPropPage[i].wNotification) {
lstrcpy (szOut, nlPropPage[i].pszLabel);
break;
}
}
if (i == nPropPageSize)
wsprintf (szOut, TEXT ("Notify code:%d"),
((NMHDR *)lParam)->code);
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (-1,ID_STATPAGE), (LPARAM)szOut);
return FALSE; // Return false to force default processing.
}
return FALSE;
}


ScrollDlg.cpp
//======================================================================
// ScrollDlg – Scroll bar dialog box window code
//
// Written for the book Programming Windows CE
// Copyright (C) 2003 Douglas Boling
//======================================================================
#include <windows.h> // For all that Windows stuff
#include <prsht.h> // Property sheet includes
#include "DlgDemo.h" // Program-specific stuff
extern HINSTANCE hInst;
//----------------------------------------------------------------------
// Global data
//
// Identification strings for various WM_xSCROLL notifications
NOTELABELS nlVScroll[] = {{TEXT ("SB_LINEUP "), 0},
{TEXT ("SB_LINEDOWN "), 1},
{TEXT ("SB_PAGEUP "), 2},
{TEXT ("SB_PAGEDOWN "), 3},
{TEXT ("SB_THUMBPOSITION"), 4},
{TEXT ("SB_THUMBTRACK "), 5},
{TEXT ("SB_TOP "), 6},
{TEXT ("SB_BOTTOM "), 7},
{TEXT ("SB_ENDSCROLL "), 8},
};
NOTELABELS nlHScroll[] = {{TEXT ("SB_LINELEFT "), 0},
{TEXT ("SB_LINERIGHT "), 1},
{TEXT ("SB_PAGELEFT "), 2},
{TEXT ("SB_PAGERIGHT "), 3},
{TEXT ("SB_THUMBPOSITION"), 4},
{TEXT ("SB_THUMBTRACK "), 5},
{TEXT ("SB_LEFT "), 6},
{TEXT ("SB_RIGHT "), 7},
{TEXT ("SB_ENDSCROLL "), 8},
};
extern NOTELABELS nlPropPage[];
extern int nPropPageSize;
//======================================================================
// ScrollDlgProc – Scroll bar page dialog box procedure
//
BOOL CALLBACK ScrollDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam,
LPARAM lParam) {
TCHAR szOut[128];
SCROLLINFO si;
HWND hwndMain;
INT i, sPos;
switch (wMsg) {
case WM_INITDIALOG:
// The generic parameter contains
// the top-level window handle.
hwndMain = (HWND)((LPPROPSHEETPAGE)lParam)->lParam;
// Save the window handle in the window structure.
SetWindowLong (hWnd, DWL_USER, (LONG)hwndMain);
return TRUE;
//
// Reflect WM_COMMAND messages to main window.
//
case WM_VSCROLL:
case WM_HSCROLL:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Update the report window.
// Determine whether from horizontal or vertical scroll bar.
if (GetDlgItem (hWnd, 101) == (HWND)lParam) {
for (i = 0; i < dim(nlVScroll); i++) {
if (LOWORD (wParam) == nlVScroll[i].wNotification) {
lstrcpy (szOut, nlVScroll[i].pszLabel);
break;
}
}
if (i == dim(nlVScroll))
wsprintf (szOut, TEXT ("notification: %x"),
HIWORD (wParam));
} else {
for (i = 0; i < dim(nlHScroll); i++) {
if (LOWORD (wParam) == nlHScroll[i].wNotification) {
lstrcpy (szOut, nlHScroll[i].pszLabel);
break;
}
}
if (i == dim(nlHScroll))
wsprintf (szOut, TEXT ("notification: %x"),
HIWORD (wParam));
}
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (-1, ID_SCROLLPAGE), (LPARAM)szOut);
// Get scroll bar position.
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
GetScrollInfo ((HWND)lParam, SB_CTL, &si);
sPos = si.nPos;
// Act on the scroll code.
switch (LOWORD (wParam)) {
case SB_LINEUP: // Also SB_LINELEFT
sPos -= 2;
break;
case SB_LINEDOWN: // Also SB_LINERIGHT
sPos += 2;
break;
case SB_PAGEUP: // Also SB_PAGELEFT
sPos -= 10;
break;
case SB_PAGEDOWN: // Also SB_PAGERIGHT
sPos += 10;
break;
case SB_THUMBPOSITION:
sPos = HIWORD (wParam);
break;
}
// Check range.
if (sPos < 0)
sPos = 0;
if (sPos > 100)
sPos = 100;
// Update scroll bar position.
si.cbSize = sizeof (si);
si.nPos = sPos;
si.fMask = SIF_POS;
SetScrollInfo ((HWND)lParam, SB_CTL, &si, TRUE);
return TRUE;
//
// Reflect notify message.
//
case WM_NOTIFY:
// Get the handle of the main window from the user word.
hwndMain = (HWND) GetWindowLong (hWnd, DWL_USER);
// Look up notify message.
for (i = 0; i < nPropPageSize; i++) {
if (((NMHDR *)lParam)->code ==
nlPropPage[i].wNotification) {
lstrcpy (szOut, nlPropPage[i].pszLabel);
break;
}
}
if (i == nPropPageSize)
wsprintf (szOut, TEXT ("Notify code:%d"),
((NMHDR *)lParam)->code);
SendMessage (hwndMain, MYMSG_ADDLINE,
MAKEWPARAM (-1, ID_SCROLLPAGE), (LPARAM)szOut);
return FALSE; // Return false to force default processing.
}
return FALSE;
}











The dialog box procedures for each of the property pages report all WM_COMMAND and WM_NOTIFY messages back to the main window, where they're displayed in a list box contained in the main window. The property page dialog box procedures mirror the child window procedures of the CtlView example, the differences being that the page procedures don't have to create their controls and that they field the WM_INITDIALOG message to initialize the controls. The page procedures also use the technique of storing information in their window structures—in this case, the window handle of the main window of the example. This is necessary because the parent window of the pages is the property sheet, not the main window. The window handle is conveniently accessible during the WM_INITDIALOG message because it's loaded into the user-definable parameter in the PROPSHEETPAGE structure by the main window when the property sheet is created. Each page procedure copies the parameter from the PROPSHEETPAGE structure into the DWL_USER field of the window structure available to all dialog box procedures. When other messages are handled, the handle is then queried using GetWindowLong. The page procedures also field the WM_NOTIFY message so that they, too, can be reflected back to the main window.

As with CtlView, the best way to learn from DlgDemo is to run the program and watch the different WM_COMMAND and WM_NOTIFY messages that are sent by the controls and the property sheet. Opening the property sheet and switching between the pages results in a flood of WM_NOTIFY messages informing the individual pages of what's happening. It's also interesting to note that when the OK button is pressed on the property sheet, the PSN_APPLY messages are sent only to property pages that have been displayed.

The menu handlers that display the Print and Color common dialogs work with a bit of a twist. Because some Windows CE systems don't support these dialogs, DlgDemo can't call the functions directly. That would result in these two functions being implicitly linked at run time. On systems that did not support these functions, Windows CE wouldn't be able to resolve the implicit links to all the functions in the program, and therefore the program wouldn't be able to load. So instead of calling the functions directly, you explicitly link these functions in InitApp by loading the common dialog DLL using LoadLibrary and getting pointers to the functions using GetProcAddress. If DlgDemo is running on a system that doesn't support one of the functions, the GetProcAddress function fails and returns 0 for the function pointer. In OnCreateMain, a check is made to see whether these function pointers are 0, and if so, the Print and Color menu items are disabled. In the menu handler functions DoMainCommandColor and DoMainCommandPrint, the function pointers returned by GetProcAddress are used to call the functions. This extra effort isn't necessary if you know your program will run only on a system that supports a specific set of functions, but every once in a while, this technique comes in handy.

The Pocket PC handles the common print dialog differently. Although the Pocket PC exports the function PageSetupDialog, the function prototype isn't included in the SDK, and the function returns immediately when called.

One other detail is how this program adapts to the Pocket PC shell. DlgDemo creates a menu bar instead of a command bar when compiled for the Pocket PC. This provides a place for the menu as well as exposing the Soft Keyboard button.

In addition, on Pocket PCs, the property sheet expands to fill the full screen, and its tabs are located on the bottom of the sheet instead of the top. I made these adaptations to demonstrate how to comply with the Pocket PC user interface guidelines. To place the tabs on the bottom of the sheet and provide the hyperlink text below the pages, DlgDemo provides the property sheet callback function shown here:

int CALLBACK PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) {
if (uMsg == PSCB_INITIALIZED) {
// Get tab control
HWND hwndTabs = GetDlgItem (hwndDlg, 0x3020);
DWORD dwStyle = GetWindowLong (hwndTabs, GWL_STYLE);
SetWindowLong (hwndTabs, GWL_STYLE, dwStyle | TCS_BOTTOM);
} else if (uMsg == PSCB_GETVERSION)
return COMCTL32_VERSION;
return 1;
}

The source of this rather strange code comes from the MFC source code provided with the Pocket PC SDK. During the PSCB_INITIALIZE notification, the handle of the Tab control of the property sheet is queried using the predefined control ID 0x3020. The style bits of the Tab control are then modified to have the control place the tabs on the bottom instead of the top by setting the TCS_BOTTOM style flag.

The function also handles the PSCB_GETLINKTEXT notification and returns the following text:

TEXT ("Launch the calculator by tapping <file:calc.exe{here}>.")

The hyperlink is enclosed in angle brackets <>. The text displayed for the link is enclosed in curly braces {}. When the hyperlink is tapped, the Pocket PC will launch calc.exe. The hyperlink can also be a data file such as book1.pxl or memo.pwd.

Dialog boxes and property sheets are quite often the only user interface a Windows CE program has. Although sometimes complex in implementation, the help Windows CE provides in creating and maintaining dialog boxes and property sheets reduces the workload on the program to some extent.

This chapter also marks the end of the introductory section, "Windows Programming Basics." In these first six chapters, I've talked about fundamental Windows programming while also using a basic Windows CE application to introduce the concepts of the system message queue, windows, and messages. I've given you an overview of how to paint text and graphics in a window and how to query the user for input. Finally, I talked about the windows hierarchy, controls, common controls, and dialog boxes. For the remainder of the book, I move from description of the elements common to both Windows CE and the desktop versions of Windows to the unique nature of Windows CE programming. It's time to turn to the operating system itself. Over the next four chapters, I'll cover memory management, files, databases, and processes and threads. These chapters are aimed at the core of the Windows CE operating system.

/ 169