Windows API-GDI入门基础知识详解
2008-03-08 21:38:48 来源:WEB开发网 【

核心提示:什么是GDI?GDI是Graphics Device Interface的缩写,含义是图形设备接口,Windows API-GDI入门基础知识详解,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出,这就证实了窗口的覆盖会造成无效矩形的出现,系统将会发送WM_PAINT消息,
什么是GDI? GDI是Graphics Device Interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
设备描述表是GDI内部保存数据的一种数据结构,此结构中的属性内容与特定的输出设备(显示器,打印机等)相关,属性定义了GDI函数的工作细节,在稍后我们将看到如何使用TextOut函数输出文字,在这里属性确定了文字的颜色,x坐标和y坐标映射到窗口显示区域的方式等。 设备描述表句柄一旦获得,那么系统将使用默认的属性值填充设备描述表结构。 假如有必要,我们可以使用一些GDI函数获取和改变设备描述表中的属性值。什么是有效矩形什么是无效矩形? 当应用程序接受到WM_PAINT消息后通常就预备更新正个显示区域,但是通常只需要更新一个比较小的区域而不是整个区域,这种情况通常出现在当应用程序的主窗口的一部分被一个对话框覆盖,需要重画的只是被覆盖的矩形区域(见下图)。


HWND hwnd,, // handle to window
LPPAINTSTRUCT pPaint // paint information
);
BOOL EndPaint(
HWND hWnd, // handle to window
CONST PAINTSTRUCT *pPaint // paint data
); 从上面BeginPaint函数的原形中我们可以看到需要一个PAINTSTRUCT结构对象的内存地址,PAINTSTRUCT结构包含在WinUser.h头文件中。 定义如下:typedef struct tagPAINTSTRUCT {
HDC hdc; //设备描述表句柄
BOOL fErase; //擦除状态
RECT rcPaint; //无效矩形座标
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
}
PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT; 事实上当程序调用BeginPaint函数的时候,Windows会自动的填写此结构的各个属性,而程序作者只需要关心前三个属性。 第一个属性hdc表示当前的设备描述表句柄。 第二个属性fErase来说,多数情况下它是被标记成FALSE(0)的,这表示Windows已经擦除了无效矩形的背景,这个擦除动作是是在BeginPaint函数中发生的,而擦除背景用的画刷则是WNDCLASS结构中的hbrBackground属性指定的画刷来擦除背景的,在很多情况下可能程序作者想自己定义一些插除行为,那么可以通过响应消息队列中的WM_ERASEBKGND消息来完成。 第三个属性rcPaint则表示无效矩形座标,它定义了无效矩形的边界。 RECT结构可以在WinDef.h头文件中找到。 定义如下:typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT; 注重,我们在前面提到了InvalidateRect函数,并已经清楚了调用它可以让窗口显示区域内的矩形变为无效,那么我们就可以在处理WM_PAINT消息的时候通过调用它实现在无效矩形外绘图,该调用是在调用BegingPaint函数之前调用的。 使用方法:InvalidateRect(hwnd,NULL,TRUE); 通过上面代码的调用我们让整个显示区域变为了无效,并擦除背景,要注重的是,最后一个参数假如为FALSE,则不擦除背景,原有的东西将保留在原处,这通常是在接受到WM_PAINT消息的时候而不考虑rcPaint属性的情况下简单的重绘整个显示区域最方便的方法,例如,在显示区域内我们输出了一个图形,这个图形的一小部分落在了无效矩形区域内,而这就让绘制这个图形的无效部分变的没有意义,这时就需要重绘整个图形,因为在调用BeginPaint函数传回设备描述表句柄的时候,Windows不会绘制rcPaint也就是无效矩形以外的任何部分。 对于InvalidateRect函数的具体举例,我们将在以后的章节中看到。

HWND hWnd // handle to window
);
int ReleaseDC(
HWND hWnd, // handle to window
HDC hDC // handle to DC
); 两种方法的区别: <1> 使用BeginPaint函数获得的的操作区域是显示区域中的无效矩形区域,接下来绘图操作只能在窗口的无效区域范围内进行,无效区域以外的区域将被忽略不能进行操作,而GetDC函数获得的操作区域则是整个窗口的显示区域,之后的操作可以在任何部分进行,而不只限制在无效区域。 <2> BeginPaint函数会自动把无效区域变成有效的区域,而GetDC函数则不会将任何无效区域变得有效,必须强行调用ValidateRect函数,并把第二个参数设置为NULL来完成。 最后我们给出一个可执行程序的例子,当应用程序执行的时候会有一个对话框出现,当你拉动这个对话框的时候又会出现同样的另一个对话框,这就证实了窗口的覆盖会造成无效矩形的出现,系统将会发送WM_PAINT消息。 未完待续……

更多精彩
赞助商链接