GetObject函数用于从指定的图形对象中获取信息,原型如下:
int GetObject( __in HGDIOBJ hgdiobj, __in int cbBuffer, __out LPVOID lpvObject );
其中
(1)参数hgdiobj是图形对象的句柄,图形对象可以是如下几种:逻辑位图、刷子、字体、调色板、画笔或者由函数CreateDIBSection创建的设备无关位图;
(2)参数cbBuffer是即将写入到缓冲区中的图形对象信息的字节数;
(3)参数lpvObject是指向接收图形对象信息的缓冲区的指针,下表是每一种图形对象对应获取到的缓冲区中的信息:
返回值:
当函数执行成功且参数lpvObject为NULL时,返回值是保存获取的信息的缓冲区需要的字节数;
当函数执行成功且参数lpvObject是有效地指针时,返回值是存储到缓冲区中的数据的字节数;
当函数执行失败时,返回值是0。
实例代码如下,使用GetObject函数获取指定位图的大小:
/******************************************************************** * 获取指定位图的宽和高 ********************************************************************/ inline void GetBitmapSize(HBITMAP hBitmap, int& nWidth, int& nHeight) { BITMAP bm; ::GetObject(hBitmap, sizeof(BITMAP), (PSTR)&bm); nWidth = bm.bmWidth; nHeight = bm.bmHeight; }
GradientFill函数用于填充矩形和三角形结构,原型如下:
BOOL GradientFill( __in HDC hdc, __in PTRIVERTEX pVertex, __in ULONG nVertex, __in PVOID pMesh, __in ULONG nMesh, __in ULONG ulMode );
其中
(1)参数hdc是目标设备上下文的句柄;
(2)参数pVertex是指向存储TRIVERTEX结构数据的数组;
(3)参数nVertex是数组pVertex中的顶点数;
(4)参数pMesh在三角形模式中表示存储GRADIENT_TRIANGLE结构数据的数组;在矩形模式中表示存储GRADIENT_RECT结构数据的数组;
(5)参数nMesh是pMesh数组中元素的个数;
(6)参数ulMode指定渐变填充模式,取值如下:
返回值:
函数执行成功时返回TRUE;失败时返回FALSE;
上面函数中使用到了几个结构,下面分别介绍:
1)TRIVERTEX结构包含了颜色信息和位置信息,原型如下:
typedef struct _TRIVERTEX { LONG x; //逻辑单位下矩形左上角的x坐标 Long y; //逻辑单位下矩形左上角的y坐标 COLOR16 Red; //上述点的颜色信息 COLOR16 Green; COLOR16 Blue; COLOR16 Alpha; } TRIVERTEX, *PTRIVERTEX;
2)GRADIENT_RECT结构指定了函数GradientFill中参数pVertex数组中的两个点的索引,这两个点分别是一个矩形的左上角和右下角点,结构原型如下:
typedef struct _GRADIENT_RECT { ULONG UpperLeft; //矩形左上角 ULONG LowerRight; //矩形右下角 } GRADIENT_RECT, *PGRADIENT_RECT;
3)GRADIENT_TRIANGLE结构指定了函数GradientFill函数中pVertex数组中的三个点的索引,这三个点组成一个三角形,结构原型如下:
typedef struct _GRADIENT_TRIANGLE { ULONG Vertex1; ULONG Vertex2; ULONG Vertex3; } GRADIENT_TRIANGLE, *PGRADIENT_TRIANGLE;
实例代码如下:
/************************************************* * 画出颜色渐变的矩形 *************************************************/ inline void DrawGradualColorRect( HDC dc, const RECT& drawRC, COLORREF clrFirst = RGB(255, 255, 255), COLORREF clrEnd = RGB(0, 0, 0), BOOL fVertical = TRUE ) { //下面的重复代码是为了扩展,虽然现在是一样的, //但并不排除以后垂直渐变和水平渐变取值不一样 if (fVertical) //垂直渐变 { GRADIENT_RECT gRect = {0, 1}; //指定vert中的点的索引 TRIVERTEX vert[2] = { {drawRC.left , drawRC.top , 0, 0, 0, 0}, {drawRC.right, drawRC.bottom, 0, 0, 0, 0} }; vert[0].Red = GetRValue(clrFirst) << 8; vert[0].Green = GetGValue(clrFirst) << 8; vert[0].Blue = GetBValue(clrFirst) << 8; vert[1].Red = GetRValue(clrEnd) << 8; vert[1].Green = GetGValue(clrEnd) << 8; vert[1].Blue = GetBValue(clrEnd) << 8; ::GradientFill(dc, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V); } else //水平渐变 { GRADIENT_RECT gRect = {0, 1}; //指定vert中的点的索引 TRIVERTEX vert[2] = { {drawRC.left , drawRC.top , 0, 0, 0, 0}, {drawRC.right, drawRC.bottom, 0, 0, 0, 0} }; vert[0].Red = GetRValue(clrFirst) << 8; vert[0].Green = GetGValue(clrFirst) << 8; vert[0].Blue = GetBValue(clrFirst) << 8; vert[1].Red = GetRValue(clrEnd) << 8; vert[1].Green = GetGValue(clrEnd) << 8; vert[1].Blue = GetBValue(clrEnd) << 8; ::GradientFill(dc, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_H); } }