在Win中嵌入MFC对话框设计实现.doc_第1页
在Win中嵌入MFC对话框设计实现.doc_第2页
在Win中嵌入MFC对话框设计实现.doc_第3页
在Win中嵌入MFC对话框设计实现.doc_第4页
在Win中嵌入MFC对话框设计实现.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Winform中嵌入MFC对话框设计一改造MFC应用程序要将MFC的对话框嵌入到Winform中,我们的对话框必须运行在MFC的MDI程序中,因此我们一开始就必须建立一个MFC的应用程序,然后再将其改造成MFC的动态连接库。如果我们一开始就建立MFC的动态连接库的话,还要自己添加MFC的MDI框架类,比较的麻烦。如图:对于MFC的类来说(例如CDocument,CView,CMainFrame)必须依赖于CWinApp才能初始化和运行。因此我们只能将整个应用程序嵌入到winform的应用程序中。如何实现呢?那就需要.net的托管C+的支持了。我们在刚才改造好的MFC_App_View.dll(本例中改造的库)中,混入一些托管的C+类定义一些接口,通过这些接口来和Winform中的类进行通讯。这里我先将要添加的类以及接口列出来(包括一些非托管类):类 对应文件CCmdUIHandler CCmdUIHandler.h,CCmdUIHandler.cppICmdUITarget ICmdUiTarget.hCLayoutView CLayoutView.h /非托管类CDocManagerEx DocManagerEx.h,DocManagerEx.cpp /非托管类 IFramework IFramework.hIWndManager IwndManager.hIFrameworkImpl MfcAppAdapter.hMfcAppAdapter MfcAppAdapter.h, MfcAppAdapter.cppMfcCommand MfcCommand.hCMFCTemp CMFCTemp.h, CMFCTemp.cpp /非托管类CNotifyHook CnotifyHook.h, CnotifyHook.cpp /非托管类ViewCtrl ViewCtrl.h, ViewCtrl.cpp添加了上述类之后,我们的一个混合的Dll就初步改造完成了。为了使托管代码和非托管代码的混合Dll能够安全的运行,我们必须对Dll的属性进行一些相应的设置(如果不设置,编译时也会通不过),具体设置详情如下图:另外对于托管的C+类我们必须让他受到公共语言运行库的支持,在对应类的.cpp文件的属性中进行如下设置,如下图:由于ViewCtrl类是继承自Winform Control,必须添加命名空间的引用,因此在项目属性的通用属性中必须添加对应命名空间的引用,如下图:注意:在设置此项属性时,有时我们点击添加新引用按钮时,在弹出的对话框中找不到任何公共语言运行库的类,这是因为编译器并不知道我们使用了托管C+类。我们可以先将Dll设为公共语言运行库支持,再来添加引用就可以了,添加完后必须记得将Dll设为不受公共语言运行库的支持,不然编译通不过。二混合Dll的结构前面完成的只是宏观上的一些类的添加,及库的设置,现在要做的就是将Dll中的一些具体类进行修改,先看Dll的结构图:从上图还不能够很清晰的看到混合Dll是如何与winform进行交互的,但是我们可以知道,在MFC程序嵌入到winform中时MfcAppAdapter起着很中要的作用。在MfcAppAdapter中保存了IframeworkImpl(winfrom的应用程序框架),IwndManager(用控制MFC程序的激活),同时还有AttachApplication(IWndManager wndManager)负责将MFC程序附加到Winform程序中,在MfcAppAdapter销毁时,将MFC程序从winform中退出。1. MfcAppAdapter为了辅助MfcAppAdapter的AttachApplication的实现,我们要在MFC_App_View.cpp中定义两个全局函数:BOOL AttachApplication(IFramework* framework)AFX_MANAGE_STATE(AfxGetStaticModuleState();/获取当前模块状态CMFC_App_ViewApp* app = (CMFC_App_ViewApp*)AfxGetApp();return app-AttachApplication(framework);BOOL DetachApplication()AFX_MANAGE_STATE(AfxGetStaticModuleState();CMFC_App_ViewApp* app = (CMFC_App_ViewApp*)AfxGetApp();return app-DetachApplication();同时要对CMFC_App_ViewApp:InitInstance()函数进行一些修改,如下:BOOL CMFC_App_ViewApp:InitInstance()/设置模块状态、初始化dll的资源,mixMFCDll的入口点AFX_MANAGE_STATE(AfxGetStaticModuleState();InitApplication();m_pDocManager = new CDocManagerEx; / replace the default doc managerAFX_MODULE_STATE* pModuleState = AfxGetModuleState();pModuleState-m_bDLL = NULL;/INITCOMMONCONTROLSEX InitCtrls;/InitCtrls.dwSize = sizeof(InitCtrls);/InitCtrls.dwICC = ICC_WIN95_CLASSES;/InitCommonControlsEx(&InitCtrls);/CWinApp:InitInstance();AfxEnableControlContainer();SetRegistryKey(_T(MFC混合DLL程序);LoadStdProfileSettings(4); / 加载标准INI 文件选项(包括MRU)/ 注册应用程序的文档模板。文档模板/ 将用作文档、框架窗口和视图之间的连接CMultiDocTemplate* pDocTemplate;pDocTemplate = new CMFCTemp(IDR_MFC_App_ViewTYPE,RUNTIME_CLASS(CMFC_App_ViewDoc),RUNTIME_CLASS(CChildFrame), / 自定义MDI 子框架RUNTIME_CLASS(CMFC_App_ViewView);if (!pDocTemplate)return FALSE;AddDocTemplate(pDocTemplate);/ 创建主MDI 框架窗口/*CMainFrame* pMainFrame = new CMainFrame;if (!pMainFrame | !pMainFrame-LoadFrame(IDR_MAINFRAME)delete pMainFrame;return FALSE;m_pMainWnd = pMainFrame;*/return TRUE;首先将CWinApp:InitInstance();注释掉,阻止程序从DllMain()进入。然后添加如下代码使CMFC_App_ViewApp类正确初始化AFX_MANAGE_STATE(AfxGetStaticModuleState();InitApplication();m_pDocManager = new CDocManagerEx; / replace the default doc managerAFX_MODULE_STATE* pModuleState = AfxGetModuleState();pModuleState-m_bDLL = NULL;最后将pMainFrame的创建部分注释掉,复制到BOOL CMFC_App_ViewApp:AttachApplication(IFramework* framework)m_IFramework = framework;/ create MainFrameCMainFrame* pMainFrame = new CMainFrame;if( !pMainFrame-LoadFrame( IDR_MAINFRAME ) )return FALSE;m_pMainWnd = pMainFrame;return TRUE;此方法也是为辅助用,还需添加对应的BOOL CMFC_App_ViewApp:DetachApplication()LRESULT lRes = 0;/ if m_pMainWnd=NULL than application detached yetif(m_pMainWnd)lRes = :SendMessage(m_pMainWnd-GetSafeHwnd(),WM_CLOSE,0,0);/关闭主窗口return lRes=0;此时我们也注意到,在CMFC_App_ViewApp中需添加一个IFramework* m_IFramework成员,方便获取winform程序的信息。2. CmainFrame我们的MFC程序与winform程序同时运行时,为了监视winform的一些消息,如 关闭、新建等,在MFC的CmainFrame类中必须添加一个CnotifyHook对象CMainFrame:CMainFrame()/Winform命令,实现命令的转发CMFC_App_ViewApp* pApp = (CMFC_App_ViewApp*)AfxGetApp(); m_pNotifyHook = new CNotifyHook(this,pApp-m_IFramework-GetExternFrame();m_bIsClosed = FALSE;对于一些关键的函数也必须重载,来确保程序的安全void CMainFrame:OnWindowNew() CMDIChildWnd* pActiveChild = MDIGetActive(); CDocument* pDocument; if (pActiveChild = NULL | (pDocument = pActiveChild-GetActiveDocument() = NULL) /AS /pTemplate-InitialUpdateFrame(pFrame, pDocument); / We make visible later pTemplate-InitialUpdateFrame(pFrame, pDocument, FALSE);void CMainFrame:OnClose() m_bIsClosed = TRUE;/ Check that we dont have views attached to control CDocManager* pDocManager = AfxGetApp()-m_pDocManager;/ no doc manager - no templatesif (pDocManager != NULL)/ we can not exit if there are outstanding component objects m_pNotifyHook-m_pFrameWnd = NULL; delete m_pNotifyHook; m_pNotifyHook = NULL; CMDIFrameWnd:OnClose();void CMainFrame:OnDestroy()if(!m_bIsClosed)TRACE(traceAppMsg, 0, Warning: destroying not detached application.n);/detache applicationthis-OnClose();elseCMDIFrameWnd:OnDestroy();在CMainFrame:PreCreateWindow 中指定CmainFrame的句柄CMFC_App_ViewApp* pApp = (CMFC_App_ViewApp*)AfxGetApp(); cs.hwndParent = pApp-m_IFramework-GetExternFrame();3. CMFC_App_ViewDoc CMFC_App_ViewDoc类也需对一些关键函数进行重载。/确保程序关闭时所有的view都已经关闭BOOL CMFC_App_ViewDoc:CanCloseFrame(CFrameWnd* pFrameArg)ASSERT_VALID(pFrameArg);UNUSED(pFrameArg); / unused in release buildsPOSITION pos = GetFirstViewPosition();/ otherwise only one frame that we know aboutreturn SaveModified();void CMFC_App_ViewDoc:UpdateFrameCounts()/ 循环所有Frame的View,记录View个数CMFC_App_ViewApp* pApp = (CMFC_App_ViewApp*)AfxGetApp(); POSITION pos = GetFirstViewPosition();while (pos != NULL)ASSERT(iFrame = nFrames + 1);4. CMFC_App_ViewViewCMFC_App_ViewView必须继承自自定义的ClayoutView类并实现里面的一些接口函数virtual void Scale(float scaleX,float scaleY)=0;virtual BOOL GetAutoSize()=0;virtual void SetAutoSize(BOOL value)=0;virtual CSize GetPreferredSize(CSize proposedSize)=0;三Winform Control的封装Winform Control 的结构如下:在CtrlComponet为Host属性指定值时调用CtrlManager的InitMFC函数,通过MfcAppAdapter将MFC程序Attach到当前winform程序中来。CtrlManager继承自IwndManager,使MFC程序能在适当的时候将窗口激活在winfrom中。在Winform中调用Cview对象显示只需对MfcAppAdapter传递MfcAppAdapter.OnCmdMsg(AS.MfcHost2.MfcCommand.FILE_NEW)就可以显示。实际上该指令传递给了CMainFrame,由他来创建一个新的Cview。而我们把对话框放在这个新建的Cview中,这样对话框就显示出来了。四ViewCtrl 类ViewCtrl类是MfcAppAdapter的辅助类,由于它的存在才能使MFC

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论