zhuang@linux:~/reading/programming-windows/04-an-exercise-in-text-output/$ less
An Exercise in Text Output
This post extracts some knowledge from Programming Windows Chapter 4 – An Exercise in Text Output.
The WM_PAINT Message
Most Windows programs call the function UpdateWindow during initialization in WinMain shortly before entering the message loop. Windows takes this opportunity to send the window procedure its first WM_PAINT message.
This message informs the window procedure that the client area must be painted. Thereafter, that window procedure should be ready at almost any time to process additional WM_PAINT messages and even to repaint the entire client area of the window if necessary. A window procedure receives a WM_PAINT message whenever one of the following events occurs:
- A previously hidden area of the window is brought into view when a user moves a window or uncovers a window.
- The user resizes the window (if the window class style has the
CS_HREDRAWandCW_VREDRAWbits set). - The program uses the
ScrollWindoworScrollDCfunction to scroll part of its client area. - The program uses the
InvalidateRectorInvalidateRgnfunction to explicitly generate aWM_PAINTmessage.
Getting a Device Context Handle
Windows applications generally use two methods for getting a device context handle in preparation for painting the screen.
Method One: BeginPaint and EndPaint
While processing a WM_PAINT message, the window procedure first calls BeginPaint. The BeginPaint function generally causes the background of the invalid region to be erased in preparation for painting. The function also fills in the fields of the ps structure. The value returned from BeginPaint is the device context handle. This is commonly saved in a variable named hdc. A call to EndPaint releases the device context handle.
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
// [ Some GDI function ]
EndPaint(hwnd, &ps);
return 0;The Paint Information Structure
Windows maintains a “paint information structure” for each window. That’s what PAINTSTRUCT is. The structure is defined as follows:
typedef struct tagPAINTSTRUCT { // ps
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT;Method Two: GetDC and ReleaseDC
Although it is best to structure your program so that you can update the entire client area during the WM_PAINT message, you may also find it useful to paint part of the client area while processing messages other than WM_PAINT. Or you may need a device context handle for other purposes, such as obtaining information about the device context.
hdc = GetDC(hwnd);
// [ using GDI function ]
ReleaseDC(hwnd, hdc);The Size of a Character
GetTextMetrics requires a handle to a device context because it returns information about the font currently selected in the device context.
hdc = GetDC (hwnd) ;
GetTextMetrics (hdc, &tm) ;
ReleaseDC (hwnd, hdc) ;The TEXTMETRIC structure has 20 fields, but we’re interested in only the first seven:
typedef struct tagTEXTMETRIC
{
LONG tmHeight ;
LONG tmAscent ;
LONG tmDescent ;
LONG tmInternalLeading ;
LONG tmExternalLeading ;
LONG tmAveCharWidth ;
LONG tmMaxCharWidth ;
// [other structure fields]
}
TEXTMETRIC, * PTEXTMETRIC ;The values of these fields are in units that depend on the mapping mode currently selected for the device context.
Scroll Bar
Scroll Bar Message
WM_VSCROLL and WM_HSCROLL are accompanied by the wParam and lParam message parameters.
For messages from scroll bars created as part of your window, you can ignore lParam;
that’s used only for scroll bars created as child windows, usually within dialog boxes.
The wParam message parameter is divided into a low word and a high word.
The low word of wParam is a number that indicates what the mouse is doing to the scroll bar.
This number is referred to as a “notification code.”
Notification codes have values defined by identifiers that begin with SB, which stands for “scroll bar.”
When you position the mouse cursor over the scroll bar thumb and press the mouse button, you can move the thumb.
This generates scroll bar messages with notification codes of SB_THUMBTRACK and SB_THUMBPOSITION.
When the low word of wParam is SB_THUMBTRACK, the high word of wParam is the current position of the scroll bar thumb as the user is dragging it.
This position is within the minimum and maximum values of the scroll bar range.
When the low word of wParam is SB_THUMBPOSITION, the high word of wParam is the final position of the
scroll bar thumb when the user released the mouse button.
For other scroll bar actions, the high word of wParam should be ignored.
Scroll Bar function
SetScrollRange, SetScrollPos, GetScrollRange, and GetScrollPos (obsolete, new application donot use)
SetScrollInfo and GetScrollInfo
ScrollWindowEx and ScrollWindow
zhuang@linux:~/reading/programming-windows/04-an-exercise-in-text-output/$ comments