MFC原创教程:1.0 Draw

本文介绍如何在VisualStudio2005中利用MFC进行绘图操作,包括记录鼠标点击位置、绘制线条、使用不同颜色的画笔、填充矩形等,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用软件 visual studio 2005
要在程序中划线,需要知道鼠标左键按下时的和松开时鼠标的起始坐标。
1.创建单文档MFC应用程序。
2.先以增加一个BUTTON按钮控件为例,说明下添加消息响应的过程。
类视图--右键点击CMainFrame--属性
右侧可以看到:
点击--消息--找到 WM_LBUTTONDOWN--添加。
添加代码:
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
MessageBox("MainFrame点击")
CFrameWnd::OnLButtonDown(nFlags, point);
}
同样的,在CDrawView类添加这个消息
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
MessageBox("VIEW点击");
CView::OnLButtonDown(nFlags, point);
}
这时,按下F7,可能会发现无法编译。(如果是C2664错误,解决方法是: 项目菜单--项目属性(最后一个)--配置属性--常规--项目默认值--字符集,将使用Unicode字符集改为未设置即可
编译成功后,按下F5,运行,单击窗口界面,发现是弹出窗口:“VIEW点击”而不是“MainFrame点击”。(MainFrame类是地面,VIEW类是地板,VIEW类覆盖在MainFrame类之上,所以“单击”只对VIEW有效)
CMainFrame::OnLButtonDown不需要了,删除这个消息的话,类视图--右键点击CMainFrame--属性--点击--消息--找到 WM_LBUTTONDOWN--删除。(因为多处地方已经自动生成了代码)
OnLButtonDown中的一个参数CPoint point,就记录了鼠标左键按下时的坐标,我们要记录它。
方法:右键点击-CDrawView--添加--变量

然后修改代码
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_ptOrigin=point;
CView::OnLButtonDown(nFlags, point);
}
这样就获取了起点坐标,接下来创建一个OnLButtonUp消息,添加代码:
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
/*HDC hdc;
hdc=::GetDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,m_ptOrigin.x,m_ptOrigin.y);
::ReleaseDC(m_hWnd,hdc);*/
//上面注释的代码是实现画线功能的另一种方法,不过我在VS2005无法实现,VC++6.0应该可以,没去研究。
//所有与绘图相关的操作封装到了CDC类中。
CDC *pDC=GetDC(); //获取句柄(DC指针)
pDC->MoveTo(m_ptOrigin); //将点移到起点处
pDC->LineTo(point); //从起点画线到终点
ReleaseDC(pDC); //释放DC
CView::OnLButtonUp(nFlags, point);
}
也可以使用另一个类CClientDC (封装了获取句柄和释放DC的函数),使用方法如下:
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this); //this指View类指针
//CClientDC dc(GetParent()); //GetParent()获取父窗口句柄,在工具栏也可实现画线功能
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
/*
CWindowDC dc(GetParent());
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
*/
//这段注释实现的功能:在菜单栏也可以画线。若将参数GetParent()改为GetDesktopWindow(),则实现在整个桌面画线的功能。
CView::OnLButtonUp(nFlags, point);
}
画笔,实现画不同颜色的线的功能。
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CPen pen(PS_SOLID,1,RGB(255,0,0)); //创建新画笔(实线,宽度1,颜色红色)
CClientDC dc(this);
CPen *pOldPen=dc.SelectObject(&pen); //保存旧画笔,把新的画笔选入到设备描述表。这句代码的作用是将新创建的画笔作为当前画笔但是
// SelectObject()的返回值则是新建画笔之前的画笔的指针,所以pOldPen保存的是一开始的画笔指针
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
dc.SelectObject(pOldPen); //恢复为旧画笔
CView::OnLButtonUp(nFlags, point);
}

画刷
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CBrush brush(RGB(255,0,0));
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush); //填充矩形区域.CRect有多种构造函数,当前参数为矩形左上和右下两个坐标

//下面注释的代码实现位图的填充。首先插入Bitmap资源,得到IDB_BITMAP1
/*
CBitmap bitmap;
bitmap.LoadBitmapA(IDB_BITMAP1); //一般是bitmap.LoadBitmap(IDB_BITMAP1);
//为什么VS2005是LoadBitmapA()这个函数,还有很多函数都加了个A字母?
//对于参数中含有字符串的API,实际上都有两个版本,一个是LoadBitmapA,一个是LoadBitmapW,一个对应ANSI版本,
//一个对应UNICODE版本,而LoadBitmap只是一个宏,真正的API是上面两个,你上面说的加个A说明你当前编译环境是ANSI
CBrush brush(&bitmap);
CClientDC dc(this);
dc.FillRect(CRect(m_ptOrigin,point),&brush);
*/
CView::OnLButtonUp(nFlags, point);
}
画透明矩形
void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
//GetStockObject(NULL_BRUSH)获取“空画刷”的句柄,返回HGDIOBJ句柄。
//((HBURSH)强制转换为HBURSH句柄
//FromHandle封装在CBrush里,将句柄转换为C++指针。(FromHandle)
CBrush *pOldBrush=dc.SelectObject(pBrush);
dc.Rectangle(CRect(m_ptOrigin,point)); //画矩形。新矩形覆盖在旧矩形之上
dc.SelectObject(pOldBrush);
CView::OnLButtonUp(nFlags, point);
}
画连续的曲线。首先先画扇形。
添加WM_MOUSEMOVE消息( 若出现错误,无法执行添加/移除操作,因为代码元素“……”是只读的。把编辑器中所有打开的文件关闭,再把工程下的.ncb文件删除,重新打开工程应该就好了。)
添加bool变量m_bMouseMove。
代码如下:(鼠标每次移动都画一个小三角形)
void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_ptOrigin=point;
m_bMouseMove=TRUE;
CView::OnLButtonDown(nFlags, point);
}

void CDrawView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_bMouseMove=FALSE;
CView::OnLButtonUp(nFlags, point);
}

void CDrawView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CClientDC dc(this);
if(m_bMouseMove==TRUE)
{
dc.SetROP2(R2_BLACK); //绘图模式!所有绘制出来的像素为黑色
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
}
CView::OnMouseMove(nFlags, point);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值