画笔和画刷是重要的GDI对象,因为不管你画什么图形都需要画笔和画刷,虽然多数情况下是系统默认的。
Windows提供的三种备用画笔(stock pen)
白色画笔:WHITE_PEN
黑色画笔:BLACK_PEN //这是默认的画笔
空画笔:NULL_PEN
使用画笔需要以下几个函数:
//获取预定义的备用笔、刷子、字体或者调色板的句柄
//HGDIOBJ就是GDI对象的句柄
HGDIOBJ GetStockObject(
int fnObject //对象类型
);
//该函数选择一对象到指定的设备上下文环境中,新对象替换先前的相同类型的对象。
HGDIOBJ SelectObject(
HDC hdc, // 设备环境句柄
HGDIOBJ hgdiobj // 对象句柄
);
它返回一个先前选入DC的句柄,比如hPen=SelectObject(hDc,GetStockObject(WHITE_PEN));
此时hPen的颜色为BLACK_PEN,当前为WHITE_PEN。
//删除对象句柄
BOOL DeleteObject(
HGDIOBJ hObject //对象句柄
);
如果想用画笔,就必须把该画笔选到设备环境。
例如:
HPEN hPen=nullptr;//创建画笔句柄
hPen=(HPEN)GetStockObject(WHITE_PEN);//获取画笔颜色
SelectObject(hDc,hPen);//把画笔选入设备环境
[其它代码]
DeleteObject(hPen);
创建自定义画笔:
画笔、画刷、位图、区域、字体和调色盘都是GDI对象,这些对象要用的话都要选入设备环境
我们要用到如下函数:
//创建一个逻辑画笔
//成功返回一个逻辑画笔句柄,否则返回NULL
HPEN CreatePen(
int fnPenStyle, // 画笔风格,参阅MSDN
int nWidth, // 画笔宽度(像素为单位)
COLORREF crColor // 画笔颜色
);
例如:
//创建逻辑画笔
hPen = CreatePen(PS_SOLID, 4, RGB(255,255,0));
SelectObject(hdc, hPen);//选入设备环境
MoveToEx(hdc, 10, 10, nullptr);
LineTo(hdc, 200, 200);
EndPaint(hwnd, &ps);
DeleteObject(hPen);//删除画笔
逻辑画笔信息结构
typedef struct tagLOGPEN {
UINT lopnStyle; //画笔风格
POINT lopnWidth; //画笔宽度,只用x,y不用
COLORREF lopnColor; //画笔颜色
} LOGPEN, *PLOGPEN;
创建逻辑画笔
HPEN CreatePenIndirect(
CONST LOGPEN *lplgpn // 指向逻辑画笔信息结构的指针
);
例如:
POINT pt[1] = {0};
HPEN hPen = nullptr;
//创建逻辑画笔信息结构
LOGPEN logpen = {0};
[其它代码]
//设置画笔宽度
pt[0].x= 4;
logpen.lopnStyle = PS_SOLID;//画笔风格
logpen.lopnWidth = pt[0];
logpen.lopnColor = RGB(255, 255, 0);
hPen = CreatePenIndirect(&logpen);
SelectObject(hdc, hPen);
MoveToEx(hdc, 10, 10, nullptr);
LineTo(hdc, 200, 200);
EndPaint(hwnd, &ps);
DeleteObject(hPen);
//获取指定对象句柄的信息
int GetObject(
HGDIOBJ hgdiobj, // 对象句柄
int cbBuffer, // 指定将要写到缓冲区的信息的字节数目
LPVOID lpvObject // 指向一个缓冲区的指针,该缓冲区将要检索指定图形对象的信息
);
例如:
POINT pt[1] = {0};
HPEN hPen = nullptr;
LOGPEN logpen = {0};
//缓冲区长度
DWORD iLength = 0;
//存放输出信息的缓冲区
WCHAR SZBuffer[100] = { 0 };
hPen = CreatePen(PS_SOLID, 4, RGB(255, 255, 0));
SelectObject(hdc, hPen);
//获取hPen的信息
GetObject(hPen, sizeof(LOGPEN), &logpen);
//获取logpen里面的信息
iLength = wsprintfW(SZBuffer, TEXT("logpen.lopnStyle =%u logpen.lopnWidth=%u logpen.lopnColor = %u"),logpen.lopnStyle,logpen.lopnWidth,logpen.lopnColor);
TextOut(hdc, 200, 200, SZBuffer, iLength);
MoveToEx(hdc, 10, 10, nullptr);
LineTo(hdc, 200, 200);
EndPaint(hwnd, &ps);
DeleteObject(hPen);
//获取当前被选入设备环境的画刷句柄
HGDIOBJ GetCurrentObject(
HDC hdc, // 设备环境句柄
UINT uObjectType // 对象类型
);
hPen=GetCurrentObject(hDc,OBJ_PEN);
接下以来到画刷。
Windows提供的六种备用画刷(stock brush)
白色画刷:WHITE_BRUSH
浅灰色画刷:LTGRAY_BRUSH、
灰色画刷:GRAY_BRUSH、
深灰色画刷:DKGRAY_BRUSH、
黑色画刷:BLACK_BRUSH
空画刷:NULL_BRUSH (也叫HOLLOW_BRUSH)
其原理和画笔一样,就不多讲了。
要注意的是,这里的选入DC的画刷和窗口类中的背景画刷不一样
这里的画刷是当画某个图形的时候里面会自动填充该画刷的颜色。
创建自定义画刷,其原理也和画笔基本一样:
//创建一个逻辑画刷
HBRUSH CreateSolidBrush(
COLORREF crColor // 画刷颜色
);
//创建一个有阴影线的画刷
HBRUSH CreateHatchBrush(
int fnStyle, // 阴影风格
COLORREF clrref // 指定用于阴影的刷子的前景色
);
//逻辑画刷信息结构
typedef struct tagLOGBRUSH {
UINT lbStyle; //画刷风格
COLORREF lbColor; //画刷颜色
LONG lbHatch; //阴影风格
} LOGBRUSH, *PLOGBRUSH;
//创建逻辑画刷
HBRUSH CreateBrushIndirect(
CONST LOGBRUSH *lplb // 指向LOGBRUSH的指针
);
例如:
hPen = CreatePen(PS_SOLID, 4, RGB(255, 255, 0));
SelectObject(hdc, hPen);
//使用纯画刷
logbrush.lbStyle = BS_SOLID;
//使用阴影画刷
//logbrush.lbStyle = BS_HATCHED;
logbrush.lbHatch = HS_CROSS;
logbrush.lbColor = RGB(255, 255, 0);
hBrush = CreateBrushIndirect(&logbrush);
SelectObject(hdc, hBrush);
//这是画矩形的函数
Rectangle(hdc, 100, 100, 300, 300);
画笔和画刷基本就这样使用了,还有位图画刷,这是后面才用到的内容。