使用 GDI 函数
本文讲述 MiniGUI 中 GDI 函数及其使用。主要包括:设备上下文的概念、获取和释放;矩形操作和区域操作;基本绘图函数;位图操作函数;逻辑字体操作函数等。
1 引言
GUI 系统的一个重要组成部分就是 GDI,即图形设备接口(Graphics Device Interface)。通过 GDI,GUI 程序就可以在计算机屏幕上,或者其他的显示设备上进行图形输出,包括基本绘图和文本输出。本文将详细描述 MiniGUI 中的 GDI 函数,并举例说明重要函数的用法。其中包括:DC 的概念、获取和释放;矩形操作和剪切域操作;基本绘图函数;位图操作函数;逻辑字体操作函数等。
2 图形设备上下文
在 MiniGUI 中,采用了在 Windows 和 X Window 中普遍采用的图形设备概念。每个图形设备定义了计算机显示屏幕上的一个矩形输出区域。在调用图形输出函数时,均要求指定经初始化的图形设备上下文(Device Context,DC),也称作"设备环境"。从程序员的角度看,一个经过初始化的图形设备上下文确定了其后进行图形输出的一些基本属性,并一直保持这些属性,直到被改变为止。这些属性包括:输出的线条颜色、填充颜色、字体颜色、字体形状等等。而从 GUI 系统角度来讲,一个图形设备上下文所代表的含义就要复杂得多,它起码应该包含如下内容:
该设备上下文本所在设备信息(显示模式、色彩深度、显存布局等等);
该设备上下文所代表的窗口以及该窗口被其他窗口剪切的信息(在 MiniGUI 中,称作"全局剪切域");
该设备上下文的基本操作函数(点、直线、多边形、填充、块操作等),及其上下文信息;
由程序设定的局部信息(绘图属性、映射关系和局部剪切域等)。
所以,从程序员的角度看来,他所关心的仅仅是设备上下文本身的一小部分东西。
2.1 设备上下文的获取和释放
在 MiniGUI 中,所有绘图相关的函数均需要有一个设备上下文。设备上下文可通过 GetClientDC 和 ReleaseDC 获取和释放。由 GetDC 所获取的设备上下文是针对整个窗口的,而 GetClientDC 所获取的设备上下文是针对窗口客户区,也就是说,前一个函数获得的设备上下文,其坐标原点位于窗口左上角,输出被限定在窗口范围之内;后一个函数获得的设备上下文,其坐标原点位于窗口客户区左上角,输出被限定在窗口客户区范围之内。下面是这三个函数的原型说明(include/gdi.h):
398 HDC GUIAPI GetDC (HWND hwnd);
399 HDC GUIAPI GetClientDC (HWND hwnd);
400 void GUIAPI ReleaseDC (HDC hdc);
GetDC 和 GetClientDC 是从系统预留的若干个 DC 当中获得一个目前尚未使用的设备上下文。所以,应该注意如下两点:
在使用完成一个由 GetDC 返回的设备上下文之后,应该尽快调用 ReleaseDC 释放。
避免同时使用多个设备上下文,并避免在递归函数中调用 GetDC 和 GetClientDC。
为了方便程序编写,提高绘图效率,MiniGUI 还提供了建立私有设备上下文的函数,所建立的设备上下文在整个窗口生存期内有效,从而免除了获取和释放的过程。这些函数的原型如下:
403 HDC GUIAPI CreatePrivateDC (HWND hwnd);
404 HDC GUIAPI CreatePrivateClientDC (HWND hwnd);
405 HDC GUIAPI GetPrivateClientDC (HWND hwnd);
406 void GUIAPI DeletePrivateDC (HDC hdc);
在建立主窗口时,如果主窗口的扩展风格中指定了 WS_EX_USEPRIVATEDC 风格,则 CreateMainWindow 函数会自动为该窗口的客户区建立私有设备上下文。通过 GetPrivateClientDC 函数,可以获得该设备上下文。对控件而言,如果控件类具有 CS_OWNDC 属性,则所有属于该控件类的控件将自动建立私有设备上下文。DeletePrivateDC 函数用来删除私有设备上下文。对上述两种情况,系统将在销毁窗口时自动调用 DeletePrivateDC 函数。
另外一个获取和释放设备上下文的方法是通过 BeginPaint 和 EndPaint 函数。这两个函数只能在处理 MSG_PAINT 的消息中调用。MiniGUI 在 BeginPaint 函数中通过 GetClientDC 获取客户区设备上下文,然后将窗口当前的无效区域选择到窗口的剪切区域中;而 EndPaint 函数则清空窗口的无效区域,并释放设备上下文。这两个函数的原型如下(include/window.h):
623 HDC GUIA欢迎光临学网,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
$False$
PI BeginPaint(HWND hWnd);
624 void GUIAPI EndPaint(HWND hWnd, HDC hdc);
因为 BeginPaint 函数将窗口的无效区域选择到了设备上下文中,所以,可以通过一些必要的优化来提高 MSG_PAINT 消息的处理效率。比如,某个程序要在窗口客户区中填充若干矩形,就可以在 MSG_PAINT 函数中如下处理:
MSG_PAINT:
{
HDC hdc = BeginPaint (hWnd);
for (j = 0; j < 10; j ) {
if (RectVisible (hdc, rcs j)) {
FillBox (hdc, rcs.left, rcs.top, rcs .right, rcs .bottom);
}
}
EndPaint (hWnd, hdc);
return 0;
}
这样可以避免不必要的重绘操作,从而提高绘图效率。
2.2 系统内存中的设备上下文
MiniGUI 也提供了内存设备上下文的创建和销毁函数。利用内存设备上下文,可以在系统内存中建立一个类似显示内存的区域,然后在该区域中进行绘图操作,结束后再复制到显示内存中。这种绘图方法有许多好处,比如速度很快,减少直接操作显存造成的闪烁现象等等。不过,目前 MiniGUI 中只能建立和显示内存,也就是物理设备上下文一样的内存设备上下文。用来建立和销毁内存设备上下文的函数原型如下(include/gdi.h):
401 HDC GUIAPI CreateCompatibleDC (HDC hdc);
402 void GUIAPI DeleteCompatibleDC (HDC hdc);
2.3 屏幕设备上下文
MiniGUI 在启动之后,就建立了一个全局的屏幕设备上下文。该 DC 是针对整个屏幕的,并且没有任何预先定义的剪切域。在某些应用程序中,可以直接使用该设备上下文进行绘图,将大大提高绘图效率。在 MiniGUI 中,屏幕设备上下文用 HDC_SCREEN 标识,不需要进行任何获取和释放操作。
2.4 映射模式
一个设备上下文被初始化之后,其坐标系原点通常是输出矩形的左上角,而 x 轴水平向左,y 轴垂直向下,并以象素为单位。这种坐标的映射模式标识为 MM_TEXT。MiniGUI 提供了一套函数,可以改变这种映射方式,包括对默认坐标系进行偏移、缩放等操作。这些函数的原型如下(include/gdi.h):
453 int GUIAPI GetMapMode (HDC hdc);
454 void GUIAPI GetViewportExt (HDC hdc, POINT* pPt);
455 void GUIAPI GetViewportOrg (HDC hdc, POINT* pPt);
456 void GUIAPI GetWindowExt (HDC hdc, POINT* pPt);
457 void GUIAPI GetWindowOrg (HDC hdc, POINT* pPt);
458 void GUIAPI SetMapMode (HDC hdc, int mapmode);
459 void GUIAPI SetViewportExt (HDC hdc, POINT* pPt);
460 void GUIAPI SetViewportOrg (HDC hdc, POINT* pPt);
461 void GUIAPI SetWindowExt (HDC hdc, POINT* pPt);
462 void GUIAPI SetWindowOrg (HDC hdc, POINT* pPt);
GetMapMode 函数返回当前的映射模式,若不是 MM_TEXT 模式,则返回MM_ANISOTROPIC。SetMapMode 函数设置映射模式,MiniGUI 目前只支持两种映射模式,即MM_ANISOTROPIC 和 MM_TEXT。Get 函数组用来返回映射模式信息,包括偏移量、缩放比例等等,而 Set 函数组用来设置相应的映射信息。
通常情况下,MiniGUI 的 GDI 函数所指定的坐标参数称为"逻辑坐标",在绘制之前,首先要转化成"设备坐标"。当使用 MM_TEXT 映射模式时,逻辑坐标和设备坐标是等价的。LPtoDP 函数用来完成逻辑坐标到设备坐标的转换,DPtoLP 函数用来完成从设备坐标到逻辑坐标的转换。逻辑坐标和设备坐标的关系可从 LPtoDP 函数中看到(src/gdi/coor.c):
61 void GUIAPI LPtoDP(HDC hdc,欢迎光临学网,点击这里查看更多文章教程 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
POINT* pPt)
62 {
63 PDC pdc;
64
65 pdc = dc_HDC2PDC(hdc);
66
67 if (pdc->mapmode != MM_TEXT) {
68 pPt->x = (pPt->x - pdc->WindowOrig.x)
69 * pdc->ViewExtent.x / pdc->WindowExtent.x
70 pdc->ViewOrig.x;
71
72 pPt->y = (pPt->y - pdc->WindowOrig.y)
73 * pdc->ViewExtent.y / pdc->WindowExtent.y
74 pdc->ViewOrig.y;
75 }
76 }
77
另外,LPtoSP 函数和 SPtoLP 函数完成逻辑坐标和屏幕坐标之间的转换。
3 矩形操作和区域操作
3.1 矩形操作
在 MiniGUI 中,矩形是如下定义的(include/common.h):
120 typedef struct tagRECT
121 {
122 int left;
123 int top;
124 int right;
125 int bottom;
126 } RECT;
127 typedef RECT* PRECT;
128 typedef RECT* LPRECT;
简而言之,矩形就是用来表示屏幕上一个矩形区域的数据结构,定义了矩形左上角的 x, y 坐标(left 和 top)以及右下角的 x, y 坐标(right 和 bottom)。需要注意的是,MiniGUI 中的矩形,其右侧的边和下面的边是不属于该矩形的。例如,要表示屏幕上的一条扫描线,应该用
RECT
rc = {x, y, x w 1, y 1};
表示。其中 x 是扫描线的起点,y 是扫描线的垂直位置,w 是扫描线宽度。
MiniGUI 提供了一组函数,可对 RECT 对象进行操作:
SetRect 对 RECT 对象的各个分量进行赋值;
SetRectEmpty 将 RECT 对象设置为空。MiniGUI 中的空矩形定义为高度或宽度为零的矩形;
IsRectEmpty 判断给定 RECT 对象是否为空。
NormalizeRect 对给定矩形进行正规化处理。MiniGUI 中的矩形,应该满足(right > left 并且 bottom > top)的条件。满足这一条件的矩形又称"正规化矩形",该函数可以对任意矩形进行正规化处理。
CopyRect 复制矩形;
EqualRect 判断两个 RECT 对象是否相等,即两个 RECT 对象的各个分量相等;
IntersectRect 该函数求两个 RECT 对象之交集。若两个矩形根本不相交,则函数返回 FALSE,且结果矩形未定义;否则返回交矩形。
DoesIntersec 该函数仅仅判断两个矩形是否相交。
IsCovered 该函数判断 RECT 对象 A 是否全部覆盖 RECT 对象 B,即 RECT B 是 RECT A 的真子集。
UnionRect 该函数求两个矩形之并。如果两个矩形根本无法相并,则返回 FALSE。两个相并之后的矩形,其中所包含的任意点,应该属于两个相并矩形之一。
GetBoundRect 该函数求两个矩形的外包最小矩形。
SubstractRect 该函数从一个矩形中减去另外一个矩形。注意,两个矩形相减的结果可能生成 4 个不相交的矩形。该函数将返回结果矩形的个数以及差矩形。详细信息可参见"MiniGUI 体系结构之二――多窗口管理和控件及控件类"一文。
OffsetRect 该函数对给定的 RECT 对象进行平移处理。
InflateRect 该函数对给定的 RECT 对象进行膨胀处理。注意膨胀之后的矩形宽度和高度是给定膨胀值的两倍。
InflateRectToPt 该函数将给定的 RECT 对象膨胀到指定的点。
PtInRect 该函数判断给定的点是否位于指定的 RECT 对象中。
3.2 区域操作
在 MiniGUI 中,区域定义为互不相交矩形的集合,在内部用链表形式表示。MiniGUI 的区域可以用来表示窗口的剪切域、无效区域、可见区域等等。文章整理:学网 http://www.xue5.com (本站) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
在 MiniGUI 中,区域和剪切域的定义是一样的,剪切域定义如下(include/gdi.h):
76 // Clip Rect
77 typedef struct tagCLIPRECT
78 {
79 RECT rc;
80 struct tagCLIPRECT* next;
81 }CLIPRECT;
82 typedef CLIPRECT* PCLIPRECT;
83
84 // Clip Region
85 typedef struct tagCLIPRGN
86 {
87 RECT rcBound; // bound rect of clip region
88 PCLIPRECT head; // clip rect list head
89 PCLIPRECT tail; // clip rect list tail
90 PBLOCKHEAP heap; // heap of clip rect
91 } CLIPRGN;
92 typedef CLIPRGN* PCLIPRGN;
每个剪切域对象有一个 BLOCKHEAP 成员。该成员是剪切域分配 RECT 对象的私有堆。在使用一个剪切域对象之前,首先应该建立一个 BLOCKHEAP 对象,并对剪切域对象进行初始化。如下所示:
static BLOCKHEAP sg_MyFreeClipRectList;
...
CLIPRGN my_region
InitFreeClipRectList (&sg_MyFreeClipRectList, 20);
InitClipRgn (&my_regioni, &sg_MyFreeClipRectList);
在实际使用当中,多个剪切域可以共享同一个 BLOCKHEAP 对象。
在初始化剪切域对象之后,可以对剪切域进行如下操作:
SetClipRgn 该函数将剪切域设置为仅包含一个矩形的剪切域;
ClipRgnCopy 该函数复制剪切域;
ClipRgnIntersect 该函数求两个剪切域的交集;
GetClipRgnBoundRect 该函数求剪切域的外包最小矩形;
IsEmptyClipRgn 该函数判断剪切域是否为空,即是否包含剪切矩形;
EmptyClipRgn 该函数释放剪切域中的剪切矩形,并清空剪切域;
AddClipRect 该函数将一个剪切矩形追加到剪切域中。注意该操作并不判断该剪切域是否和剪切矩形相交。
IntersectClipRect 该函数求剪切区域和给定矩形相交的剪切区域。
SubtractClipRect 该函数从剪切区域中减去指定的矩形。
矩形和区域的运算构成了窗口管理的主要算法,也是高级 GDI 函数的基本算法之一,在 GUI 编程中占有非常重要的地位。
4 基本图形操作
4.1 基本绘图属性
在了解基本绘图函数之前,我们首先了解一下基本绘图属性。在 MiniGUI 的目前版本中,绘图属性比较少,大体包括线条颜色、填充颜色、文本背景模式、文本颜色、TAB 键宽度等等。表 1 给出了这些属性的操作函数。
表 1 基本绘图属性及其操作函数
绘图属性 操作函数 受影响的 GDI 函数
线条颜色 GetPenColor/SetPenColor LineTo、Circle、Rectangle
填充颜色 GetBrushColor/SetBrushColor FillBox
文本背景模式 GetBkMode/SetBkMode TextOut、DrawText
文本颜色 GetTextColor/SetTextColor 同上
TAB 键宽度 GetTabStop/SetTabStop 同上
MiniGUI 目前版本中还定义了刷子和笔的若干函数,这些函数是为将来兼容性而定义的,目前无用。
4.2 基本绘图函数
MiniGUI 中的基本绘图函数为点、线、圆、矩形、调色板操作等基本函数,原型定义如下(include/gdi.h,版本 1.0.06):
433 // Palette support
434 int GUIAPI GetPalette (HDC hdc, int start, int len, gal_color* cmap);
435 int GUIAPI SetPalette (HDC hdc, int start, int len,欢迎光临学网,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
gal_color* cmap);
436 int GUIAPI SetColorfulPalette (HDC hdc);
437
438 // General drawing support
439 void GUIAPI SetPixel (HDC hdc, int x, int y, gal_pixel c);
440 void GUIAPI SetPixelRGB (HDC hdc, int x, int y, int r, int g, int b);
441 gal_pixel GUIAPI GetPixel (HDC hdc, int x, int y);
442 void GUIAPI GetPixelRGB (HDC hdc, int x, int y, int* r, int* g, int* b);
443 gal_pixel GUIAPI RGB2Pixel (HDC hdc, int r, int g, int b);
444
445 void GUIAPI LineTo (HDC hdc, int x, int y);
446 void GUIAPI MoveTo (HDC hdc, int x, int y);
447
448 void GUIAPI Circle (HDC hdc, int x, int y, int r);
449 void GUIAPI Rectangle (HDC hdc, int x0, int y0, int x1, int y1);
这里有两个基本的概念需要明确区分,即象素值和 RGB 值。RGB 是计算机中通过三原色的不同比例表示某种颜色的方法。通常,RGB 中的红、绿、蓝可取 0 ~ 255 当中的任意值,从而可以表示 255x255x255 种不同的颜色。而在显示内存当中,要显示在屏幕上的颜色并不是用 RGB 这种方式表示的,显存当中保存的其实是所有象素的象素值。象素值的范围根据显示模式的不同而变化。在 16 色显示模式下,象素值范围为;而在 256 色模式下,象素值范围为 ;在 16 位色模式下,象素值范围为。通常我们所说显示模式是多少位色,就是指象素的位数。
在 MiniGUI 中,设置某个象素点的颜色,既可以直接使用象素值(SetPixel),也可以间接通过 RGB 值来设置(SetPixelRGB),并且通过 RGB2Pixel 函数,可以将 RGB 值转换为象素值。
调色板是低颜色位数的模式下(比如 256 色或者更少的颜色模式),用来建立有限的象素值和 RGB 对应关系的一个线性表。在 MiniGUI 当中,可以通过 SetPalette和 GetPalette 进行调色板的操作,而SetColorfulePalette 将调色板设置为默认的调色板。一般而言,在更高的颜色位数,比如 15 位色以上,因为象素值范围能够表达的颜色已经非常丰富了,加上存储的关系,就不再使用调色板建立象素值和 RGB 的对应关系,而使用更简单的方法建立 RGB 和实际象素之间的关系,如下所示(src/gal/native/native.h):
174
175
178
179 #define RGB2PIXEL888(r,g,b) 180 (((r) << 16) | ((g) << 8) | (b))
181
182
183 #define RGB2PIXEL565(r,g,b) 184 ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
185
186
187 #define RGB2PIXEL555(r,g,b) 188 ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b)
& 0xf8) >> 3))
189
190
191 #define RGB2PIXEL332(r,g,文章整理:学网 http://www.xue5.com (本站) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
b) 192 (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
RGB2PIXEL888 将 的 RGB 值转换为 24 位色的象素值;而 RGB2PIXEL565 转换为 16 位色的象素值;RGB2PIXEL555 和RGB2PIXEL332 分别转换为 15 位色和 8 位色。
4.3 剪切域操作函数
在利用设备上下文进行绘图时,还可以进行剪切处理。MiniGUI 提供了如下函数完成对指定设备上下文的剪切处理(include/gdi.h):
468 // Clipping support
469 void GUIAPI ExcludeClipRect (HDC hdc, int left, int top,
470 int right, int bottom);
471 void GUIAPI IncludeClipRect (HDC hdc, int left, int top,
472 int right, int bottom);
473 void GUIAPI ClipRectIntersect (HDC hdc, const RECT* prc);
474 void GUIAPI SelectClipRect (HDC hdc, const RECT* prc);
475 void GUIAPI SelectClipRegion (HDC hdc, const CLIPRGN* pRgn);
476 void GUIAPI GetBoundsRect (HDC hdc, RECT* pRect);
477 BOOL GUIAPI PtVisible (HDC hdc, const POINT* pPt);
478 BOOL GUIAPI RectVisible (HDC hdc, const RECT* pRect);
ExcludeClipRect 从设备上下文的当前可见区域中排除给定的矩形区域,设备上下文的可见区域将缩小;IncludeClipRect 向当前设备上下文的可见区域中添加一个矩形区域,设备上下文的可见区域将扩大;ClipRectIntersect 将设备上下文的可见区域设置为已有区域和给定矩形区域的交集;SelectClipRect 将设备上下文的可见区域重置为一个矩形区域;SelectClipRegion 将设备上下文的可见区域设置为一个指定的区域;GetBoundsRect 获取当前可见区域的外包最小矩形;PtVisible 和 RectVisible 用来判断给定的点或者矩形是否可见,即是否全部或部分落在可见区域当中。
5 位图操作函数
在 MiniGUI 的 GDI 函数中,位图操作函数占有非常重要的地位。实际上,许多高级绘图操作函数均建立在位图操作函数之上,比如文本输出函数。MiniGUI 的主要位图操作函数如下所示(include/gdi.h):
495 void GUIAPI FillBox (HDC hdc, int x, int y, int w, int h);
496 void GUIAPI FillBoxWithBitmap (HDC hdc, int x, int y, int w, int h,
497 PBITMAP pBitmap);
498 void GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h,
499 int bw, int bh, PBITMAP pBitmap, int xo, int yo);
500
501 void GUIAPI BitBlt (HDC hsdc, int sx, int sy, int sw, int sh,
502 HDC hddc, int dx, int dy, DWORD dwRop);
503 void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
504 HDC hddc, int dx, int dy, int dw, int dh, DWORD dwRop);
FillBox 用当前填充色填充矩形框;FillBoxWithBitmap 用设备相关位图对象填充矩形框,可以用来扩大或者缩小位图;FillBoxWithBitmapPart 用设备相关位图对象的部分填充矩形框,也可以扩大或缩小位图。BitBlt 函数用来实现两个不同设备上下文之间的显示内存复制。欢迎光临学网,收藏本篇文章 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
StretchBlt 则在 BitBlt 的基础上进行缩放操作。
通过 MiniGUI 的 LoadBitmap 函数,可以将某种位图文件装载为 MiniGUI 设备相关的位图对象,即 BITMAP 对象。设备相关的位图指的是,位图当中包含的是与指定设备上下文的显示模式相匹配的象素值,而不是设备无关的位图信息。MiniGUI 目前可以用来装载BMP 文件、JPG 文件、GIF 文件以及 PCX、TGA 等格式的位图文件,而 LoadMyBitmap 函数则用来将位图文件装载成设备无关的位图对象。在 MiniGUI 中,设备相关的位图对象和设备无关的位图对象分别用 BITMAP 和 MYBITMAP 两种数据结构表示。相关函数的原型如下(include/gdi.h):
666 int GUIAPI LoadMyBitmap (HDC hdc, PMYBITMAP pMyBitmap, RGB* pal, const char* spFileName);
667 int GUIAPI LoadBitmap (HDC hdc, PBITMAP pBitmap, const char* spFileName);
668 #ifdef _SAVE_BITMAP
669 int GUIAPI SaveBitmap (HDC hdc, PBITMAP pBitmap, const char* spFileName);
670 #endif
671 void GUIAPI UnloadBitmap (PBITMAP pBitmap);
672
673 int GUIAPI ExpandMyBitmap (HDC hdc, const MYBITMAP* pMyBitmap, const RGB* pal, PBITMAP pBitmap);
674
675 void GUIAPI ExpandMonoBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
676 BYTE* bitmap, int bg, int fg);
677 void GUIAPI Expand16CBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
678 BYTE* bitmap, const RGB* pal);
679 void GUIAPI Expand256CBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
680 BYTE* bitmap, const RGB* pal);
681 void GUIAPI CompileRGBBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
682 BYTE* bitmap, int rgb_order);
683
684 void GUIAPI ReplaceBitmapColor (HDC hdc, PBITMAP pBitmap, int iOColor, int iNColor);
上面的 Expand 函数组,用来将设备无关的位图转化为与指定设备上下文相关的位图对象。
有关位图操作的详细使用方法,可见 mglite-exec 包中的 bitmaptest 示例程序。