使用Windows GDI绘图,可以使用MFC,也可以直接使用Windows API绘图,两者其实都一样。MFC也是封装了Windows API。
下面以MFC为例,进行说明。因为MFC帮我们做好了一些底层,可以直接使用Windows GDI的函数。
在MFC中使用GDI进行绘图,主要就是在View类的OnDraw函数中进行编程,这个函数为
void ClassAView::OnDraw(CDC* pDC)
ClassAView是一个视图对象,CDC是设备上下文标识符,代表了一个抽象的绘图对象,一把来说就是窗口的绘图区。
在绘图之前,首先需要设置映射模式,然后设置画笔,笔刷,然后就可以直接进行一些几何元素的绘图的。
映射模式
CDC::SetMapMode(int nMapMode)
MapMode默认有多种,比如下面是一些定义
默认情况下使用的MM_TEXT,但是也可以通过设置为其他MM_ANISOTROPIC定义,这种方法比较自由,下面以MM_ANISOTROPIC为例来说明
其实设置映射模式,其实就是设置绘图区的逻辑坐标到设备坐标之间的关系。逻辑坐标就是我们在绘图时使用的坐标,设备坐标就是真实绘图区的像素坐标。在Windows文档中把逻辑坐标校正“窗口坐标”,而把设备坐标定义成“视口坐标”,有下面的关系
x
W
i
n
d
o
w
s
,
y
W
i
n
d
o
w
xWindows, yWindow
xWindows,yWindow就是逻辑坐标
x
V
i
e
w
P
o
r
t
,
y
V
i
e
w
P
o
r
t
xViewPort, yViewPort
xViewPort,yViewPort就是设备坐标
其中 x V i e w E x t , y V i e w E x t xViewExt, yViewExt xViewExt,yViewExt可以用下面的函数进行设置
CSize CDC::SetWindowExt(int cx, int cy)
CSize CDC::SetWindowExt(Size size)
其中 x V i e w E x t , y V i e w E x t xViewExt, yViewExt xViewExt,yViewExt可以哦那个下面函数进行设置
CSize CDC::SetViewportExt(int cx, int cy)
CSize CDC::SetViewportExt(Size size)
返回值都是原来的范围
设置逻辑坐标原点
CPoint CDC::SetWindowOrg(int x, int y)
CPoint CDC::SetWindowOrg(POINT p)
设置设备坐标原点
CPoint CDC::SetViewportOrg(int x, int y)
CPoint CDC::SetViewportOrg(POINT p)
返回的都是原来的原点值
一般SetWindowOrg和SetViewportOrg只使用一个,因为使用两个会使得逻辑坐标到设备坐标之间转换比较复杂。在本文中使用SetViewportOrg。
因此使用窗口映射,可以把逻辑坐标系设置到绘图区的中心,并且X轴向右,Y轴向上
CRect rect;
GetClientRect(&rect);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(rect.Width(), rect.Height());
pDC->SetViewportExt(rect.Width(), -rect.Height());
pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
画笔
创建画笔的函数
BOOL CPen::CreatePen(int PenStyle, int penwidth, COLORREF color)
返回非0为成功,0为不成功
其中PenStyle有下面一些定义
penwidth是画笔的宽度,
color是画笔颜色,可以用RGB(r,g,b)来定义
创建画笔后,需要选择画笔
CPen *CDC::SelectObject(CPen *pen)
返回值是旧的画笔
使用完后删除画笔
BOOL CGdiOjbect::DeleteObject()
除了自定义的画笔,也可以使用库里面自带的画笔
CGDIObject *CDC::SelectStockObject(int nIndex)
返回值为旧的画笔,这样就不用自己创建画笔了,也不需要删除画笔
nIndex有下面3种库自带画笔
笔刷
笔刷是用于填充颜色的,创建和使用与画笔一致
创建笔刷
BOOL CBrush::CreateSolidBrush(COLORREF color)
选择笔刷与选择画笔一样,都是使用
CBrush* CDC::SelectObject(CBrush *brush)
删除笔刷也一样
BOOL CGdiObject::DeleteObject()
也可以选择库中定义好的一些笔刷
CGdiObject *CDC::SelectStockObject(int nIndex)
nIndex有以下一些自定义笔刷
绘图函数
绘制像素点
COLORREF SetPixel(int x, int y, COLORREF color)
COLORREF SetPixel(POINT p, COLORREF color)
返回值如果是RGB值,表示绘制成功;如果点不在绘图区,返回-1
绘制直线
CPoint CDC::MoveTo(int x, int y)
CPoint CDC::MoveTo(POINT p)
返回值是原来的位置,这个函数只是将位置更新,不进行绘图,绘图函数是下面这个
BOOL CDC::LineTo(int x, int y)
BOOL CDC::LineTo(POINT p)
绘制矩形框
BOOL CDC::Rectangle(int x1, int y1, int x2, int y2)
BOOL CDC::Rectangle(LPCRECT lpRect)
矩形框由左上角和右下角指定,矩形框不包含右边界和下边界。
绘制椭圆函数
BOOL CDC::Ellipse(int x1, int y1, int x2, int y2)
BOOL CDC::Ellipse(LPCRECT lpRect)
椭圆由外接矩形框来定义,外接矩形框的定义方法与上面一样。如果需要画一个圆形,让外接矩形框为正方形即可。