工程模板:https://www.cnblogs.com/eternalmoonbeam/p/10793080.html
安全的文本输出方式:
需要额外包含头文件strsafe.h
依次使用以下三个函数:
1.StringCchPrintf
2.StringCchLength
3.TextOut
StringCchPrintf:
STRSAFEAPI StringCchPrintfA
(
STRSAFE_LPSTR pszDest,
size_t cchDest,
STRSAFE_LPCSTR pszFormat,
...
);
将格式化数据写入指定的字符串。向函数提供目标缓冲区的大小,以确保它不会写入超过该缓冲区的结尾。
第一个参数是待写入的字符串,可使用TCHAR定义(不可省略长度);
第二个参数是缓冲区大小,尽量使用合适的长度,可稍大于字符串长度,使用size_t定义;
第三个参数规定了文本的输入方式,并可引入其它变量进行输入通过转换修饰符“%”,可直接通过TEXT(" ")进行编辑;
添加的参数要与转换修饰符一一对应。
StringCchLength:
STRSAFEAPI StringCchLengthW
(
STRSAFE_PCNZWCH psz,
size_t cchMax,
size_t *pcchLength
);
确定字符串是否超过指定的长度(以字符为单位)。
第一个参数使用与上个函数相同的字符串名;
第二个参数是字符串最大长度;
第三个参数是存储字符串实际长度的变量,使用size_t进行定义,但传入的是其地址,要使用地址运算“&”。
TextOut:
BOOL TextOutA(
HDC hdc,
int x,
int y,
LPCSTR lpString,
int c
);
第一个参数是获取设备环境上下文的句柄,在模板中已经定义过;
第二、第三个参数是目标显示位置的坐标,即文本矩形的左上角,默认单位像素点;
第四个参数与前二个函数的第一参数一样;
第五个参数使用上一个函数第四个参数的内容,为目标字符串的实际长度。
输入到下一行:
使用GetTextMetrics:
BOOL GetTextMetrics
(
HDC hdc,
LPTEXTMETRIC lptm
);
为此需要定义一个
TEXTMETRIC的结构:
typedef struct tagTEXTMETRICA {
LONG tmHeight;
LONG tmAscent;
LONG tmInternalLeading;
LONG tmExternalLeading;
LONG tmAveCharWidth;
LONG tmMaxCharWidth;
LONG tmWeight;
LONG tmOverhang;
LONG tmDigitizedAspectX;
LONG tmDigitizedAspectY;
BYTE tmFirstChar;
BYTE tmLastChar;
BYTE tmDefaultChar;
BYTE tmBreakChar;
BYTE tmItalic;
BYTE tmUnderlined;
BYTE tmStruckOut;
BYTE tmPitchAndFamily;
BYTE tmCharSet;
} TEXTMETRICA, *PTEXTMETRICA, *NPTEXTMETRICA, *LPTEXTMETRICA;
Windows字符结构:
因此tmHeight + tmExternalLeading就是两行文本基准点的高度差。
一个例子:
#include<Windows.h>
#include<strsafe.h>
const int STRSIZE = 16;
const int X = 0;
const int Y = 0;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdshow, int iCmdshow)
{
……
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
int xstr = X;
int ystr = X;
TCHAR szstr[STRSIZE];
size_t strsize;
TEXTMETRIC tm;
static int cxchar;
static int cychar;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxchar = tm.tmAveCharWidth;
cychar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
StringCchPrintf(szstr, STRSIZE, TEXT("%s: %u"), TEXT("Output"), 1);
StringCchLength(szstr, STRSIZE, &strsize);
TextOut(hdc, xstr, ystr, szstr, strsize);
StringCchPrintf(szstr, STRSIZE, TEXT("%s: %u"), TEXT("Output"), 2);
StringCchLength(szstr, STRSIZE, &strsize);
TextOut(hdc, xstr, ystr + cychar, szstr, strsize);
EndPaint(hwnd, &ps);
return 0;
……
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
}