The two popular functions for printing text are TextOut() and DrawText().
The prototypes are as follows –
BOOL TextOut(HDC hdc, int x,int y,LPCSTR lpString,int slength);
where
hdc – A handle to the device context.
x – horizontal location.
y – vertical location.
lpString – pointer to a character string.
slength – is the number of characters in the string to be displayed
If the function succeeds, the return value is non zero. If the function fails, the return value is 0.
int DrawText( HDC hdc,LPCTSTR lpString,int nCount,LPRECT lpRect,UINT uFormat);
where
hdc – A handle to the device context.
lpString – A pointer to the string that specifies the text to be drawn. If the nCount parameter is -1, the string must be null-terminated.
nCount – The length, in characters, of the string
lpRect -A pointer to a RECT structure that contains the rectangle (in logical coordinates) in which the text is to be formatted.
uFormat -The method of formatting the text.
If the function succeeds, the return value is the height of the text in logical units. If the function fails, the return value is zero.
In addition to a small variety of built-in fonts, Windows also allows the creation of custom-built fonts. To create a custom font use the CreateFont win32 API function. The syntax for the CreateFont function is
HFONT CreateFont(int cHeight,int cWidth,int cEscapement,int cOrientation,int cWeight,DWORD bItalic,DWORD bUnderline,DWORD bStrikeOut,DWORD iCharSet,DWORD iOutPrecision,DWORD iClipPrecision,DWORD iQuality,DWORD iPitchAndFamily,LPCSTR pszFaceName);
If successful the CreateFont returns a handle to the font created. If the function fails, the return value is NULL. Any created font must be deleted before the application terminates. In order to delete the font use the DeleteObject() function.
For a more detailed explanation on font creation – https://docs.microsoft.com/en-us/windows/win32/gdi/font-creation-and-selection
The windows API functions SetTextColor and SetBkColorTo are used to set the text colour and text background colour. The syntax for these two are
COLORREF SetTextColor(HDC hdc,COLORREF color);
COLORREF SetBkColor(HDC hdc,COLORREF color);
Where hdc refers to the device context and color is used to specify an RGB value. If the function succeeds, the return value is a color reference to the previous text color.
The textmetric structure is used to describe the attributes of a given font and enables an application to work with text with different font attributes. The API function GetTextMetrics() is used to get information about the current font. The syntax of this function is –
BOOL GetTextMetrics(HDC hdc,LPTEXTMETRIC lptm);
Where hdc is a handle to the device context and lptm is a pointer to the TEXTMETRIC structure that receives the text metrics.
If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.
The textmetric structure is defined as follows-
TypeDef struct TEXTMETRIC{
tmHeight As Long //height of font
tmAscent As Long //height above baseline
tmDescent As Long //length of descender
tmInternalLeading As Long //space above character
tmExternalLeading As Long //blank space above rows
tmAveCharWidth As Long //average width
tmMaxCharWidth As Long //maximum width
tmWeight As Long //weight
tmOverhang As Long //extra width added to special font
tmDigitizedAspectX As Long //horizontal aspect
tmDigitizedAspectY As Long //vertical aspect
tmFirstChar As Byte //first character in font
tmLastChar As Byte //last character in font
tmDefaultChar As Byte //dafault character
tmBreakChar As Byte //character used to break words
tmItalic As Byte //non zero if italic
tmUnderlined As Byte //non zero if underlined
tmStruckOut As Byte //non zeri is struckout
tmPitchAndFamily As Byte //pitch and family of font
tmCharSet As Byte //character set identifier
}End Type
For more information
https://docs.microsoft.com/en-gb/windows/win32/api/wingdi/ns-wingdi-textmetrica
Since the characters in a non-monospaced typeface will not occupy the same amount of horizontal space on a line, it will be necessary for an application to know the length of a string in order that it can output consecutive lines of text. As windows does not keep track of the current output location then an application will need to know where any previous text output ended. To provide this information the Windows API includes the function GetTextExtentPoint32()-
BOOL GetTextExtentPoint32(HDC hdc,LPCSTR lpString,int len,LPSIZE lpsize);
where
hdc – A handle to the device context.
lpString – holds the string used for the length calculation.
len – length of the string lpString.
lpsize – A pointer to a SIZE structure that returns the width or height of the string (see below)
If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.
The prototype for the size structure is
typedef struct tagSIZE {LONG cx;LONG cy;} SIZE;
Upon return, the CX field will contain the length of the string and the CY will contain the height of the string.
The following code creates a basic window to demonstrate various aspects of font formatting
//Font Formatting Example//
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("myWindowClass");
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
RegisterClassEx(&wc);
CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("myWindowClass"), TEXT("Text Output"), WS_VISIBLE | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 700, 200, NULL, NULL, hInstance, NULL);
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT Ps;
HDC hdc;
SIZE size;
TCHAR str[100]=TEXT("\0");
HFONT font;
HBRUSH hBrush;
TEXTMETRIC tm;
int y=0;
int x=0;
int textlength;
switch (msg)
{
case WM_PAINT://traps paint message
//output text using default font
hdc = BeginPaint(hwnd, &Ps);
int hDCLast;
hDCLast=SaveDC(hdc);//save current device context
textlength=wsprintf(str,TEXT("Stock font"));
TextOut(hdc,0,y,str,textlength);
//select ANSI_FIXED_FONT and output text
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;//calculate new vertical coordinate using text metric
hBrush=(HBRUSH)GetStockObject(ANSI_FIXED_FONT);
SelectObject(hdc,hBrush);
textlength=wsprintf(str,TEXT("ANSI_FIXED_FONT") );
TextOut(hdc,0,y,str,textlength);
//set text to colour red and output text
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;
COLORREF newtextcolour;
newtextcolour=COLORREF RGB(255, 0, 0);
SetTextColor(hdc,newtextcolour);
textlength=wsprintf(str,TEXT("ANSI_FIXED_FONT, colour red") );
TextOut(hdc,x,y,str,textlength);
//set text background to colour blue and output text
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;
COLORREF newbkcolour;
newbkcolour=COLORREF RGB(0, 0, 255);
SetBkColor(hdc,newbkcolour);
textlength=wsprintf(str, TEXT("ANSI_FIXED_FONT, colour red with blue background") );
TextOut(hdc,x,y,str,textlength);
//set text background to transparent and output text
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;
SetBkMode(hdc,TRANSPARENT);
SelectObject(hdc,hBrush);
textlength=wsprintf(str,TEXT("ANSI_FIXED_FONT,colour red transparent background") );
TextOut(hdc,0,y,str,textlength);
//select font Ariel 20 and output text
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;
font = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Ariel"));
SelectObject(hdc,font);
textlength=wsprintf(str,TEXT("ANSI_FIXED_FONT, colour red, transparent background,arial 20") );
TextOut(hdc,0,y,str,textlength);
//restore default font using saved value and output text
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;
RestoreDC(hdc,hDCLast);
textlength=wsprintf(str,TEXT("stock font restored using SaveDC/RestoreDC") );
TextOut(hdc,x,y,str,textlength);
GetTextMetrics(hdc,&tm);
y=y+tm.tmHeight;//calculate new vertical coordinate using text metric
//select font times new romans 30 and output text
int baseline;//used to caculate font baseline
font = CreateFont(30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Times New Roman"));
SelectObject(hdc,font);
GetTextMetrics(hdc,&tm);
baseline=tm.tmAscent;
textlength=wsprintf(str,TEXT("times new roman 30 statement 1") );
TextOut(hdc,x,y,str,textlength);
GetTextExtentPoint32(hdc,str,lstrlen(str),&size);
x=x+size.cx;
//select font courier new 20 and output text
int baselinecourier;
font = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("Courier New"));
SelectObject(hdc,font);
GetTextMetrics(hdc,&tm);
baselinecourier=baseline-tm.tmAscent;
textlength=wsprintf(str, TEXT("Courier statement ") );
TextOut(hdc,x,y+baselinecourier,str,textlength);
GetTextExtentPoint32(hdc,str,lstrlen(str),&size);
x=x+size.cx;
//select font ariel 20 and output text
int baselineariel;
font = CreateFont(10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,TEXT( "Ariel"));
SelectObject(hdc,font);
GetTextMetrics(hdc,&tm);
baselineariel=baseline-tm.tmAscent;
textlength=wsprintf(str, TEXT("ariel 10 statement 3 ") );
TextOut(hdc,x,y+baselineariel,str,textlength);
EndPaint(hwnd, &Ps);
DeleteDC(hdc);
DeleteObject(font);
DeleteObject(hBrush);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}