The WHATSIZE Program

We'll use various mapping modes as we explore the GDI functions in the next four chapters. Right now, let's simply look at the size of a client area in terms of inches and millimeters. The WHATSIZE program, shown in Figure 11-5, displays the size of the client area in terms of units associated with the six fully constrained mapping modes: MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, and MM_TWIPS.

WHATSIZE.MAK

#------------------------

# WHATSIZE.MAK make file

#------------------------

whatsize.exe : whatsize.obj whatsize.def

link whatsize, /align:16, NUL, /nod slibcew libw, whatsize

rc whatsize.exe

whatsize.obj : whatsize.c

cl -c -Gsw -Ow -W2 -Zp whatsize.c

WHATSIZE.C

/*-----------------------------------------

WHATSIZE.C -- What Size Is the Window?

(c) Charles Petzold, 1990

-----------------------------------------*/

#include <windows.h>

#include <stdio.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpszCmdLine, int nCmdShow)

{

static char szAppName[] = "WhatSize" ;

HWND hwnd ;

MSG msg ;

WNDCLASS wndclass ;

if (!hPrevInstance)

{

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ; RegisterClass (&wndclass) ;

}

hwnd = CreateWindow (szAppName, "What Size Is the Window?",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, nCmdShow) ;

UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

void Show (HWND hwnd, HDC hdc, short xText, short yText, short nMapMode,

char *szMapMode)

{

char szBuffer [60] ;

RECT rect ;

SaveDC (hdc) ;

SetMapMode (hdc, nMapMode) ;

GetClientRect (hwnd, &rect) ;

DPtoLP (hdc, (LPPOINT) &rect, 2) ;

RestoreDC (hdc, -1) ;

TextOut (hdc, xText, yText, szBuffer,

sprintf (szBuffer, "%-20s %7d %7d %7d %7d", szMapMode,

rect.left, rect.right, rect.top, rect.bottom)) ;

}

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)

{

static char szHeading [] =

"Mapping Mode Left Right Top Bottom" ;

static char szUndLine [] =

"------------ ---- ----- --- ------" ;

static short cxChar, cyChar ;

HDC hdc ; PAINTSTRUCT ps ;

TEXTMETRIC tm ;

switch (message)

{

case WM_CREATE :

hdc = GetDC (hwnd) ;

SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

GetTextMetrics (hdc, &tm) ;

cxChar = tm.tmAveCharWidth ;

cyChar = tm.tmHeight + tm.tmExternalLeading ;

ReleaseDC (hwnd, hdc) ;

return 0 ;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

SetMapMode (hdc, MM_ANISOTROPIC) ;

SetWindowExt (hdc, 1, 1) ;

SetViewportExt (hdc, cxChar, cyChar) ;

TextOut (hdc, 1, 1, szHeading, sizeof szHeading - 1) ;

TextOut (hdc, 1, 2, szUndLine, sizeof szUndLine - 1) ;

Show (hwnd, hdc, 1, 3, MM_TEXT, "TEXT (pixels)") ;

Show (hwnd, hdc, 1, 4, MM_LOMETRIC, "LOMETRIC (.1 mm)") ;

Show (hwnd, hdc, 1, 5, MM_HIMETRIC, "HIMETRIC (.01 mm)") ;

Show (hwnd, hdc, 1, 6, MM_LOENGLISH, "LOENGLISH (.01 in)") ;

Show (hwnd, hdc, 1, 7, MM_HIENGLISH, "HIENGLISH (.001 in)") ;

Show (hwnd, hdc, 1, 8, MM_TWIPS, "TWIPS (1/1440 in)") ;

EndPaint (hwnd, &ps) ;

return 0 ;

case WM_DESTROY :

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}

WHATSIZE.DEF

;-------------------------------------

; WHATSIZE.DEF module definition file

;-------------------------------------

NAME WHATSIZE

DESCRIPTION 'What Size Is the Window? (c) Charles Petzold, 1990'

EXETYPE WINDOWS

STUB 'WINSTUB.EXE'

CODE PRELOAD MOVEABLE DISCARDABLE

DATA PRELOAD MOVEABLE MULTIPLE

HEAPSIZE 1024

STACKSIZE 8192

EXPORTS WndProc

For ease in displaying the information using the TextOut function, WHATSIZE uses the MM_ANISOTROPIC mapping mode with logical units set to character dimensions:

SetMapMode (hdc, MM_ANISOTROPIC) ;

SetWindowExt (hdc, 1, 1) ;

SetViewportExt (hdc, cxChar, cyChar) ;

The program can then specify logical coordinates to TextOut in character row and character column coordinates for a fixed-pitch font.

When WHATSIZE needs to obtain the size of the client area for one of the six mapping modes, it saves the current device context, sets a new mapping mode, obtains the client-area coordinates, converts them to logical coordinates, and then restores the original mapping mode before displaying the information. This code is in WHATSIZE's Show function:

SaveDC (hdc) ;

SetMapMode (hdc, nMapMode) ;

GetClientRect (hwnd, &rect) ;

DPtoLP (hdc, (LPPOINT) &rect, 2) ;

RestoreDC (hdc, -1) ;

Figure 11-6 shows a typical display from WHATSIZE.

Now that we have the preliminaries down, we're ready to start drawing.