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资源
使用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);
CDC::Rectangle()会使用DC中画刷(默认为白色画刷)来绘制一个带边框的矩形,如果想要改变矩形里的颜色则应该调用CDC::SelectObject()函数将指定颜色的画刷选入到DC中。
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也可以调用其静态函数由句柄获得对应的指针。
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()用来绘制多边形。