《Windows程序设计》读书笔四 文本输出

客户区是指整个应用程序窗口中没有被标题栏,边框,菜单栏,工具栏,状态栏和滚动条占用的区域。就是窗口中程序可以在上面绘制并向用户传达可视化信息的区域


4.1 绘制和重绘

windows是一个消息驱动的系统,他使用两种方式把事件通知给应用程序。1)把消息放在应用程序消息队列中2)或者适当向窗口过程发送消息。

4.1.1 WM_PAINT消息

在进入消息循环之前调用UpdateWindow函数,向窗口过程发送最初的WM_PAINT消息,通知窗口过程绘制客户区。

以下事件都可能导致窗口收到WM_PAINT消息:

* 用户移动一个窗口,导致原来被遮盖的部分窗口暴露出来。

* 用户调整窗口的大小(当窗口类型设定为CS_HREDRAW 和 CS_VREDRAW)

* 程序调用ScrollWindow或ScrollDC函数滚动客户区

* InvalidateRect 或InvalidateRgn函数显示生成WM_PAINT消息


某些情况下windows会试图保持被覆盖的客户区一遍恢复时使用,但并非每次都成功。以下情形windows有时会发送一条WM_PAINT消息

* Windows 关闭一个覆盖了部分窗口的对话框或消息

* 下拉菜单被拉下然后收回

* 显示提示信息

少数情况下windows总会保存被覆盖区的显示内容

* 鼠标指针在客户区内移动

* 在客户区内拖动图标


4.1.2 有效矩形和无效矩形

需要重新绘制的区域称为“无效区域”,导致windows在消息队列中放置一条WM_PAINT消息,并更新一个“绘制信息结构”,保持着无效区域的矩形。当收到WM_PAINT消息的时候可以使用GetUpdateRect来获得无效矩形的坐标。

在BeginPaint函数以后,整个客户区会变成有效。也可以调用ValidateRect是客户区中任意矩形变得有效,如果该函数让整个无效区都变得有效,那么当前消息队列中的WM_PAINT消息就会被删除。


4.2 GDI简介

最常用的字符输出函数是TextOut

TextOut(hdc, x, y, psText, iLength);

4.2.1 设备环境Device context

设备环境是GDI内部维护的一种数据结构,与特定的显示设备相关联(显示器或打印机)

设备环境中的某些值是图形“属性”,这些属性决定了GDI绘图函数的工作细节。例如在TextOut函数中,设备环境的属性决定着文本颜色,背景颜色。

GDI函数可以改变设备环境的默认属性,也可以获得当前值,还有一些GDI函数可以让你在窗口区绘图。

在绘图完成以后,必须释放设备环境

4.2.2 获取设备环境的方法:方法一

在WM_PAINT消息时 BeginPaint 获取

4.2.3 绘制信息结构

调用BeginPaint函数windows自动填充该结构

typedef struct tagPAINTSTRUCT {
    HDC         hdc;
    BOOL        fErase;
    RECT        rcPaint;
    BOOL        fRestore;
    BOOL        fIncUpdate;
    BYTE        rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;

fErase 设为false, 表明在先前BeginPaint函数已经擦除了无效区域。

使用InvalidateRect是客户区矩形无效时,最后一个参数指定背景是否要擦除,fasle windows不会擦除背景

InvalidateRect(hwnd, NULL, TRUE); 是整个客户区无效化,其后调用BeginPaint会擦除原有背景。 设为false会保留原有背景

4.2.4 获取设备环境句柄:方法二

有些时候在非WM_PAINT消息也需要绘制客户区。

hdc = GetDC(hwnd);

Release(hwnd, hdc);  两者成对出现,不要夸消息。

GetDC获取的是整个客户区,不会使无效矩形有效化。如果要是整个客户区有效化,使用

ValidateRect(hwnd, NULL) 函数

通常用户处理键盘鼠标消息,而不用使用BeginPaint使客户区无效化。

GetWindowDC 获取窗口的设备环境句柄。也要处理非客户区绘制  WM_NCPAINT


4.2.5 TextOut函数详解

TextOut(hdc, x, y, psText, iLength);

hdc 设备环境,通过BeginPaint 或者GetDC获得, 默认有一系列字体属性

psText 显示文本的指针,

iLength 文本长度

x,y 逻辑坐标

windows将不会显示字符串落在剪裁区域以外的部分。


4.2.6 系统字体

设备环境定义了在调用TextOut时候的Windows使用的字体,默认系统字体(SYSTEM_FONT)

4.2.7 字符大小

GetSystemMetrics 获取用户界面的尺寸,

GetTextMetrics 获取字体尺寸,返回当前设备环境中选中字体的信息。

typedef struct tagTEXTMETRICW
{
    LONG        tmHeight;
    LONG        tmAscent;
    LONG        tmDescent;
    LONG        tmInternalLeading;
    LONG        tmExternalLeading;
    LONG        tmAveCharWidth;
    LONG        tmMaxCharWidth;
    LONG        tmWeight;
    LONG        tmOverhang;
    LONG        tmDigitizedAspectX;
    LONG        tmDigitizedAspectY;
    WCHAR       tmFirstChar;
    WCHAR       tmLastChar;
    WCHAR       tmDefaultChar;
    WCHAR       tmBreakChar;
    BYTE        tmItalic;
    BYTE        tmUnderlined;
    BYTE        tmStruckOut;
    BYTE        tmPitchAndFamily;
    BYTE        tmCharSet;
} TEXTMETRICW, *PTEXTMETRICW, NEAR *NPTEXTMETRICW, FAR *LPTEXTMETRICW;
默认映射模式是MM_TEXT 所以以像素为单位

获取字符相关信息

TEXTMETRIC tm

hdc = GetDC(hwnd);

GetTextMetrics(hdc, &tm);

ReleaseDC(hwnd, hdc);


4.2.8 文本尺寸的度量

TEXTMETRIC 结构中有设备环境中当前字体的各种信息。

tmHeight  是tmAscent(基线之上)和tmDescent(基线之下)之和

tmInternalLeading(内部间距)


tmExternalLeading 字体设计者建议在两行文字间流出的空间大小。

tmAveCharWidth 小写字符的加权平均宽度,

tmMaxCharWidth 字体中最宽的字符的宽度

不要猜测字体尺寸,不用使用固定值,应该通过GetTextMetrics函数来获得信息。


4.2.9 文本格式化

在WM_CREATE消息时调用一次GetTextMetrics函数

case WM_CREATE:
    hdc = getDC(hwnd);
    GetTextMetrics(hdc, &tm);
    cxChar = tm.tmAveCharWidth;
    cyChar = tm.tmHeight + tm.tmExternalLeading;
    ReleaseDC(hwnd, hdc);
    return 0;

一个wsprintf 和TextOut组合的例子

int iLength;
TCHAR szBuffer[40];
iLength = wsprintf(szBuffer, TEXT("The sum of %i and %i is %i"), iA, iB, iA + iB);
TextOut(HDC, x, y, szBuffer, iLength);

也可以合并成一句

TextOut(hdc, x, y, szBuffer,
	wsprintf(szBuffer, TEXT("The sum of %i and %i is %i"), iA, iB, iA + iB));

4.2.10 综合使用

GetSystemMetrics 获得windows中各种图形项(图标,鼠标指针,标题栏和滚动条)的尺寸信息。也称为“索引”参数。

一个使用GetSystemMetrics函数获取系统信息的例子

sysmets.h

#define NUMLINES ((int)(sizeof sysmetrics / sizeof sysmetrics[0]))

struct 
{
	int		iIndex;
	TCHAR*	szLabel;
	TCHAR*	szDesc;
}

sysmetrics[] =
{
	SM_CXSCREEN, TEXT("SM_CXSCREEN"),
	TEXT("Screen width in pixels"),
	SM_CYSCREEN, TEXT("SM_CYSCREEN"),
	TEXT("Screen height in pixels"),
	SM_CXVSCROLL, TEXT("SM_CXVSCROLL"),
	TEXT("Vertical scroll width"),
	SM
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值