使用画刷画图


(1)简单画刷

MFC提供一个CBrush类,可以用来创建画刷对象,通常填充一块区域

 C++ Code 
1
2
3
4
5
6
7
8
9
 
//创建一个红色画刷
CBrush brush(RGB( 25500));

//创建并获得设备描述表
CClientDC dc( this);

//利用红色画刷填充鼠标拖拽过程中形成的区域
dc.FillRect(CRect(m_CPoint, point), &brush);

     首先创建一个红色画刷:接着创建设备描述表对象,然后调用设备描述表对象的成员函数
     CRect类提供多个构造函数,这个通过指定矩形区域的左上角和右下角来构造一个矩形区域

CRect( int l, int t, int r, int b );

CRect( const RECT& srcRect );

CRect( LPCRECT lpSrcRect );

CRect( POINT point, SIZE size );

CRect( POINT topLeft, POINT bottomRight );


     CDC类的成员函数FillRect,该函数的功能是用指定的画刷填充一个矩形,该函数将填充全局的矩形,包括左边和上部辩解,但不填充右边和底部边界

void FillRect( LPCRECT lpRect, CBrush* pBrush );



(2)位图画刷
CBrush( CBitmap* pBitmap );
throw( CResourceException );

pBitmap

Points to a CBitmap object that specifies a bitmap with which the brush paints.

     创建CBitmap对象时,仅调用其构造函数并不能得到一个有用的位图对象,还需要调用一个初始化函数来初始化这个对象
      BOOL LoadBitmap( LPCTSTR  lpszResourceName  );

     BOOL LoadBitmap( UINT nIDResource );

     Return Value

          Nonzero if successful; otherwise 0.

     Parameters

     lpszResourceName

          Points to a null-terminated string that contains the name of the bitmap resource.

     nIDResource

          Specifies the resource ID number of the bitmap resource.

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 

//创建位图对象
CBitmap bitmap;

//加载位图资源
bitmap.LoadBitmap(IDB_BITMAP1);

//创建位图画刷
CBrush brush(&bitmap);

//创建并获得设备描述表
CClientDC dc( this);

//利用红色画刷填充鼠标拖拽过程中形成的区域
dc.FillRect(CRect(m_CPoint, point), &brush);



(3)透明画刷

 C++ Code 
1
2
3
4
5
 
//创建并获得设备描述表
CClientDC dc( this);

//绘制一个矩形
dc.Rectangle(CRect(m_CPoint, point));

BOOL Rectangle( int x1, int y1, int x2, int y2 );

BOOL Rectangle( LPCRECT lpRect );

Return Value

     Nonzero if the function is successful; otherwise 0.

Parameters

x1

     Specifies the x-coordinate of the upper-left corner of the rectangle (in logical units).

y1

     Specifies the y-coordinate of the upper-left corner of the rectangle (in logical units).

x2

     Specifies the x-coordinate of the lower-right corner of the rectangle (in logical units).

y2

     Specifies the y-coordinate of the lower-right corner of the rectangle (in logical units).

lpRect

     Specifies the rectangle in logical units. You can pass either a CRect object or a pointer to a RECT structure for this parameter

     当我们绘制两个相互重叠的矩形时,后绘制的矩形就会覆盖住先前绘制的矩形,这时因为设备描述表中有一个默认的白色画刷,在绘图时,它会利用这个画刷来填充矩形内部,所以,当位置存在重叠时,后绘制的矩形就会把先前绘制的矩形遮挡住

     如果希望矩形内部是透明的,能够看到被遮挡的图像,那么就要创建一个透明画刷
      在这里我们需要活学活用,如果子类没有相应的函数,就应该在父类中找

     

GetStockObject函数,利用该函数可以获取一个黑色或白色的画刷句柄。

GetStockObject

The GetStockObject function retrieves a handle to one of the stock pens, brushes, fonts, or palettes.

HGDIOBJ GetStockObject(
  int fnObject   // stock object type
    利用GetStockObject函数获取的是一个画刷句柄,而我们在进行绘制操作时需要的是一个画刷对象,这里要用到FromHandle函数来实现功能
static CBrush* PASCAL FromHandle( HBRUSH hBrush );
Return Value
     A pointer to a CBrush object if successful; otherwise NULL.
Parameters
      hBrush
HANDLE  to a Windows GDI brush.
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
//创建并获取设备描述表
CClientDC dc( this);

//创建一个空画刷
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

//将空画刷选入设备描述表
CBrush *pOldBrush = dc.SelectObject(pBrush);

//绘制一个矩形
dc.Rectangle(CRect(m_CPoint, point));

//恢复先前的画刷
dc.SelectObject(pOldBrush);

需要注意的地方:
  1. FromHandle函数的调用方式,这个调用类的静态成员函数的方式
  2. 由于GetStockObject函数返回的类型是HGDIOBJECT,需要进行一个强制类型转换,将其转换为HBRUSH类型
  3. 这里创建的平Brush变量本身就是一个指针类型,因此在调用SelectObject函数时,该变量前面不用再加上取地址符。
  4. 另外比较一个FillRect函数和Rectangle函数,首先二者都能绘制矩形,但前者在参数中提供了绘制使用的画刷,因此他就直接利用此画刷来填充矩形,并不需要先把需要的画刷选入设备描述表中,而后者并没有提供画刷这个参数,因此先要把需要的画刷选入设备描述表中,然后再调用此函数来绘制矩形。



(4)绘制连续线条
     为了绘制连续的线条,首先需要得到线条的起点,然后需要捕获鼠标移动过程中的每一个点,这可以通过鼠标移动消息来实现,在此消息响应函数中,在以此捕获到的各个点之间绘制一条条非常短的线段,从而就可以绘制出一条连续的线条
     首先为视类田间一个BOOL型的私有成员变量m_bDraw,当鼠标做左键按下去时,此变量为真,说表左键弹起来的时,此变量为假
     然后在OnMouseMove函数中首先对m_bDraw变量进行判断,如果其值为真,说明鼠标左键已经按下去了,这个时候开始进行画线操作。
     还有一点需要注意,因为每绘制一条线段后,下次应该从这条线段的重点开始绘制,因此,绘制完当前线段后,应该修改线段的起点,将当前线段的终点作为下一跳线段的起点

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
 
//获得DC
CClientDC dc( this);

if (m_bDraw == TRUE)
{
     //画线
    dc.MoveTo(m_CPoint);
    dc.LineTo(point);

     //修改线段的起点
    m_CPoint = point;
}

如果需要田间颜色的话:
 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
//获得DC
CClientDC dc( this);

//创建一个红色的宽度为1的实线画笔
CPen pen(PS_SOLID,  5, RGB( 2551750));

//把创建的画笔选入设备描述表
CPen *OldPen = dc.SelectObject(&pen);
if (m_bDraw == TRUE)
{
     //画线
    dc.MoveTo(m_CPoint);
    dc.LineTo(point);

     //修改线段的起点
    m_CPoint = point;
}

//恢复设备描述表
dc.SelectObject(OldPen);































































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值