前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【专业技术】Win32 SDK编程:我们如何输出文本

【专业技术】Win32 SDK编程:我们如何输出文本

作者头像
程序员互动联盟
发布2018-03-12 16:55:42
1.9K0
发布2018-03-12 16:55:42
举报

在使用Win32编程时,我们常常需要输出文本到窗口上,Windows所有的文本字符或者图形输出都是通过图形设备接口(GDI)进行的,Windows的三大组件之一的GDI32.dll封装了所有的文本和图像输出函数。你也许会说直接用printf不就可以了吗?不错,这个确实是可以输出文本,但是这个智能用于console下的文本输出,而不能用于直接在窗口上面。要在窗口上输出文本,以下的函数都可以实现:

DrawText、DrawTextExt、ExtTextOut以及TextOut,这些函数基本都有相似的参数,比如hdc,坐标位置,字符串。下面以最常用的TextOut为例来说明如何在Windows窗口中如何输出文本,其他请查看MSDN的用法。TextOut的函数原型如下:

BOOL TextOut( HDC hdc, // handle to DC

intnXStart, // x-coordinate ofstarting position

intnYStart, // y-coordinate ofstarting position

LPCTSTRlpString, // character string

intcbString // number of characters

);

参数说明:

Hdc,设备上下文句柄,所有的窗口都会有这个句柄,最后的文本将在上面输出。

nXStart,字符串输出的开始横坐标。

nYStart,字符串输出的开始纵坐标。

lpString,要输出的字符串。

cbString,要输出的字符数目,注意是字符数而不是字节数。

在windows窗口上输出有两种方式来获取设备上下文句柄,一种是在处理WM_PAINT消息时通过BeginPaint函数获取,另外一种就是通过主动获取上下文句柄函数GetDC或者GetWindowDC,这种可以在任何时候进行输出,但是一旦窗口有更新,必须想办法重新绘制,否则就会消失了。而通过WM_PAINT绘制的文本会在窗口有更新时自动调用,因此不用担心什么时候需要重绘的问题,Windows会在以下的情况下受到WM_PAINT消息:

  • 用户移动一个窗口,导致原来被盖住的部分窗口显示出来。
  • 用户调整窗口的大小,并且窗口风格类型设置为CS_HREDRAW和CS_VREDRAW。
  • 程序调用ScrollWindow或者ScrollDC函数滚动客户区。
  • 程序调用InvalidateRect或者InvalidateRgn函数,该函数显示生产一条WM_PAINT消息。

使用WM_PAINT还有一个好处,就是windows会自己计算哪些区域需要更新,也就是说只有真正变化的地方才会更新,这样更新的代价会降低到最小。

下面的实例中,我们用了这两种方式获取设备上下文句柄来输出文本:

#include <windows.h>

staticTCHAR szAppName[] = TEXT("HelloWin32");

staticLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

intWINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{

HWND hWnd;

MSG msg;

WNDCLASS wndclass;

// 注册窗口类

wndclass.style =CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc;

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance =hInstance;

wndclass.hIcon =LoadIcon(NULL, IDI_APPLICATION);

wndclass.hCursor =LoadCursor(NULL, IDC_ARROW);

wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

wndclass.lpszMenuName = NULL;

wndclass.lpszClassName = szAppName;

if (!RegisterClass(&wndclass))

{

MessageBox (NULL, TEXT("This programrequires Windows NT!"), szAppName, MB_ICONERROR);

return 0;

}

//创建主窗体

hWnd = CreateWindow(szAppName, //window class name

TEXT("TextOut demo"), // window caption

WS_OVERLAPPEDWINDOW, // window style

CW_USEDEFAULT, //initial x position

CW_USEDEFAULT, //initial y position

400, // initialx size

300, //initial y size

NULL, //parent window handle

NULL, //window menu handle

hInstance, //program instance handle

NULL); //creation parameters

ShowWindow(hWnd, iCmdShow);

UpdateWindow(hWnd);

//进入消息循环

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return msg.wParam;

}

staticLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

HDC hDC;

PAINTSTRUCTps;

static int cxClient,cyClient;

switch (message)

{

case WM_CREATE:

return 0;

case WM_SIZE:

cxClient= LOWORD(lParam);

cyClient= HIWORD(lParam);

return 0;

case WM_PAINT:

hDC= BeginPaint(hWnd, &ps);

//使用BeginPaint函数返回的句柄

TextOut(hDC,50, 50, TEXT("Hello, World!"),13);

EndPaint(hWnd,&ps);

return 0;

case WM_LBUTTONDOWN:

{

//点击鼠标左键后也执行文本输出

HDChDC = GetDC(hWnd);

//设置文本颜色

SetTextColor(hDC,RGB(0, 0xFF, 0));

//设置文本背景颜色

SetBkColor(hDC,RGB(0xFF, 0, 0));

//使用GetDC函数返回的句柄

TextOut(hDC,50, 100, TEXT("This is a test!"),15);

}

return 0;

case WM_DESTROY:

PostQuitMessage(0);

return 0 ;

}

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

}

程序运行,点击鼠标左键后效果如下:

然后我们用鼠标改变窗口大小后,可以看见直接用GetDC获取设备上下文句柄画出来的文本消失了,而在处理WM_PAINT消息时通过BeginPaint函数获取设备上下文画出来的文本依然存在。

至于用DrawText、DrawTextExt、ExtTextOut这几个函数输出文本大同小异,前面两个都增加了矩形的限制。详细用法请自己参考MSDN,通过本例,您应该学会如何输出文本了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2015-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员互动联盟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档