昔洛 的个人博客

Bug不空,誓不成佛

  menu
70 文章
14633 浏览
6 当前访客
ღゝ◡╹)ノ❤️

Windows编程简单绘图

一、新建一个简单MFC工程

image.png
image.png
点击Finish创建完一个简单的mfc程序运行结果如下
image.png

二、为MFC工程添加左键消息

  • 第一种添加消息的方法
    image.png
    在工作区间找到类图
    右键视图类点击选项如图所示
    image.png
    待选项如图
    image.png
    双击左边的左键按下消息自动添加到右边
    image.png
    可再次双击右边的消息快速编辑该事件
  • 第二种添加消息事件的方法
    点击菜单栏的Viewimage.png
    点击ClassWizard(vc6.0的mfc类管理器)或者代码页面右键找到ClassWizard点击后如图
    image.png
    选择要添加消息的类image.png
    在下方寻找要添加的消息image.png双击完成

三、获取窗口控制器DC的各种方法

  • 通过全局SDK(::GetDC(HWND hwnd)获取HDC对象
    • hdc = ::GetDC(m_hWnd);m_hWnd是mfc程序的一个类成员变量,它代表的是该类的窗口句柄。
  • 通过类成员函数GetDC(),该函数返回本类窗口的CDC地址(指针)
CDC *pDC = GetDC();

通过全局和类成员函数获得HDC最后需要分别使用::ReleaseDC(m_hWnd,hdc);和ReleaseDC(pDC);来释放HDC句柄,否则会一直占用系统资源造成浪费。

  • 通过构造方法CClientDC的创建对象获取
    • CClientDC dc(this);作用范围在View内
    • CClientDC dc(GetParent());作用范围在Fraim内
    • 通过构造方法创建的HDC对象的话是不需要手动释放的,其释放动作在析构函数里面进行
  • 通过CWindowDC获取
    • CWindowDC dc(this);作用范围在view窗口内
    • CWindowDC dc(GetParent());作用范围在Fraim内
    • CWindowDC dc(GetDesktopWindow());作用范围在整个桌面内
    • CWindowDC获取的DC也不需要手动释放,其析构函数也会自动释放掉的

四、以简单划线说明各种DC的作用

首先向drawView类添加鼠标鼠标左键释放的消息事件
再添加一个类成员变量类型是POINT或者CPoint主要是用来记录起点坐标
代码如下:

void CMy0303View::OnLButtonDown(UINT nFlags, CPoint point) 
{
	m_pOrigin.x = point.x;
	m_pOrigin.y = point.y;
	CView::OnLButtonDown(nFlags, point);
}
  • SDK获得的DC代码如下:
HDC dc = ::GetDC(m_hWnd);
::MoveToEx(dc,m_pOrigin.x,m_pOrigin.y,NULL);//将当前位置更新到指定的点(起点)
::LineTo(dc,point.x,point.y);	//从当前点(起点)向指定点(鼠标松开左键时的点)画一条线
::ReleaseDC(m_hWnd,dc);		//释放掉DC资源

效果如图所示
image.png

  • 通过类成员函数获得DC
CDC *dc = GetDC();	//通过类成员函数获取CDC的对象地址
dc->MoveTo(m_pOrigin.x,m_pOrigin.y);//利用CDC的成员函数MoveTo将位置点更新到起点
dc->LineTo(point.x,point.y);//成员函数划线到指定点
ReleaseDC(dc);//释放CDC

结果如下:
image.png

  • 通过CClientDC构造方法获取DC对象进行划线
    代码如下:
CClientDC dc(this);
dc.MoveTo(m_pOrigin.x,m_pOrigin.y);
dc.LineTo(point.x,point.y);

结果如图:
image.png
将构造参数改为CClientDC dc(GetParent());
image.png
如图可见当参数为GetParent()时可以划到工具栏但不能划到菜单栏

  • 通过CWindowDC获取DC
CWindowDC dc(GetParent());
dc.MoveTo(m_pOrigin.x,m_pOrigin.y);
dc.LineTo(point.x,point.y);

image.png
如图所示,此时可以画到菜单栏了
将构造参数改为CWindowDC dc(GetDesktopWindow())运行结果如图
image.png
可以对整个桌面进行画图了

五、简单绘图之颜色变化,画笔,画刷的简单用法

  • 画一个红色的线条步骤如下

1.创建一个画笔
2.获取DC控制器
3.让控制器选择画笔
4.划线
5.还原控制器的画笔

代码如下:

CPen pen(PS_SOLID,1,RGB(255,0,0));//创建一个画笔,第一个参数为画笔类型,第二个为粗细,第三个则为颜色
CClientDC dc(this);//获取dc
CPen *oldPen = dc.SelectObject(&pen);//为dc选择画笔并返回旧的画笔存储起来
dc.MoveTo(m_pOrigin.x,m_pOrigin.y);
dc.LineTo(point.x,point.y);
dc.SelectObject(*oldPen);//画完线后将dc的画笔还原

效果如图所示
image.png

  • 画一个矩形图形步骤

1.创建一个画刷
2.获得DC
3.用DC的成员函数直接话个框框

代码如下:

CBrush brush(RGB(255,0,0));//创建一个画刷,并设置颜色为红色
CClientDC dc(this);/获取dc
dc.FillRect(CRect(m_pOrigin,point),&brush);//画一个填充矩形,矩形的左上右下坐标分别为起点终点坐标
  • 画一个透明不叠加的矩形步骤

1.获得DC
2.创建一个画刷指针,用CBrush::FormHandle静态成员函数获取一个透明类型画刷
返回一个画刷对象的地址(指针)
3.设置dc的画刷并且记录旧的画刷
4.画矩形
5.恢复旧的dc画刷

代码如下:

CClientDC dc(this);//获得DC 
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//利用静态类成员函数创建画刷的对象并返回一个地址
CBrush *pOldBrush = dc.SelectObject(pBrush);//为dc设置画刷并保存旧的画刷
dc.Rectangle(CRect(m_ptOrigin,point));//用Rectang画一个矩形
dc.SelectObject(pOldBrush);//恢复旧的画刷

结果如下图:
image.png

  • 利用位图做为画刷的内容
    步骤如下:

1.创建一个bitmap位图(菜单栏Insert->Resource->Bitmap->New)也可以导入已有的
2.利用位图的id加载位图,id可在工作空间resource工程下的Bitmap下找到
3.创建画刷,构造参数为位图对象
4.获取dc
5.用dc的成员函数直接画图形这里以画一个填充矩形为例
代码如下:

CBitmap bitmap;//创建位图
bitmap.LoadBitmap(IDB_BITMAP1);//加载位图对象
CBrush brush(&bitmap);//创建画刷,内容为位图
CClientDC dc(this);//获取dc
dc.FillRect(CRect(m_pOrigin,point),&brush);//画矩形,内容是位图

运行如下:
image.png

内事不懂问百度,外事不懂问谷歌~