Saturday, November 5, 2011

Hello Windows in C programming

We would begin our tryst with graphics programming under windows by displaying a message “Hello Windows” in different fonts. Note that though we are displaying text under Windows even text gets drawn graphically in the window. First take a look at the program given below before we set out to understand it.

# include <windows.h>
# include "helper.h"
void OnPaint ( HWND ) ;
void OnDestroy ( HWND ) ;
int __stdcall WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdline, int nCmdShow )
{
MSG m ;
/* Perform application initialization */
InitInstance ( hInstance, nCmdShow, "Text" ) ;

/* Main message loop */
while ( GetMessage ( &m, NULL, 0, 0 ) )
DispatchMessage(&m);
return 0 ;
}
LRESULT CALLBACK WndProc ( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_DESTROY :
OnDestroy ( hWnd ) ;
break ;
case WM_PAINT :
OnPaint ( hWnd ) ;
break ;
default :
return DefWindowProc ( hWnd, message, wParam, lParam ) ;
}
return 0 ;
}
void OnDestroy ( HWND hWnd )
{
PostQuitMessage ( 0 ) ;
}
void OnPaint ( HWND hWnd )
{
HDC hdc ;
PAINTSTRUCT ps ;
HFONT hfont ;
LOGFONT f = { 0 } ;
HGDIOBJ holdfont ;
char *fonts[ ] = { "Arial", "Times New Roman", "Comic Sans MS" } ;
int i ;
hdc = BeginPaint ( hWnd, &ps ) ;
for ( i = 0 ; i < 3 ; i++ )
{
strcpy ( f.lfFaceName, fonts[ i ] ) ; /* copy font name */
f.lfHeight = 40 * ( i + 1 ) ; /* font height */
f.lfItalic = 1 ; /* italic */
hfont = CreateFontIndirect ( &f ) ;
holdfont = SelectObject ( hdc, hfont ) ;
SetTextColor ( hdc, RGB ( 0, 0, 255 ) ) ;
TextOut ( hdc, 10, 70 * i, "Hello Windows", 13 ) ;
SelectObject ( hdc, holdfont ) ;
DeleteObject ( hfont ) ;
ram the window shown in Figure 18.1 appears





Drawing to a window involves handling the WM_PAINT message. This message is generated whenever the client area of the window needs to be redrawn. This redrawing would be required in the following situations:

(a) When the Window is displayed for the first time.
(b) When the window is minimized and then maximized.
(c) When some portion of the window is overlapped by another window and the overlapped window is dismissed.
(d) When the size of the window changes on stretching its boundaries.
(e) When the window is dragged out of the screen and then brought back into the screen.
Would a WM_PAINT message be generated when the cursor is dragged in the window? No. In this case the window saves the area overlapped by the cursor and restores it when the cursor moves to another position.
When the switch-case structure inside WndProc( ) finds that the message ID passed to WndProc( ) is WM_PAINT, it calls the function OnPaint( ). Within OnPaint( ) we have called the API function BeginPaint( ). This function obtains a handle to the device context. Additionally it also fills the PAINTSTRUCT structure with information about the area of the window which needs to be repainted. Lastly it removes WM_PAINT from the message queue. After obtaining the device context handle, the control enters a loop.
Inside the loop we have displayed “Hello Windows” in three different fonts. Each time through the loop we have setup a LOGFONT structure f. This structure is used to indicate the font properties like font name, font height, italic or normal, etc. Note that in addition to these there are other font properties that may be setup. The properties that we have not setup in the loop are all initialized to 0. Once the font properties have been setup we have called the CreateFontIndirect( ) API function to create the font.
This function loads the relevant font file. Then using the information in the font file and the font properties setup in the LOGFONT structure it creates a font in memory. CreateFontIndirect( ) returns the handle to the font created in memory. This handle is then passed to the SelectObject( ) API function to get the font into the DC. This function returns the handle to the existing font in the DC, which is preserved in holdfont variable. Next we have used the SetTextColor( ) API function to set the color of the text to be displayed through TextOut( ). The RGB( ) macro uses the red, green and blue component values to generate a 32-bit color value. Note that each color component can take a value from 0 to 255. To TextOut( ) we have to pass the handle to the DC, position where the text is to be displayed, the text to be displayed and its length.
With hfont only one font can be associated at a time. Hence before associating another font with it we have deleted the existing font using the DeleteObject( ) API function. Once outside the loop we have called the EndPaint( ) API function to release the DC handle. If not released we would be wasting precious memory, because the device context structure would remain in memory but we would not be able access it.
In place of TextOut( ) we can also use the DrawText( ) API function. This function permits finer control over the way the text is displayed. You can explore this function on your own.

No comments:

Post a Comment