现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

MFC绘图总结(3):设置绘图颜色

2012-12-24 22:52 工业·编程 ⁄ 共 4985字 ⁄ 字号 暂无评论

1.颜色

Windows中的颜色一般用4个字节表示(0BGR(整数) = R G B 0(字节序) [Intel CPU低位字节在前]),Win32 API中定义了一个专门表示颜色索引值的变量类型COLORREF:(windef.h)

typedef DWORD COLORREF; // 0x00bbggrr

和一个由红绿蓝三原色构造颜色值的宏RGB:(wingdi.h)

#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))

其中,r、g、b为字节变量,取值范围为0~255。其函数说明为:

COLORREF RGB(

BYTE bRed, // red component of color

BYTE bGreen, // green component of color

BYTE bBlue // blue component of color

);

例如:

              COLORREF red, gray;

              red = RGB(255, 0, 0);

              gray = RGB(128, 128,128);

在API中还定义了由COLORREF变量获取各个颜色分量的宏Get?Value:(wingdi.h)

#define GetRValue(rgb) (LOBYTE(rgb))

#define GetGValue(rgb) (LOBYTE(((WORD)(rgb)) >> 8))

#define GetBValue(rgb) (LOBYTE((rgb)>>16))

其中:

typedef unsigned long ULONG_PTR;

typedef ULONG_PTR DWORD_PTR;

#define LOBYTE(w)  ((BYTE)((DWORD_PTR)(w) & 0xff))

它们对应的函数说明为:

BYTE GetRValue(DWORD rgb); // DWORD rgb ~ COLORREF col

BYTE GetGValue(DWORD rgb);

BYTE GetBValue(DWORD rgb);

2.点色(像素)

在Windows中,像素(pixel)的颜色是直接由设备上下文类CDC的成员函数SetPixel来设置的,该函数的原型为:

COLORREF SetPixel( int x, int y, COLORREF crColor );

COLORREF SetPixel( POINT point, COLORREF crColor );

其中,x与y分别为像素点的横坐标与纵坐标,crColor为像素的颜色值。例如:

pDC->SetPixel(10, 10, RGB(0, 255, 0));

另外,也可以用CDC的成员函数

COLORREF GetPixel( int x, int y ) const;

COLORREF GetPixel( POINT point ) const;

来获得指定点(x, y)或point的颜色。例如:

    COLORREF col;

    col = pDC->GetPixel(10, 10);

3.线色(笔)

在Windows中,线状图必须用笔(pen)来画,所以线的颜色就由笔色来确定。在MFC中,笔的属性和功能由CPen类提供(CPen是CGDIObject的派生类)。

笔的创建与使用的步骤为:

创建笔对象:创建笔类CPen对象的方法有如下两种:

使用构造函数CPen

CPen( int nPenStyle, int nWidth, COLORREF crColor );

其中:

nPenStyle为笔的风格,可取值:

PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PSDASHDOTDOT

注意:1~4号笔风格只是在笔宽=0或1时有效,笔宽>1时总为实心的。

nWidth为笔宽,与映射模式有关,使用缺省映射时为像素数,若nWidth = 0,则不论什么映射模式,笔宽都为一个像素;

crColor为笔的颜色值。

例如

CPen* pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128));

CPen grayPen(PS_SOLID, 0, RGB(128, 128, 128));

使用成员函数CreatePen

BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );

如:

CPen grayPen;

grayPen.CreatePen(PS_SOLID, 0, RGB(128, 128, 128));

缺省的笔为单像素宽的实心黑色笔

将笔对象选入设备上下文:为了能使用我们所创建的笔对象,必须先将它选入设备上下文,这可以调用设备上下文类CDC的成员函数SelectObject来完成:

CPen* SelectObject( CPen* pPen );

返回值为指向原来笔对象的指针(一般将其保存下来,供下次再装入时使用)。如

pOldPen = pDC->SelectObject(&pen);

另外,Windows中有一些预定义的笔对象,可用CDC的另一成员函数SelectStockObject将其选入DC,其函数原型为

virtual CGdiObject* SelectStockObject( int nIndex );

预定义的笔对象有BLACK_PEN(黑色笔)、WHITE_PEN (白色笔)、NULL_PEN(空笔/无色笔)。例如:

pDC->SelectStockObject(BLACK_PEN);

使用设备上下文画线状图:画线状图以及面状图的边线,所使用的是当前设备上下文中的笔对象。线状图有直线、折线、矩形、(椭)圆(弧)等,详见4)(2)

将笔对象从设备上下文中放出:为了能删除使用过的笔对象,必须先将它从设备上下文中释放出来后,然后才能删除。释放的方法是装入其他的笔对象(一般是重新装入原来的笔对象)。例如

pDC->SelectObject(pOldPen);

删除笔对象:为了能删除笔对象,必须先将其从设备上下文中释放。删除方法有如下几种

调用笔类CDC的成员函数DeleteObject删除笔的当前内容(但是未删除笔对象,以后可再用成员函数CreatePen在笔对象中继续创建新的笔内容)。如

pen.DeleteObject();

使用删除运算符delete将笔对象彻底删除,如delete pen;

自动删除:若笔对象为局部变量,则在离开其作用域时,会被系统自动删除

下面为一段较完整地创建与使用笔的例子代码:

       CPen pen, *pOldPen;

       for (int j = 0; j <= 255; j++) {

              HSLtoRGB(m_hue, m_sat, 255 - j, r, g, b); // 自定义的函数

              pen.CreatePen(PS_SOLID, 0, RGB(r, g, b));

              pOldPen = pDC->SelectObject(&pen);

              pDC->MoveTo(0, j); pDC->LineTo(40, j);

              pDC->SelectObject(pOldPen);

              pen.DeleteObject();

       }

4.面色(刷)

在Windows中,面状图必须用刷(brush)来填充,所以面色是由刷色来确定的。MFC中的刷类为CBrush(它也是CGDIObject的派生类),刷的创建与使用的步骤与笔的相似。

构造函数有4个:

CBrush( ); // 创建一个刷的空对象

CBrush( COLORREF crColor ); // 创建颜色为crColor的实心刷

CBrush( int nIndex, COLORREF crColor ); // 创建风格由nIndex指定且颜色为crColor的条纹(hatch孵化)刷,其中nIndex可取条纹风格(Hatch Styles)值:

符号常量
数字常量
风格
HS_HORIZONTAL
0
水平线
HS_VERTICAL
1
垂直线
HS_FDIAGONAL
2
正斜线
HS_BDIAGONAL
3
反斜线
HS_CROSS
4
十字线(正网格)
HS_DIAGCROSS
5
斜十字线(斜网格)

5.文本色

可使用CDC类的成员函数SetTextColor和SetBkColor来分别设置输出文本的前景色和背景色:(缺省的前景色为黑色,背景色空)

COLORREF GetTextColor( ) const;

virtual COLORREF SetTextColor( COLORREF crColor );

COLORREF GetBkColor( ) const;

virtual COLORREF SetBkColor( COLORREF crColor );

例如:

       pDC->TextOut(10, 10, "Test text");

       pDC->SetTextColor(RGB(0, 128, 0)); pDC->TextOut(10, 30, "Test text");

       pDC->SetBkColor(RGB(0, 0, 128));     pDC->TextOut(10, 50, "Test text");

6.绘图工具

1)GDI对象

Windows的图形设备接口(GDI = graphics device interface)对象指各种绘图工具,如笔、刷、位图、字体、调色板、区域等,对应的MFC类为CPen、CBrush、CBitmap、CFont等。这些图形绘制对象类都是CGDIObject的派生类,而CGDIObject则是直接从CObject类派生的抽象基类。<!--[endif]-->其中,Windws CE不支持调色板类CPalette;CRgn为区域类,对应于窗口中的一个矩形、多边形或(椭)圆区域(region),可用于移动、拷贝、合并、判断和裁剪。

2)选入

可用设备上下文类CDC的多态成员函数SelectObject,来将绘图工具对象选入设备上下文,以供绘图时使用:

CPen* SelectObject( CPen* pPen );

CBrush* SelectObject( CBrush* pBrush );

virtual CFont* SelectObject( CFont* pFont );

CBitmap* SelectObject( CBitmap* pBitmap );

int SelectObject( CRgn* pRgn );

CGdiObject* SelectObject( CGdiObject* pObject );

3)获取

可用API函数GetCurrentObject来获得当前在DC中的指定类型的绘图对象:

HGDIOBJ GetCurrentObject(

HDC hdc,           // handle to device context

UINT uObjectType   // specifies the object-type

);

其中,参数uObjectType可取值:

OBJ_PEN      // Returns the current selected pen.

OBJ_BRUSH // Returns the current selected brush.

OBJ_PAL       // Returns the current selected palette.

OBJ_FONT  // Returns the current selected font.

OBJ_BITMAP // Returns the current selected bitmap.

也可分别调用CDC类的下列成员函数来做同样的事:

CPen* GetCurrentPen( ) const;

CBrush* GetCurrentBrush( ) const;

CFont* GetCurrentFont( ) const;

CBitmap* GetCurrentBitmap( ) const;

CPalette* GetCurrentPalette( ) const;

如:

HPEN hPen = (HPEN)GetCurrentObject(pDC->m_hDC, OBJ_PEN);

CPen* pPen = CPen::FromHandle(hPen);

等价于:

CPen* pPen = pDC-> GetCurrentPen( );

给我留言

留言无头像?