MFC原创教程:1.0 Draw

使用软件 visual studio 2005
要在程序中划线,需要知道鼠标左键按下时的和松开时鼠标的起始坐标。
1.创建单文档MFC应用程序。
2.先以增加一个BUTTON按钮控件为例,说明下添加消息响应的过程。
类视图--右键点击CMainFrame--属性
右侧可以看到:
MFC原创教程:1.0 Draw_第1张图片
点击--消息--找到 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--添加--变量
MFC原创教程:1.0 Draw_第2张图片
然后修改代码
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);
}

你可能感兴趣的:(mfc,mfc,vc++,vc++)