www.xbdev.net xbdev - software development
Friday December 14, 2018
home | about | contact | Donations

     
 

Win32..

Using our Windows API's...

 

Tutorial 2: Win32 - More than graphics...

by bkenwright@xbdev.net

 

Text - "Hello Window"

 

You look at your window, and its not just pretty lines and pictures.... there's writing as well...different sizes and all over the place..  Which leads us to "FONTS"....yup creating text out.  Its not as hard as you might think...once you get past the how...its will become second nature eventually.

 

To splash some text on our screen.....be it our window or the desktop...or any window...all we need is the Handle to the DC...e.g. HDC...which we can get using the API, GetDC(..) like this: hdc = GetDC(hWnd); ...  its pretty simple once you have the dc.

 

DownloadSourceCode

 

The simple demo will show you how easy it is to add text output to your simple Win32 application.... we'll use the default Font first, which is the font that is currently in the HDC, whatever it might be...and we'll render our mouse position to the window, as you can see from the screen shot on the right.

// This is our Call Back procedure, where you would put your code...this gets

// called repeatedly from our windows messaging loop.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

{

      switch(iMessage)

      {

      case WM_MOUSEMOVE:

            {

                  // NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW **

                  HDC hDC = GetDC(hWnd);

                  int xp = LOWORD(lParam);

                  int yp = HIWORD(lParam);

                  // Use the default Font to display our mouse position on screen

                  char buf[200];           // Temp text buffer

                  sprintf(buf, "xpos:%d, ypos:%d", xp, yp);

 

 

                  //       +--- HDC, which is our screen drawing canvas

                  //       |   +---+-- x and y position..where 0,0 is the top left

                  //       |   |   |   +--- Our string of char's

                  //       |   |   |   |       +------The number of characters to display

                  //      \|/ \|/ \|/ \|/     \|/

                  //       |   |   |   |       |

                  TextOut(hDC, 5,  5, buf, strlen(buf));

                  ReleaseDC(hWnd, hDC);

            }

            break;

      case WM_CLOSE:

            if(MessageBox(hWnd, "Leave? Quit the our mini window?", "Message", MB_YESNO) == IDYES)

                  PostQuitMessage(0);

           

            break;

      default:

            return DefWindowProc(hWnd, iMessage, wParam, lParam);

      }

      return 0;

}

 

 

But we'll want to use our own font eventually...maybe arial 10...or time roman....who knows..  Which will bring us the the CreateFont(..) API, which is one of the biggest you'll ever come across.....not because its so powerful...but because it takes so many parameters which you pass to it.

 

Most of the time you'll just select default values for most of the parameters shown for the CreateFont(..) API, as you can see below in our demo, you can create massive fonts.... or italics etc. 

 

Usually you end up making a wrapper function...something called "void CreateMyFont(..)" which only takes parameters that you think would be useful.  Like font size and type of font.

 

Once you've used it once or twice you'll soon get the hand of it.

/* Details for CreateFont(..) from the ms docs.

      HFONT CreateFont(

            int nHeight,               // height of font

            int nWidth,                // average character width

            int nEscapement,           // angle of escapement

            int nOrientation,          // base-line orientation angle

            int fnWeight,              // font weight

            DWORD fdwItalic,           // italic attribute option

            DWORD fdwUnderline,        // underline attribute option

            DWORD fdwStrikeOut,        // strikeout attribute option

            DWORD fdwCharSet,          // character set identifier

            DWORD fdwOutputPrecision,  // output precision

            DWORD fdwClipPrecision,    // clipping precision

            DWORD fdwQuality,          // output quality

            DWORD fdwPitchAndFamily,   // pitch and family

            LPCTSTR lpszFace           // typeface name

      );

*/

 

That the first parameter is the height can be quite useful to know. A 0 here means "I don't care what the stupid height is just give me the font and give it now, please" or something like that.
The next parm is the width, pretty much the same can be said about the width as I said about the height.
The next two parameters are called Escapement and Orientation, I mention these together since for Win95/98 you should set these two to the same value (this is not the case for WinNT). They want the angle in tenths of degrees that the textbase should be rotated, 0 here will cause normal text.
The next parm is the weight, this is the place you specify baldness...no, no your boldness...ahm, the boldness of the font. Here FW_DONTCARE means "I don't care what the stupid weight is just give me the font and give it now, please" and FW_THIN will mean a really, really thin font. FW_NORMAL will mean the same as FW_REGULAR. FW_BOLD means that the text will be bold, FW_ULTRABOLD means that you want something more than just bold, you want ultrabold (sorry html only allows me to make one type of bold). Finally if nothing else helps, you've got FW_BLACK which is the super-ultra-mega bold or so-bold-you-can't-get-any-bolder-and-still-be-bold type of bold, if you know what I mean...(blink, blink)? Yep, that kind of bold!
The next parm is a boolean you set to true if you want italic text-style.
The next parm is also a boolean and you set it to true for underlined texts.
Further on the next parm is set to true for strikeout text-style.
In the next parm you specify the character set you want to use (ANSI, Chineese), I prefer DEFAULT_CHARSET and so does the docs.
The next parm is another non-care, it specifies how close the chosen font must match the specifications given. Use OUT_DEFAULT_PRECIS for most apps.
Now comes another boring parm, the clip-precision, use CLIP_DEFAULT_PRECIS or consult the Win32 docs for more info.
Yep, there's more, now comes the quality parm. There are only three possible values: DEFAULT_QUALITY (should be used), DRAFT_QUALITY (less quality), PROOF_QUALITY (more quality). I won't explain the ins and outs of the different qualities, if you want to know consult the Win32 docs. Ok, we're almost there, just two more parms (by now you must have understood why I chosed to create the function MyCreateFont()).
Ok the first of the two are called pitch and family. In this the two low-order bits defines the pitch, which can be: DEFAULT_PITCH (the easy way out ;-), FIXED_PITCH and VARIABLE_PITCH. Then the four high-order bits should be one of the following: FF_DECORATIVE, FF_DONTCARE (this is what I use), FF_MODERN, FF_ROMAN, FF_SCRIPT or FF_SWISS. Try to use different families to see what the effects are. However the pitch and family are or:ed together, ex: DEFAULT_PITCH | FF_DONTCARE.
And finally, the last parm is a string that can contain the name of a font you want, ex. "New Times Roman" or something like that, it can of course be NULL and then Windows choses font for you.

 

If you change something, always put it back to the way you found it!  A rule of thumb for windows programmers.  As when we get the Handle to a DC, if we select a new object into it, well when we've finished with it, we put the old object back before releasing it.  Else if you don't, this can lead to mini memory leaks which are horrible to track down.... so be a good coder and save the object your returned when you use "SelectObject(..)" with your new font.

 

 

DownloadSourceCode

 

A larger font... and we can specify the width..height...italic's etc...all using our new CreateFont(..) API.

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

{

      switch(iMessage)

      {

      case WM_MOUSEMOVE:

            {

                  HDC hDC = GetDC(hWnd);

                  int xp = LOWORD(lParam);

                  int yp = HIWORD(lParam);

                  // Use the default Font to display our mouse position on screen

                  char buf[200];           // Temp text buffer

                  sprintf(buf, "xpos:%d, ypos:%d", xp, yp);

 

                  // NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW **

                  HGDIOBJ hObj;

                  int iWeight = 2;

                  DWORD dwItalic = 0; // 1 for italic/ 0 for no itallic

                  // Create our font!  This is where the magic happens :)

                  HFONT hNewFont = CreateFont(25, 12, 0, 0, iWeight, dwItalic, FALSE, FALSE,

                            DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,

                              DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, NULL);

 

                  // Select our new font into our DC so we can use it.

                  hObj = SelectObject(hDC, hNewFont);

 

                  //       +--- HDC, which is our screen drawing canvas

                  //       |   +---+-- x and y position..where 0,0 is the top left

                  //       |   |   |   +--- Our string of char's

                  //       |   |   |   |       +------The number of characters to display

                  //      \|/ \|/ \|/ \|/     \|/

                  //       |   |   |   |       |

                  TextOut(hDC, 5,  5, buf, strlen(buf));

                  SelectObject(hDC, hObj); // Select our old object back into hDC - always leave

                                           // it the way you found it as they say.

                  ReleaseDC(hWnd, hDC);

 

                  // NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW ** NEW **

                  DeleteObject(hNewFont);

            }

            break;

      case WM_CLOSE:

            if(MessageBox(hWnd, "Leave? Quit the our mini window?", "Message", MB_YESNO) == IDYES)

                  PostQuitMessage(0);

           

            break;

      default:

            return DefWindowProc(hWnd, iMessage, wParam, lParam);

      }

      return 0;

}

 

 

You can draw lines....set pixels on the screen with "SetPixel(..)" API...and even do fancy fonts.  Its amazing how easy it is.  Remember windows is your friend..its designed to make things easy for you.

 

 

 

 

 

 

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.