MFC里多文档多视图+多线程动态计算、绘制曲线
来源:互联网 发布:java rs232c 编辑:程序博客网 时间:2024/06/03 12:12
对于初学MFC多线程的,我建议看一看《Windows环境下的多线程编程原理与应用--王险峰》一书,里面代码实例较多,适合初学者理解MFC里的工作、界面多线程及线程间通信。
对于MFC里多线程的原理,不做过多介绍,可以看书获得。下面是我在MFC里,使用MDI框架,多文档/多视图(View)里同步绘制动态数据曲线的实现。
对应MFC里多文档/多视图的学校,推荐看侯捷的《深入浅出MFC》。
(本实例主要完成以下工作:
(1)、利用VS2010创建MDI工程;
(2)、在主.cpp文件中注册多个文档模板;
(3)、重新OnFileNew()函数,使得重新执行或New时显示自己要求的View视图窗口;
(4)、利用MFC的界面多线程CWinThread类进行界面多线程的建立;
(5)、利用全局数组的形式在和类之间传递数据;
该工程是基于VS2010的,完整源代码可在我得Github里下载:https://github.com/LuoKuanH/MultiThread
1、 利用VS2010创建MDI工程项目
2、在主cpp里注册多文档模板
// Draw.h : Draw 应用程序的主头文件//#pragma once#ifndef __AFXWIN_H__#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"#endif#include "resource.h" // 主符号// CDrawApp:// 有关此类的实现,请参阅 Draw.cpp//class CDrawApp : public CWinAppEx{public:CDrawApp();CMultiDocTemplate* m_pTemplateTime;//创建文档模板1,用于绘制时域图CMultiDocTemplate* m_pTemplateDFT;//创建文档模板2,用于绘制实时DFT图// 重写public:virtual BOOL InitInstance();virtual int ExitInstance();// 实现UINT m_nAppLook;BOOL m_bHiColorIcons;virtual void PreLoadState();virtual void LoadCustomState();virtual void SaveCustomState();afx_msg void OnAppAbout();afx_msg void OnFileNew();DECLARE_MESSAGE_MAP()afx_msg void OnDraw();};extern CDrawApp theApp;
BOOL CDrawApp::InitInstance(){...... // 注册应用程序的文档模板。文档模板// 将用作文档、框架窗口和视图之间的连接//CMultiDocTemplate* pDocTemplate;m_pTemplateTime = new CMultiDocTemplate(IDR_DrawTYPE, //注册时域视图模板RUNTIME_CLASS(CDrawDoc),RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CMainView));if (!m_pTemplateTime)return FALSE;AddDocTemplate(m_pTemplateTime);m_pTemplateDFT = new CMultiDocTemplate(IDR_DrawTYPE, //注册频域视图域模板RUNTIME_CLASS(CMainDoc),RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CDFTView));if (!m_pTemplateDFT)return FALSE;AddDocTemplate(m_pTemplateDFT);......}
然后在主cpp里重写OnFileNew()函数,使得新建文件时,同时打开两个用于绘图的View视图
ON_COMMAND(ID_FILE_NEW, OnFileNew)void CDrawApp::OnFileNew(){//CDrawApp *pMyApp = (CDrawApp * )AfxGetApp();//CMultiDocTemplate* m_pTemplateTime = pMyApp->m_pTemplateTime;m_pTemplateTime->OpenDocumentFile(NULL);m_pTemplateDFT->OpenDocumentFile(NULL);}此时当开始执行程序,或者新建时,灰同时显示两个View视图:
3、在菜单栏添加菜单命令:
CaptionID设置Prompt更新数据ID_REDATA默认两个View同时绘图在Drawdoc里添加该菜单命令的响应函数:DrawDoc.cpp
BEGIN_MESSAGE_MAP(CDrawDoc, CDocument)ON_COMMAND(ID_REDATA, &CDrawDoc::OnRedata)END_MESSAGE_MAP()void CDrawDoc::OnRedata(){// TODO: 在此添加命令处理程序代码pDFTThread = AfxBeginThread(RUNTIME_CLASS(CMainThread));pDrawThread = AfxBeginThread(RUNTIME_CLASS(CViewThread));pThread = AfxBeginThread(Calculate,this);
UINT Calculate(LPVOID pParam){CDrawDoc *pdoc = (CDrawDoc*)pParam;CViewThread *pdrawThrd = (CViewThread*)(pdoc->pDrawThread);CMainThread *pUIThrdd = (CMainThread*)(pdoc->pDFTThread);//CViewThread *pdlgThrd = (CViewThread*)(pdoc->pPROSThread);for (int i =0; i<100; i++){datax[i] = i;datay[i] = i*i/2;data = i;pdrawThrd->PostThreadMessage(WM_SHOW_VI,NULL,NULL);//pdlgThrd->PostThreadMessage(WM_PROS,NULL,NULL);pUIThrdd->PostThreadMessage(WM_SHOW_DFT,NULL,NULL);Sleep(10);}return 0;}
响应该菜单命令的函数主要是创建两个界面多线程和一个工作线程,其中Calculate()函数是工作线程,用于实时计算数据,然后利用两个界面线程,实现显示计算出来的数据。
4、由MFC的界面多线程类CWinThread派生class CMainThread : public CWinThread,线程间通信采用消息传递法方式。
线程间通信采用消息传递法,在两个派生的界面线程中,添加对应的消息响应函数
CMainThread
#define WM_SHOW_DFT WM_USER + 3...afx_msg void ShowDFT(WPARAM wParam,LPARAM lParam);...BEGIN_MESSAGE_MAP(CMainThread, CWinThread)ON_THREAD_MESSAGE(WM_SHOW_DFT,ShowDFT)END_MESSAGE_MAP()...// CMainThread 消息处理程序void CMainThread::ShowDFT(WPARAM wParam,LPARAM lParam){POSITION curTemplatePos = theApp.GetFirstDocTemplatePosition();CDocTemplate *m_doc=theApp.GetNextDocTemplate(curTemplatePos);CDocTemplate *m_doc1=theApp.GetNextDocTemplate(curTemplatePos);//文档模板//获得文档:curTemplatePos=m_doc1->GetFirstDocPosition();CMainDoc *m_pdoc=(CMainDoc*)m_doc1->GetNextDoc(curTemplatePos);//获得视图:curTemplatePos=m_pdoc->GetFirstViewPosition();CDFTView *m_dview;while(curTemplatePos !=NULL){m_dview = (CDFTView*)m_pdoc->GetNextView(curTemplatePos);if (m_dview->IsKindOf(RUNTIME_CLASS(CDFTView))){m_dview->drawline();//调用相应视图的绘图函数进行曲线绘制}else{}}}上述的ShowDFT()函数里,主要功能是遍历程序的文档模板及文档视图,遍历找到需要的View类,并利用对应的View类调用该View对应的drawline()函数进行曲线绘制。
线程间的数据传递采用全局变量的方式:
定义两个全局数组int datax[100];int datay[100];用于保存计算的数据,同时用于数据传递至界面线程里面进行曲线绘制(本实例较简单,通过Calculate()函数实现更新数据,然后两个界面线程利用此数据进行简单的直线绘制);
本例中,两个界面线程分别使用MainView和DFTView进行曲线绘制,因此,在这两个View中,分别加入函数drawline();
MainView.cppj及DFTview.cpp
// CMainViewextern int datax[100];extern int datay[100];void CMainView::drawline(){CClientDC dc (this);CPen pen1(PS_SOLID,1,RGB(0,255,0)); ////建立一个画笔类对象,构造时设置画笔属性dc.SelectObject(&pen1);for (int i=0; i<100; i++){dc.MoveTo(datax[i],150);dc.LineTo(datay[i],150);//Sleep(10);}}
5、结果显示
当我们把鼠标单击上面一个视图后,点击菜单栏的更新数据命令,便可以看到两个View里的直线同步绘制,从左至右。
注意:由于本实例代码中使用了两个文档注册文档模板,而菜单命令只在DrawDoc文档里进行的响应,因此,我们绘图是需要将焦点定位于与DrawDoc关联的View(及上面一个View里,才能响应我们的“更新数据”菜单命令);总结:这只是我自己实现的一个例子,可能有很多问题,希望指正。刚开始学习写博客,感觉好多话说不清楚。该实例的完整源码可在我的GitHub里下载,链接在上方。
对应MFC实现多文档多视图,首先需要在主cpp里注册多个文档模板,然后如果想要程序开始时或新建时显示特定View,需要重新主cpp里的OnFileOpen()和OnFileNew()函数。对应变量的传递,我苦于只想到使用全局变量的方式,应该还有更好的方式。
- MFC里多文档多视图+多线程动态计算、绘制曲线
- MFC中绘制动态曲线
- MFC中绘制动态曲线
- MFC中绘制动态曲线
- MFC 单文档多视图
- MFC单文档多视图
- 单文档多视图+MFC多文档多视图编程
- mfc绘制曲线
- MFC Windows程序设计--多文档多视图
- MFC单文档中创建多视图
- MFC单文档中创建多视图
- mfc 多文档 静态视图分拆
- 基于单文档的VC++动态曲线绘制
- 基于单文档的VC++动态曲线绘制
- 【MFC】多文档多视图工程:视图间消息发送
- 动态曲线绘制方法
- Matlab绘制动态曲线
- R绘制动态曲线
- bundle install时报错Could not fetch specs from http://ruby.taobao.org/
- 延迟渲染的一些思考
- 将0,1,3,4,5,6等转化成0~1点,3点,4~6点
- Android之android studio如何把项目分享到github并提修改的代码到Github
- 在11g安装 XML DB 组件
- MFC里多文档多视图+多线程动态计算、绘制曲线
- 10795 - A Different Task
- YII 2 配置
- 工厂模式简单理解
- explicit关键字
- 胡玉洋《三分钟学会JUnit单元测试》
- 将form表单序列化
- RedHat 安装和配置samba服务器
- 如何查看 静态库(.a) ? 还有其他库文件 比如动态库(.so) 目标文件(.o)