MFC学习(02) 矩形移动 (VC++6.0版本)


小注:这是一次计算机图形学的课后作业,作业原文:给定一个矩形(顶点和大小自己给定),利用鼠标与鼠标响应函数,如果鼠标落入矩形区域内,点击鼠标左键,矩形改变颜色(即作业中实现题2.exe示例中的虚线变为实线并着与初始矩形不同的色),移动鼠标,矩形进行移动,左键释放时矩形变为初始色。

仅供参考,不喜请喷

  • MFC学习02 矩形移动 VC60版本

    • 代码地址
    • 先来看看老师提供的样例程序
    • 分析
    • 伪代码
    • 手把手开始做框架
      • 新建项目
      • 基本设置
      • 添加类变量
      • 添加自定义消息处理函数
    • 一步步写代码
    • 总结

0. 代码地址

  • Visual C++ 6.0
    点击查看代码

1. 先来看看老师提供的样例程序

2. 分析

  1. 矩形初始是黑色的,实线
  2. 在矩形区域内按下时,鼠标样式改变,拖动时矩形是棕色虚线(这里为了视觉效果,我会改成红色)
  3. 拖动时,鼠标指针始终处于矩形中央(我写的版本里没有这种效果)
  4. 拖动结束的时候(鼠标左键弹起时),矩形恢复成黑色实线

3. 伪代码

// 鼠标左键按下事件
void OnLButtonDown(单击的坐标点point)
{m_IsReadyToMove = false;   // 初始标记一下不能移动if (光标在矩形内){记录开始移动的点p1;m_IsReadyToMove = true; // 标记一下可以移动了修改当前画笔颜色;修改鼠标指针样式;}
}
// 鼠标移动事件
void OnMouseMove(移动的当前坐标点point)
{// 我们只考虑鼠标可以移动时鼠标的移动事件if (true == m_IsReadyToMove){利用当前鼠标位置和初始记录的位置来修改矩形的每个顶点; // 做到图随鼠标动的效果}
}
// 鼠标左键弹起事件
void OnLButtonUp(弹起的坐标点point)
{   if (可以移动){修改画笔颜色为黑色;清空移动信息;}恢复鼠标样式;m_IsReadyToMove = false;   // 标记一下此时不可以移动了
}

4. 手把手开始做框架

1.新建项目

2.基本设置

  • 单文档、MFC标准、静态库,然后点“完成”

3.添加类变量

  • 找到类视图
  • 右键CRectangleMoveView
  • 单击Add Member Variable…

  • 依次添加以下类变量
bool m_IsReadyToMove; // 是否可以开始移动
CPoint p1; // 移动矩形的时候会用到
CPen * m_CurrentPen; // 指向当前画笔,初始化指向黑色画笔
CPoint m_Points[4]; // 保存矩形的四个顶点

4.添加自定义消息处理函数

  • **在CRectangleMove类上右键

  • 依次添加下列消息处理函数
WM_LBUTTONDOWN
WM_MOUSEMOVE
WM_LBUTTONUP
  • 完成时应该是这样的:

至此,我们已经完成了基础的“框架”
接下来就是代码部分了
按照我们的伪代码思路,一步一步来

5.一步步写代码

  • 1.在CRectangleMoveView.cpp里定义三种不同颜色的画笔
CPen BlackPen(BS_SOLID, 1, RGB(0, 0, 0));
// PS_DASH 是虚线钢笔
CPen RedPen(PS_DASH , 1, RGB(255, 0, 0));
  • 2.在CRectangleMoveView.cpp开头定义一个用于坐标转换的宏
#define Trans(p1, rect) CPoint(long((p1.x+0.5)/1) - rect.Width()/2, long((p1.y+0.5)/1) - rect.Height()/2)
  • 3.在CRectangleMoveView类构造函数里对类变量赋值
//初始不可以移动
m_IsReadyToMove = false;
p1 = 0;
m_Points[0] = CPoint(121, 100);
m_Points[1] = CPoint(367, 100);
m_Points[2] = CPoint(367, 245);
m_Points[3] = CPoint(121, 245);
//初始指向黑色画笔
m_CurrentPen = &BlackPen; 
  • 4.在OnDraw函数里
void CRectangleMoveView::OnDraw(CDC* pDC)
{CRectangleMoveDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: 在此处为本机数据添加绘制代码CRect rect;GetClientRect(&rect);pDC->SetWindowExt(rect.Width(), rect.Height());pDC->SetViewportExt(rect.Width(), -rect.Height());pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);CDC memDC;  // 声明内存DCCBitmap NewBitmap, *pOldBitmap;memDC.CreateCompatibleDC(pDC);  // 创建一个与显示DC兼容的内存DC NewBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());     // 创建兼容内存位图 pOldBitmap = memDC.SelectObject(&NewBitmap);    // 将兼容位图选入内存DCmemDC.FillSolidRect(rect, pDC->GetBkColor());   // 按原来背景色填充客户区,否则是黑色rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);memDC.SetWindowExt(rect.Width(), rect.Height());memDC.SetViewportExt(rect.Width(), -rect.Height());memDC.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);memDC.SetROP2(R2_COPYPEN); // 设置绘图方式DrawObject(&memDC, rect);  // 画矩形的代码在这一个函数里// 将内存DC中的位图拷贝到设备DCpDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, -rect.Width() / 2, -rect.Height() / 2, SRCCOPY); memDC.SelectObject(pOldBitmap);
}
  • DrawObject函数的声明与定义
// 在CRectangleMoveView.h里CRectangleMoveView类内部public部分声明
void CRectangleMoveView::DrawObject(CDC* pDC, const CRect& rect);
// 在CRectangleMoveView.cpp里实现
void CRectangleMoveView::DrawObject(CDC* pDC, const CRect& rect)
{int i = 0;CPen * oldPen = pDC->SelectObject(m_CurrentPen);// 画出矩形pDC->Rectangle(CRect(Trans(m_Points[0], rect), Trans(m_Points[2], rect)));pDC->SelectObject(oldPen);
}

至此,我们可以编译运行看一下矩形效果图了

  • 5.在OnLButtonDown函数里
void CRectangleMoveView::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值m_IsReadyToMove = false;   // 初始标记一下不能移动if (m_Points[0].x <= point.x && point.x <= m_Points[2].x &&m_Points[0].y <= point.y && point.y <= m_Points[2].y){p1 = point;m_IsReadyToMove = true; // 标记一下可以移动了m_CurrentPen = &RedPen;SetCapture();           // 设置鼠标捕获   SetCursor(LoadCursor(NULL, IDC_SIZEALL)); // 设置光标为八个方向}// 触发OnDraw函数,动态效果Invalidate(FALSE);CView::OnLButtonDown(nFlags, point);
}
  • 6.在OnOnMouseMove函数里
void CRectangleMoveView::OnMouseMove(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值// 我们只考虑鼠标可以移动时鼠标的移动事件if (true == m_IsReadyToMove){SetCursor(LoadCursor(NULL, IDC_SIZEALL)); // 设置光标为八个方向   // 利用当前鼠标位置和初始记录的位置来修改矩形的每个顶点,做到图随鼠标动的效果for (int i = 0; i < 4; i++){m_Points[i] += point - p1;}p1 = point;}// 触发OnDraw函数,动态效果Invalidate(FALSE);CView::OnMouseMove(nFlags, point);
}
  • 7.在OnLButtonUp函数里
void CRectangleMoveView::OnLButtonUp(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值// 如果可以移动if (true == m_IsReadyToMove){m_CurrentPen = &BlackPen;   // 修改画笔颜色为黑色p1 = NULL;      // 清空移动信息}ReleaseCapture(); // 释放鼠标捕获m_IsReadyToMove = false;   // 标记一下此时不可以移动了// 触发OnDraw函数,动态效果Invalidate(FALSE);CView::OnLButtonUp(nFlags, point);
}

6.总结

  • 本人能力有限,希望这篇文章能帮到你

MFC学习(02) 矩形移动 (VC++6.0版本)相关推荐

  1. 九阳道人的MFC学习之旅

    九阳道人的MFC学习之旅 好记性不如烂笔头,MFC用过很多遍了,每次用完后就很久不去碰,之后就忘了怎么用MFC,现在特此记录. 文章目录 九阳道人的MFC学习之旅 1.修改程序版本信息 2.截获和处理 ...

  2. C语言入门--VC++6.0

    [适用于大一需要学计算机但完全不了解的同学] 作为一名计算机的初学者,在艰难的探索历程中,往往会遇到很多非常非常基础的问题((((*。_。)_,这种问题在很多地方都找不到解答,希望我的回答能帮到你. ...

  3. 《吕鑫:VC++6.0就业培训宝典之MFC视频教程》学习笔记 -- 第一章 Visual C++ 安装介绍...

    综述:这篇博文会记录<吕鑫:VC++6.0就业培训宝典之MFC视频教程>的学习进度 转载于:https://www.cnblogs.com/SunnyD/p/7694746.html

  4. VC++6.0及MFC基础知识

    VC++6.0及MFC基础知识 这是早期的学习笔记,今天翻出来,觉得还有点价值,就转发到这里. Visual C++ 6.0的主界面 VC++6.0的MFC Windows 的三大模块就是以DLL( ...

  5. 使用VC++6.0创建MFC对话框程序

    使用VC++6.0创建MFC对话框程序

  6. VC++ 6.0 C8051F340 MFC programming note

    /*************************************************************************************** VC++ 6.0 C8 ...

  7. 入门学习C语言需要使用vc++6.0吗?

    提到VC++便会顺带提一下网上吐槽最多到谭浩强的C语言教材,回顾我以前入门学习C语言到的时候,看的第一本书也是这一本. 这么多年过去了,尽管网上吐槽得很多,但很多大学还是使用这一本教材,还在使用VC+ ...

  8. vc++6.0:MFC写的一个汉字取模软件(附源码)

    vc++6.0:MFC写的一个汉字取模软件(附源码) 一.毕业有九年了,突然想起以前在大学时候用MFC写的一个汉字取模软件.主要的功能是在PC上获取汉字16X16点阵数据然后通过串口把点阵数据发送给A ...

  9. VC++6.0+MFC网络聊天工具(含源码)

    毕业一年多了,晒晒自己做的毕业设计,VC++6.0+MFC完成,所有代码都是自己一步步编写完成,当初也没有什么经验,全靠网上找资料试验,大家有意见轻拍. 功能包括: 0.普通聊天(文字.图片) 1.聊 ...

最新文章

  1. excel html modify,在Excel 2010中修改Series对象上的Z-index(Modify Z-index on Series object in Excel 2010)...
  2. Vim 相关插件整理
  3. select子句顺序
  4. Matlab画图中的小技巧
  5. Java 中textarea 换行,textarea 中的换行符
  6. 网信集团:一直在正常运营 高管被带走消息不实
  7. Using SQLite database in your Windows 10 apps
  8. php 获取刚插入的一条,php获得刚插入数据的id 的几种方法
  9. oracle rman optimization,关于RMAN中的优化(Optimization)
  10. 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第1节 网络通信概述_5_端口号...
  11. java删除文件和文件夹
  12. Excel 技巧大全之 01 如何将公式应用于 Excel 中的整列(5 种简单方法)
  13. Google Guice 快速入门
  14. Qt编写安防视频监控系统23-图片地图
  15. Day11 Dear Japanese English Learners
  16. 利用科来数据包播放器实现网络数据回放
  17. 商场三十六计——第29计 “树上开花”
  18. linux系统输入法进程怎么关闭,快速解决linux下中文输入法问题
  19. 医学影像工作站程序ProDicom的说明
  20. 华为机顶盒问题奇怪处理!!!

热门文章

  1. 小程序云开发无服务器实现实时通信
  2. [JavaScript]获取鼠标点击区域的相对、绝对位置坐标
  3. java模拟银行存取_JAVA模拟银行存钱,取钱操作以及计算利息操作
  4. 打印机打印错误修理小经验
  5. 2023 年第三届长三角高校数学建模竞赛赛题浅析
  6. [极客大挑战 2019]Secret File 1解题思路
  7. 最新公司法中的九种连带责任及解读
  8. thiel熵计算_彼得·泰尔(Peter Thiel)的前参谋长现在有五百亿美元的五角大楼预算
  9. 【译】操作系统:线程
  10. Python+Vue计算机毕业设计个人博客网站hsvav(源码+程序+LW+部署)