画笔的创建、选择和删除

尽管使用现有画笔非常方便,但却受限于实心的黑画笔、实心的白画笔,或者没有画笔这三种情况。

如果想得到更丰富多彩的效果,就必须创建自己的画笔。

而这一过程通常是:使用函数CreatePen或CreatePenIndirect创建一个“逻辑画笔”,这仅仅是对画笔的描述。这些函数返回逻辑画笔的句柄;然后调用SelectObject将画笔选进设备描述表。现在就可以使用新的画笔来画线了。在任何时候,都只能有一种画笔选进设备描述表。在释放设备描述表(或在选择了另一种画笔到设备描述表中)之后,就可以调用DeleteObject来删除所创建的逻辑画笔了。在删除后,该画笔的句柄就不再有效了。

逻辑画笔是一种“GDI对象”,它是您可以创建的6种GDI对象之一,其他5种是刷子、位图、区域、字体和调色板。除了调色板之外,这些对象都是通过SelectObjcet选进设备描述表的。

在使用画笔等GDI对象时,应该遵守以下三条规则

1.最后要删除自己创建的所有GDI对象;

2.当GDI对象正在一个有效的设备描述表中时,还要删除它;

3.不要删除现有对象。

这些规则当然是不无道理的,不过有时还挺微妙的。下面来举些例子

CreateOen函数的语法形如: hPen=CreatePen(iPenStyle,iWidth,crColor);

其中,iPenStyle参数确定画笔是实线、点线还是虚线,该参数可以是WINGDI.H头文件中定义的以下标识符,下图显示了每种线型产生的线类型。

 

对于PS_SOLD、PS_NULL、PS_INSIDEFRAME线型,iWidth参数是画笔的宽度。iWidth值为0则意味着画笔宽度为一个像素。现有画笔是一个像素宽。如果指定的是点划线或虚线式画笔线型,同时又指定一个大于1的物理宽度,那么Windows将使用实线画笔来代替。

CreatePen的crColor参数是一个COLORREF值,它指定画笔的颜色。对于除了PS_INSIDEFRAME之外的画笔线型,如果将画笔选入设备描述表中,Windows会将颜色转换为设备所能表示的最相近的纯色。PS_INSIDEFRAME是唯一一种可以使用抖动色的画笔线型,并且只有在宽度大于1的情况下才如此。

在与定义一个填充区域的函数一起使用时,PS_INSIDEFRAME线型还有另外一个奇特之处,对于除了PS_INSIDEFRAME以外的所有画笔线型来说,如果用来画边界框的画笔宽度大于1个像素,那么画笔将居中对齐在在边界框线上,这样边界框线的一部分将位于边界框之外;而对于PS_INSIDEFRAME画笔线型来说,整条边界框线都画在边界框之内。

 

您也可以通过建立一个类型为LOGPEN(“逻辑画笔”)的结构,并调用CreatePenIndirect来创建画笔。如果您的程序使用许多能在源代码中初始化的画笔,那么使用这种方法将有效得多。

要使用CreatePenIndirect,首先定义一个LOGPEN类型的结构:LOGPEN logpen;

此结构有三个成员:lopnStyle(无符号整数或UINT)是画笔线型,lopnWidth(POINT结构)是按逻辑单位度量的画笔宽度,lopnColor(COLORREF)是画笔颜色。Windows只使用lopnWidth结构的x值作为画笔宽度,而忽略y值。

 将结构的地址传递给CreatePenIndirect结构就可以创建画笔了: hPen=CreatePenIndirect(&logpen);

注意:CreatePen和CreatePenIndirect函数不需要设备描述表句柄作为参数。这些函数创建与设备描述表没有联系的逻辑画笔。直到调用SelectObjcet之后,画笔才与设备描述表发生联系。因此,可以对不同的设备(如屏幕和打印机)使用相同的逻辑画笔。

下面是创建、选择和删除画笔的一种方法。假设您的程序使用三种画笔:一种宽度为1 的黑画笔、一种宽度为3的红画笔和一种黑色点式画笔,我们可以先定义三个变量来存放这些画笔的句柄:

static HPEN hPen1,hPen2,hPen3;

可以在处理WM_CREATE期间创建这三种画笔:

hPen1=CreatePen(PS_SOLD,1,0);

hPen2=CreatePen(PS_SOLD,3,RGB(255,0,0));

hPen3=CreatePen(PS_DOT,0,0);

在处理WM_PAINT期间,或者是在拥有一个设备描述表有效句柄的任何时间里,都可以将这三个画笔之一选进设备描述表并用它来画线:

SelectObject(hdc,hPen2);{其它代码}

SelectObject(hdc,hPen1);{其它代码}

可以在处理WM_DESTORY期间删除创建的三种画笔:DeleteObject(hPen1);DeleteObject(hPen2);DeleteObject(hPen3);

以上是创建、选择和删除画笔最直接的方法。但是逻辑画笔需要在整个程序运行期间占用存储,为此,您可能想要在每个WM_PAINT消息期间创建画笔,并在调用EndPaint之后删除它们,但要小心不要删除设备描述表中当前选择的画笔。

您可能还希望随时创建画笔,并将CreatePen和SelectObject调用组合到同一个语句中:

SelectObject(hdc,CreatePen(PS_DASH,0,RGB(255,0,0)));

如上的方法如何删除画笔呢?请记住SelectObject将返回设备描述表中上一次选择的画笔句柄。所以可以通过调用SelectObject将BLACK PEN选进设备描述表,并删除从SelectObject返回的值(也可先保存在hPen变量中):

DelectObject(SelectObject(hdc,GetStockObject(BLACK_PEN)));

如果有一个画笔的句柄,就可以通过调用GetObject获取LOGPEN结构各个成员的值:

GetObject(hPen,sizeof(LOGPEN),(LPVOID)&logpen);

如果需要当前选进设备描述表的画笔句柄,可以调用: hPen=GetCurrentObject(hdc,OBJ_PEN);

还有另一个创建画笔的函数ExtCreatePen,以后讨论。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值