经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
VS2019实现C++的第一个MFC程序
来源:jb51  时间:2021/6/7 13:21:54  对本文有异议

一、创建项目


然后点下一步,配置项目,这里我命名的是myfisrtmfc

点击创建按钮,然后弹出下面的对话框。

对上面的MFC应用程序进行配置,如下:

点击完成,生成如下界面。

第一次编译生成的默认项目,之后得到下面的界面

点击VS2019的界面,“解决方案资源管理器”

到这里,项目建成,并且编译通过。

二、添加自定义的功能(以比较通用的画图为例)

点击资源视图,这里的控件将是后面需要操作的。

双击IDR_MAINFRAME,可以在这里面添加画图功能。

也可以在Ribbon里面添加画图功能

然后点击工具箱->RIbbon编辑器:

双击Ribbon下的面板控件

修改名称为形状,并添加一个按钮控件,修改名字为矩形

修改矩形的杂项,ID改为ID_RECTANGLE

右键矩形按键,选择添加事件处理程序

得到如下弹窗

配置这个弹窗如下:

点击确定后,我们得到下面的代码

以下内容参考https://www.jb51.net/article/214347.htm

第一次使用c++,mfc很多函数都不熟悉,就直接套用了。

这里我们新建一个graph.cpp源文件

  1. #include "framework.h"
  2. #include "pch.h"
  3.  
  4. IMPLEMENT_SERIAL(graph, CObject, 1)
  5. graph::graph(int l, int u, int r, int d)
  6. {
  7.     left = l;
  8.     up = u;
  9.     right = r;
  10.     down = d;
  11.     state = 0;
  12.     fcolor = 0xffffff;
  13. }
  14.  
  15. void graph::Offset(int cx, int cy)
  16. {
  17.     left += cx;
  18.     right += cx;
  19.     up += cy;
  20.     down += cy;
  21. }
  22.  
  23. void graph::onPress(int x, int y)
  24. {
  25.     sx = x; sy = y;
  26.     state = 0;
  27.     //选中图形
  28.     if (left < x && x < right &&
  29.         up < y && y < down) {
  30.         state = 1;
  31.         return;
  32.     }
  33.     if (left - f_width / 2 < x && x < left + f_width / 2)    state |= 2;    //    选中左边
  34.     if (up - f_width / 2 < y && y < up + f_width / 2)    state |= 4;//选中上边
  35.     if (right - f_width / 2 < x && x < right + f_width / 2)    state |= 8;//选中右边
  36.     if (down - f_width / 2 < y && y < down + f_width / 2)    state |= 16;    //    选中下边
  37.  
  38. }
  39.  
  40. void graph::onRelease(int x, int y)
  41. {
  42.     state = 0;
  43. }
  44.  
  45.  
  46. void graph::SetBorderColor(int color)
  47. {
  48.     fcolor = color;
  49. }
  50.  
  51. void graph::SetFillColor(int color)
  52. {
  53.     bcolor = color;
  54. }
  55. int graph::onMove(int x, int y)
  56. {
  57.     int cx, cy;
  58.     cx = x - sx; cy = y - sy;
  59.     sx = x; sy = y;
  60.  
  61.     if (state == 1) {
  62.         Offset(cx, cy);        //  位移量cx,cy
  63.     }
  64.  
  65.     if (2 == (state & 2)) {
  66.         left = x;
  67.  
  68.     }
  69.  
  70.     if (4 == (state & 4)) {
  71.         up = y;
  72.  
  73.     }
  74.  
  75.     if (8 == (state & 8)) {
  76.         right = x;
  77.  
  78.     }
  79.  
  80.     if (16 == (state & 16)) {
  81.         down = y;
  82.  
  83.     }
  84.     return state == 0 ? 0 : 1;
  85. }
  86. void graph::Serialize(CArchive& ar)
  87. {
  88.     CObject::Serialize(ar);
  89.     if (ar.IsLoading()) {
  90.         ar >> left >> right >> up >> down >> f_width >> fcolor >> bcolor;
  91.     }
  92.     else
  93.     {
  94.         ar << left << right << up << down << f_width << fcolor << bcolor;
  95.     }
  96. }
  97. graph::~graph()
  98. {
  99. }
  100. void graph::onDraw(CDC* pDC) {
  101.     CBrush b(fcolor);
  102.     pDC->SelectObject(&b);
  103.     CRect r(left, up, right, down);
  104.     pDC->FillRect(&r, &b);
  105.     CPen p(PS_SOLID, 1, bcolor);
  106.     pDC->SelectObject(&p);
  107.     pDC->Rectangle(left, up, right, down);
  108.     pDC->MoveTo(left, up);
  109.     pDC->DrawText(_T("空图形"), -1, new CRect(left, up, right, down), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  110. }

在项目中添加头文件graphz.h

在graph.h中添加下面的代码:

  1. #pragma once
  2. class graph :
  3. public CObject
  4. {
  5. protected:
  6. //边框
  7. DECLARE_SERIAL(graph)
  8. int left, up, right, down;
  9. //选中状态
  10. unsigned int state;
  11. int sx, sy;
  12. int f_width = 5;
  13. int fcolor = 0xffffff, bcolor = 0;
  14. public:
  15. graph() :graph(50, 50, 100, 100) {
  16. }
  17. graph(int l, int u, int r, int d);
  18. void Offset(int cx, int cy);
  19. void onPress(int x, int y); // 鼠标按下
  20. int onMove(int cx, int cy); // 鼠标移动
  21. void onRelease(int x, int y); // 鼠标释放
  22. virtual void onDraw(CDC* pDC);
  23. virtual int getGraphID() { return 0; }
  24. virtual void Serialize(CArchive& ar);
  25. void SetFillColor(int color);
  26. void SetBorderColor(int color);
  27. ~graph();
  28. };

在framework.h中添加graph.h

  1. #include "graph.h"

我们要画矩形,这里添加矩形的相关代码,

跟上面的步骤一样,见一个rectangle.h和rectangle.cpp

rectangle.cpp

  1. #include "framework.h"
  2. #include "pch.h"
  3. rectangle::rectangle(int l, int u, int r, int d) :graph(l, u, r, d)
  4. {
  5.     state = 0;
  6.     fcolor = 0xffffff;
  7.  
  8. }
  9.  
  10. void rectangle::onDraw(CDC* pDC)
  11. {
  12.     CBrush b(fcolor);
  13.     pDC->SelectObject(&b);
  14.     CRect r(left, up, right, down);
  15.     pDC->FillRect(&r, &b);
  16.     CPen p(PS_SOLID, 1, bcolor);
  17.     pDC->SelectObject(&p);
  18.     pDC->Rectangle(left, up, right, down);
  19.     pDC->MoveTo(left, up);
  20. }
  21.  
  22. rectangle::~rectangle()
  23. {
  24. }

rectangle.h

  1. #include "graph.h"
  2. class rectangle :
  3.     public graph
  4. {
  5. public:
  6.     //DECLARE_SERIAL(graph)
  7.     //void Serialize(CArchive& ar);
  8.     rectangle() :graph(50, 50, 100, 100) {}
  9.     rectangle(int l, int u, int r, int d);
  10.     void onDraw(CDC* pDC);
  11.     int getGraphID() { return 2; }
  12.     ~rectangle();
  13. };

然后myfirstmfcDoc.h中添加list

  1. std::list<graph*> graphList;

因为调用了list,所以在framework.h中添加

  1. #include <list>


这里要调用用OnRectangle()函数,之前生成的函数,我们现在添加下面的代码:

  1.     CmyfisrtmfcDoc* pDoc = GetDocument();
  2.     ASSERT_VALID(pDoc);
  3.     if (!pDoc)
  4.         return;
  5.     pDoc->graphList.push_front(new rectangle(50, 50, 100, 100));
  6.  
  7.     Invalidate();

修改myfirstmfcView.cpp中的OnDraw函数为如下:


  1. void CmyfisrtmfcView::OnDraw(CDC* pDC)
  2. {
  3.     CmyfisrtmfcDoc* pDoc = GetDocument();
  4.     ASSERT_VALID(pDoc);
  5.     if (!pDoc)
  6.         return;
  7.  
  8.     // TODO: 在此处为本机数据添加绘制代码
  9.     std::list<graph*>::iterator v;
  10.     for (v = pDoc->graphList.begin(); v != pDoc->graphList.end(); ++v) {
  11.         (*v)->onDraw(pDC);
  12.     }
  13. }

接下来通过类向导添加消息

添加鼠标左键按下消息,左键松开消息,鼠标移动消息

在生成的按键按下函数中

  1. void CmyfisrtmfcView::OnLButtonDown(UINT nFlags, CPoint point)
  2. {
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值
  4.     CmyfisrtmfcDoc* pDoc = GetDocument();
  5.     ASSERT_VALID(pDoc);
  6.     if (!pDoc)
  7.         return;
  8.  
  9.     // TODO: 在此处为本机数据添加绘制代码
  10.     std::list<graph*>::iterator v;
  11.     for (v = pDoc->graphList.begin(); v != pDoc->graphList.end(); ++v) {
  12.         (*v)->onPress(point.x, point.y);
  13.     }
  14.     Invalidate();
  15.     //CView::OnLButtonDown(nFlags, point);
  16. }

跟上面一样的方式

自从生成的代码在myfirstmfcView中如下:

  1. void CmyfisrtmfcView::OnLButtonUp(UINT nFlags, CPoint point)
  2. {
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值
  4.     CmyfisrtmfcDoc* pDoc = GetDocument();
  5.     ASSERT_VALID(pDoc);
  6.     if (!pDoc)
  7.         return;
  8.  
  9.     // TODO: 在此处为本机数据添加绘制代码
  10.     std::list<graph*>::iterator v;
  11.     for (v = pDoc->graphList.begin(); v != pDoc->graphList.end(); ++v) {
  12.         (*v)->onRelease(point.x, point.y);
  13.     }
  14.  
  15.     //CView::OnLButtonUp(nFlags, point);
  16. }
  17.  
  18.  
  19. void CmyfisrtmfcView::OnMouseMove(UINT nFlags, CPoint point)
  20. {
  21.     // TODO: 在此添加消息处理程序代码和/或调用默认值
  22.     CmyfisrtmfcDoc* pDoc = GetDocument();
  23.     ASSERT_VALID(pDoc);
  24.     if (!pDoc)
  25.         return;
  26.  
  27.     // TODO: 在此处为本机数据添加绘制代码
  28.     std::list<graph*>::iterator v;
  29.     for (v = pDoc->graphList.begin(); v != pDoc->graphList.end(); ++v) {
  30.         (*v)->onMove(point.x, point.y);
  31.     }
  32.     Invalidate();
  33. //    CView::OnMouseMove(nFlags, point);
  34. }

到这里就完成了全部工作,可以进行编译了。

生成下面的图形,矩形可以移动,可拉伸

点击项目中的属性,在配置属性中选择高级,MFC使用 静态库,在编译一次,生成.exe可以其他电脑上不依赖动态库也能打开了。

总结:

1.学会了如何添加项目工程

2.学会了添加用户自己的源文件和头文件,并且与项目关联

3.学会了类向导

4.学会了按键控件的生成,和通过消息ID跟函数关联起来

参考文献:

(1)vs2019 MFC实现office界面的画图小项目(超超级详细)

(2)在vs2019中使用MFC快速构建简单windows窗口程序

到此这篇关于VS2019实现C++的第一个MFC程序的文章就介绍到这了,更多相关C++第一个MFC程序内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号