Win32API文本处理

工程模板: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字符结构:

Win32API文本处理

因此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);
	}
}

  

上一篇:WIN32API获取进程句柄的2种方式


下一篇:运行Scrapy程序时出现No module named win32api问题的解决思路和方法