常用GDI函数(1):绘制线条和图形

1、

CDC::SetPixel()用来绘制一个像素点。

使用Win32 API函数:

    HDC hdc = ::GetDC(m_hWnd);//获得窗口的设备描述表
    
    ::SetPixel(hdc, 100, 200, RGB(255, 0, 0));

    ::ReleaseDC(m_hWnd, hdc);//释放DC资源

CDC::MoveTo(),CDC::LineTo()用来绘制直线。

使用CDC类:

    CDC* pDC = GetDC();//获得与当前窗口相关联的DC对象  
  
    pDC->MoveTo(ptOrigin);  
    pDC->LineTo(ptEnd);  

    ReleaseDC(pDC);//释放DC资源  

CDC::Rectangle()会使用DC中画刷(默认为白色画刷)来绘制一个带边框的矩形,如果想要改变矩形里的颜色则应该调用CDC::SelectObject()函数将指定颜色的画刷选入到DC中。

使用CClientDC类:

CClientDC dc(this);//获得与窗口相关联的DC对象  

    CBrush brush(RGB(255, 0, 0));
    CBrush* pOldBrush = dc.SelectObject(&brush);

    CRect rect(0, 0, 100, 100);
    dc.Rectangle(&rect);

    dc.SelectObject(pOldBrush);
brush.DeleteObject();

CDC::SelectObject()用来将指定的GDI对象(画笔CPen、画刷CBrush、字体CFont、位图CBitmap、调色板CPalette等)选入到DC中,其返回DC中被替换的GDI对象,应该保存该返回的对象用来还原。

如果想要画刷的颜色为透明色,即矩形为透明,则应该将系统空画刷选入到DC中:

    HBRUSH hNull_Brush = (HBRUSH)GetStockObject(NULL_BRUSH);
    CBrush *pBrush = CBrush::FromHandle(hNull_Brush);
    CBrush* pOldBrush = dc.SelectObject(pBrush);
    
    CRect rect(0, 0, 100, 100);
    dc.Rectangle(&rect);

    dc.SelectObject(pOldBrush);

GetStockObject(int i)可以获得系统标准GDI对象,常用参数有:

NULL_BRUSH 空画刷

ANSI_FIXED_FONT 固定间距(等宽)系统字体

ANSI_VAR_FONT 变间距(比例间距)系统字体;

OEM_FIXED_FONT 原始设备制造商固定间距字体

SYSTEM_FONT 系统字体

DEFAULT_PALETTE 缺省调色板

由于GetStockObject()返回的是HGDIOBJ类型的GDI对象句柄,所以我们应该将其强制转换成具体的HBRUSH或HFONT或HPALETTE,而CDC::SelectObject()的参数类型为GDI对象指针,所以需要由GDI句柄获得GDI对象指针。

CBrush::FromHandle()可以由画刷句柄获得画刷对象的指针,它是一个静态成员函数。同理,对于CPen、CFont、CBitmap、CPalette等GDI对象,甚至CDC和CWnd等也包含静态成员函数FromHandle()。实际上,MFC对各种包含内核对象的封装类都有FromHandle(HANDLE h)方法。

CGdiObject::DeleteObject()用来删除对象,如画笔、画刷、字体、位图、调色板,当GDI对象不再使用的时候可以调用这个函数,在调用这个函数后GDI对象中的句柄就会失效。

 CDC::FillRect()使用指定的画刷绘制一个不带边框的矩形:

    CClientDC dc(this);//获得与窗口相关联的DC对象  

    CBrush brush(RGB(255, 0, 0));
    CRect rect(0, 0, 100, 100);
    dc.FillRect(&rect, &brush);

还可以使用位图画刷来绘制一个矩形区域:使用一个位图来初始化位图画刷,再用这个位图来填充矩形区域

    CClientDC dc(this);

    CBitmap bitmap;
    bitmap.LoadBitmapW(IDB_BITMAP1);//初始化位图对象  
    CBrush brush(&bitmap);//构造位图画刷
  
    CRect rect(0, 0, 100, 100);
    dc.FillRect(&rect, &brush);

使用CPaintDC类

CDC::Ellipse()使用DC中画刷(默认为白色画刷)来绘制一个圆形或椭圆,如果想要改变矩形里的颜色则应该调用CDC::SelectObject()函数将指定颜色的画刷选入到DC中:

    CPaintDC dc(this); 

    CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//获得透明画刷  
    CBrush *pOldBrush = dc.SelectObject(pBrush);//将透明画刷选入到设备描述表中  

    CRect rect(0, 0, 100, 100);
    dc.Ellipse(&rect);//绘制一个圆型  

    dc.SelectObject(pOldBrush);//还原设备描述表 

使用CWindowDC类

如果想要自定义MoveTo()、LineTo()、Rectangle()、Ellipse()绘制的线条的颜色、粗细、类型(实线PS_SOLID、虚线PS_DASH、点线PS_DOT)则需要将指定的画笔对象选入到当前设备描述表中。需要注意的是虚线、点线的宽度不能大于1。

    CWindowDC dc(this);

    CPen pen(PS_DOT, 1, RGB(255,0,0));//创建一个虚线线条,宽度为1,红色的画笔对象  
    CPen* pOldPen = dc.SelectObject(&pen);//将画笔对象选入到设备描述表中  

    dc.MoveTo(100, 0);  
    dc.LineTo(100, 200);  

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

GetDesktopWindow()函数可以获得桌面窗口的句柄,所以就可以在当前屏幕上画图:

    CWindowDC dc(GetDesktopWindow());//获得与当前桌面窗口相关联的CWindowDC对象

    dc.MoveTo(100, 100);  
    dc.LineTo(100, 800); 

2、

Windows中显示是基于设备环境(DC)的,在使用GDI函数之前必须先创建一个DC对象,MFC的设备环境类CDC封装了绘图所需要的所有函数。CClientDC、CWindowDC、CPaintDC都是从CDC类派生而来。还有一个CMetaFileDC类,它对图像的保存比像素更精确,因而往往在要求较高的场合下使用,例如AutoCAD的图形保存等。

从上面来看,如果使用Win32 SDK来绘图的话需要调用GetDC()(WM_PAINT消息响应代码块中为BeginPaint)获得指定窗口的DC句柄,绘制结束后还要调用ReleaseDC()(EndPaint())来释放DC资源。如果使用MFC的DC对象则方便了很多,而且资源释放在DC对象的析构函数中自动执行。

CClientDC获得的是窗口客户区的DC,所以只能在客户区画图,其原点坐标为客户区左上角;CWindowDC获得的是整个窗口的DC,包括标题栏、边框等,其原点坐标也是整个窗口的左上角;CPaintDC只用在窗口重绘消息响应函数中;

3、

CDC::SetROP2(int nDrawMode)用来设置画笔绘画的模式,其参数可以为R2_NOTXORPEN、R2_NOT等绘图模式。R2_NOTXORPEN绘图模式就是先把画笔颜色与屏幕颜色异或,异或之后再取反最后得到一个颜色值显示在屏幕上,而这种做法就会产生一个效果:比如用画笔画了一条线,然后再用画笔画这条线就会擦除原来画的线。R2_NOT绘画模式同样有在同一个地方画两次相当于什么都没画的功能,不过R2_NOT绘画模式第一次画的时候显示颜色并不是你选定的画笔颜色,而是系统默认画笔颜色。

4、

CPen是画笔类,用来在DC上完成绘制线条的任务,常用的构造函数: 

CPen(Int style,int width ,COLORREF color);

style:画笔样式,可以为以下样式:

         PS_SOLID 实线

         PS_DASH 虚线,该值只有当画笔宽度等于1个设备单位或更小时才有效

         PS_DOT 点线,该值只有当画笔宽度等于1个设备单位或更小时才有效

         PS_DASHDOT 点和虚线交替,该值只有当画笔宽度等于1个设备单位或更小时才有效

         PS_DASHDOTDOT 双点线和虚线交替,该值只有当画笔宽度等于1个设备单位或更小时才有效

         PS_NULL 空画笔

         PS_GEOMETRIC 几何画笔

         .......

width:画笔宽度。

color:画笔颜色。    

如果CPen在定义的时候没有被初始化,那么在使用之前应该调用其以下的初始化函数来进行初始化。  

 CreatePen()用指定的样式、宽度、颜色初始化画笔。

 CreatePenIndirect()用结构LOGPEN 中指定的风格初始化画笔。

CBrush为画刷类,画刷通常用来填充一块区域,常用的构造函数:

CBrush( COLORREF crColor ); //普通画刷

CBrush( int nIndex, COLORREF crColor ); //阴影线画刷

CBrush( CBitmap* pBitmap ); //位图画刷

crColor:画刷或阴影线的颜色

nIndex:阴影线的风格,有以下风格可选:

            HS_HORIZONTAL 水平的阴影线
            HS_VERTICAL 垂直的阴影线
            HS_CROSS 水平和垂直方向以网格线作出阴影
            HS_BDIAGONAL 45度的向下影线(从左到右)
            HS_FDIAGONAL 45度的向上阴影线(从左到右)
            HS_DIAGCROSS 45度的网格线阴影

同CPen一样,如果CBrush在定义的时候没有被初始化,那么在使用之前应该调用其以下的初始化函数来进行初始化:

 CreateSolidBrush() 用指定的颜色初始化画刷。
 CreateHatchBrush() 用指定的阴影线初始化画刷。
 CreateBrushIndirect() 用结构LOGBRUSH中指定的风格、颜色和模式初始化画刷。
 CreatePatternBrush() 用位图指定的模式初始化画刷。
 CreateDIBPatternBrush() 用独立于设备的位图(DIB)初始化画刷。
 CreateSysColorBrush() 创建一个使用系统缺省颜色的画刷。

 5、

CDC::FrameRect(LPCRECT lpRect, CBrush* pBrush)用来绘制一个矩形的边框,需要注意的是其参数指向的画刷必须是使用CreateSolidBrush()、CreateHatchBrush()或CreatePattemBrush()所初始化或GetStockObject()获得的。

CDC::Polyline(const POINT* lpPoints, int nCount)用来绘制一系列线段,即折线,lpPoints是指向要连结的那些点的数组的指针,nCount为点的个数。如果nCount为2的话其相当于MoveTo()和LineTo()绘制一条直线。

CDC::Arc()绘制弧线。

CDC::RoundRect()绘制一个带圆角的矩形,即矩形的四个角是弧形的。

CDC::Invertrect()通过对矩形内部的像素点进行逻辑NOT操作而将窗口中的矩形反转。比如它会将将白色像素变为黑色,将黑色像素变为白色,对同一块矩形调用两次InvertRect()相当于什么也没做。

CDC::Polygon()用来绘制多边形。

你可能感兴趣的:(常用GDI函数(1):绘制线条和图形)