这章的内容比繁琐,需要多用练习才能较熟练的掌握。
第二章 输出文字
/****************************************/
WM_PAINT消息
发生以下事件时窗口消息处理程序会接收到一个WM_PAINT消息:
1. 当移动窗口时,窗口中先前被隐藏的区域重新可见
2. 使用者改变窗口的大小,WM_SIZE
3. 程序使用ScrollWindow 或ScrollDC函数滚动显示区域的一部分。
4. 程序使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息。
有时候Windows保存他所覆盖的显示区域,然后回复他,有以下情况:
1. 鼠标传越过的区域
2. 图标推过显示区域
有效矩形和无效矩形
Windows每次绘图时是针对某个区域来进行的,这个区域就是无效区域。
Windows内部为每个窗口保存一个PaintStruct,这个结构中包含了包围无效区域的最小矩形,当又有一个无效矩形产生时,windows则会合并所有的无效矩形,计算出新的无效矩形,再将WM_PAINT放入消息队列中。
我们可以用InvalidateRect来使显示区域内的矩形变为无效,而用ValidateRect是显示区域内的任意矩形区域变为有效,这样会把当前消息队列中的所有WM_PAINT消息都删除。
/***********************************************/
GDI(图形设备接口)
最简单最普遍的文字输出函数是TextOut,TextOut(hdc,x,y,psText,iLength);
如果程序需要使用设备,就先必须得到该设备的句柄,有两种方法来得到设备的句柄,
1. hdc = BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps);
2. hdc = GetDC(hwnd); ReleaseDC(hdc);
以上两种方法中的函数必须成对出现,否则会出现不可预知的错误。
这种方法的比较,第一种常在wm_paint消息中使用,而且只能在ps定义的区域内绘图,而第二种方法却要灵活的多,可以在ps以外的任意处绘图,所以使用的更加方便。
我们知道,WM_PAINT消息处理是,BeginPaint之后,程序是对ps定义的无效区域来绘图的,也就是说,我们可以通过改变ps结构来改变程序的无效区域。
/**************************************************/
下面是一个非常重要的函数:
Invalidate(hwnd,&rect,bool);
这个函数可以是rect的区域变为无效区域,第二个参数为NULL时,是对整个程序的区域作用,第三个参数很重要,当bool=TRUE时,windows会使rect区域无效,并擦除背景,当bool=FALSE时,windows会使rect无效,但不会擦出背景,原有的东西将保留在原处。
比如说,画一个圆,另一个窗口覆盖了这个圆的一部分,而后又移开。当bool=TRUE时,程序会擦除背景,重新绘出此圆,当bool=FALSE,程序不会擦出背景,保留未被覆盖的圆的那一部分,而被覆盖的那部分则会显示为背景色。
所以说灵活使用这个函数可以为我们的程序提供许多方便。
/****************************************************/
TextOut(hdc,x,y,psText,iLength);
非常普遍的一个输出字体函数,参数不用说明,一看就知道。函数可以这样使用:
TextOut(hdc,10,20,TEXT(“hello windows”),40);
这种输出格式十分不灵活,如果循环输出递加的i值怎么办?我们可以用下面的方法:
int iLength;
TCHAR str[MAXN];
for( int i = 0;i < cyClient/text_high; ++i) {
iLength = wsprintf(str,TEXT("here is the number of %d"),i);
TextOut(hdc,0,text_high*i,str,iLength);
}
其中wsprintf就像C中的printf一样,提供格式化字符串,功能异常强大,类似的还有函数sprintf,与wsprintf类似,不过有些不同,具体细节还徐有待学习,sprintf针对ASCII,而wsprintf针对unicode。
/*********************************************/
TEXTMETRIC
typedef struct tagTEXTMETRIC
{
LONG tmHeight ;
LONG tmAscent ;
LONG tmDescent ;
LONG tmInternalLeading ;
LONG tmExternalLeading ;
LONG tmAveCharWidth ;
LONG tmMaxCharWidth ;
其它结构字段
}
如果程序中控制字体输出,那么必须知道字体的信息,使用GetTextMetrics(hdc,&tm)来获得信息,个字段信息如下:
然后就可以结合TextOut来得到windows的基本字符处理输出的能力,效果如下(简陋啊):