Peng Lv

毋意,毋必,毋固,毋我。 言必行,行必果。

导航

Windows编程学习笔记(五)

第二章 图形基础(下)

 

用画刷填入内部

画刷是一个8*8的位图,他水平和垂直地重复使用来填入内部区域。

Windows还有五个函数,让我们建立逻辑画刷,然后就可以使用SelectObject选入,建立的逻辑画刷最后必须要删除。

1. hBrush = CreateSolidBrush(crColor); 其中Solid并不是指画刷为纯色。

2. hBrush = CreateHatchBrush(iHatchStyle,crColor); 这是由各种颜色线条组成的画刷,如果背景方式为OPAQUE,则用背景色(它也被转换为纯色)来填入线之间的空间。在这种情况下,影线和填入色都不能是混色而成的颜色。如果背景方式为TRANSPARENT,则Windows只画出影线,不填入它们之间的区域。

3. hBrush = CreatePatternBrush 和 CreateDIBPatternBrushPt 建立自己的位图的画刷。

4. hBrush = CreateBrushIndirect(&logbrush);LOGBRUSH的三个字段的结构如下表所示:

/****************************************************/

 

GDI映像方式

 

到目前为止,所有的程序都是相对于显示区域的左上角,以图素为单位的,这是内定情况,担不是唯一的。Windows定义了8种映像方式,可以使用SetMapMode(hdc,iMapMode);来设定映射方式,也可使用iMapMode = GetMapMode(hdc)来获得当前设备的映射方式。

 

设备坐标系

 

有三种坐标系:

1. 整个屏幕为基准的坐标系

2. 以整个窗口为基准的坐标系

3. 以显示区域为基准的坐标系

三者的左上角都是(0,0);

我们可使用 SetViewportOrgEx和SetWindowOrgEx用来改变视端窗口的原点,这两个函数都有改变轴的效果 ,比如想要将逻辑点(0,0)设定为显示区域的中心,可以这样使用:

SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);

我们也可以使用下列函数来得到目前视端口和窗口的原点:

POINT pt;

GetViewportOrgEx(hdc,&pt);

GetWindowOrgEx(hdc,&pt);

/*************************************************************/

 

矩形、区域

 

矩形函数 FillRect(hdc,&rect,hBrush);FrameRect(hdc,&rect,hBrush);InverRect(hdc,&rect);

第一个函数就是填充举行,第二个函数是用指定画刷画矩形的边界,第三个翻转矩形中的像素。

Windows还提供了9个函数来让我们更加方便的对RECT结构进行操作,下面就一一来看:

SetRect(&rect,xleft,ytop,xright,ybottom); 设定rect值

OffsetRect(&rect,x,y); 将矩形沿x、y移动单元

InflateRect(&rect,x,y); 增减矩形的尺寸

SetRectEmpty(&rect); 清空矩形

CopyRect(&dest_rect,&src_rect); 将矩形赋值给里一个矩形

bEmpty = IsRectEmpty(&rect); 确定矩形是否为空

bInRect = PtInRect(&rect,pt); 确定点是否在矩形内部

也可以使用 dest_rect = src_rect;

/************************************************************/

 

 

 

lbStyle (UINT)

lbColor (COLORREF)

lbHatch (LONG)

BS_SOLID

画刷的色彩

忽略

BS_HOLLOW

忽略

忽略

BS_HATCHED

影线的色彩

影线画刷风格

BS_PATTERN

忽略

位图的句柄

BS_DIBPATTERNPT

忽略

指向DIB的指标

PeekMessage OR GetMessage

 

PeekMessage(&msg,NULL,0,0,PM_REMOVE);

前面四个参数(msg指针,wnd句柄,两个值指示消息范围)与GetMessage相同。如果想要函数有传回所有的消息时,可以设定为0,如果是所有窗口的消息,可以设定为NULL,最后一个参数是决定是否删除消息,PM_REMOVE PM_NOREMOVE,如果又符合条件的消息,那么将传回TRUE,否则传回FALSE,于是PeekMessage可一窃取消息,但要记住,此函数是不会删除WM_PAINT消息的。

GetMessage则不一样,他不能返回直到从程序的消息队列中取得消息。

这使得我们可以改写普通的消息循环。我们可以将如下所示的循环:

while (GetMessage (&msg, NULL, 0, 0))

{

    TranslateMessage (&msg) ;

    DispatchMessage (&msg) ;

}

return msg.wParam ;

替换为下面的循环:

while (TRUE)

{

    if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))

    {

            if (msg.message == WM_QUIT)

                   break ;

            TranslateMessage (&msg) ;

            DispatchMessage (&msg) ;

    } else

    {

            // 完成某些工作的其它行程序

    }

}

return msg.wParam ;

/**************************************************/

 

建立和绘制剪裁区域

剪裁区域是对显示器伤的一个范围的描述,这个区域是矩形,多边形和椭圆的集合,剪裁区域是GDI对象,使用完后应该呼叫DeleteObject来删除对象。

有两种方法建立矩形剪裁区域:hRgn = CreateRectRgn(xleft,ytop,xright,ybottom)或者hRgn = CreateRectRgn(&rect);同理我们可以建立椭圆形和多边形的剪裁区域 hRgn = CreatePolygonRgn(&point,iCount,iPolyFillMode);

合并剪裁区域:CombineRgn

iRgnType = CombineRgn(hDestRgn,hSrcRgn1,hSrcRgn2,iCombine);

其中第四个参数指示两区域是怎样合并:RGN_AND RGN_OR RGN_XOR RGN_DIFF RGN_COPY

还有对剪裁区域作用的几个绘图函数:

FillRgn(hdc,hRgn,hBrush);

FrameRgn(hdc,hRgn,xFrame,yFrame);

InvertRgn(hdc,hRgn);

PaintRgn(hdc,hRgn);

我们可以使用InvalidateRgn(hwnd,hRgn,bErase)和ValidateRgn(hwnd,hRgn)来使区域有效或无效。

 

posted on 2010-02-03 16:48  Lvpengms  阅读(451)  评论(0编辑  收藏  举报