一 介绍
本文将以一个实例来说明如何将WPF技术集成在基于MFC的应用程序中 这种技术的主要目的是为了增强基于Win /MFC的应用程序的在图形方面的表现能力 本文所提供的演示程序将在MFC对话框架应用程序中显示一个WPF动画时钟 界面如图 所示
本文需要的开发工具和开发库 为了建立和运行demo程序 我们需要安装如下的组件
Visual Studio 或Visual Studio NET Framework 或 NET Framework
所需要的平台 demo程序必须在下面支持 NET Framework 的 *** 作系统平台上运行
Windows Vista Windows XP SP Windows Server SP
如果你是一名C++开发人员 并且想使用WPF技术来增强自己的基于Win /MFC应用程序 本文非常适合你 为了能从本文学习到更多的知识 我们需要熟悉VC++/CLi MFC XAML和C# 但是 如果我们不了解C#或XAML 我们仍然可以通过引用现成的DLL来使用WPF程序
二 什么是WPF
WPF是Windows Presentation Foundation的缩写 它是微软 NET Framework 的一个子系统 这种技术允许开发人员高效地创建可视化的应用程序 并改善用户体验 由于WPF的发布 使用Windows程序在富控件的设计 开发上更如虎添翼 WPF主要关注一套应用程序服务 用户接口 D和 D 矢量图 动画 数据绑字 音频 并提供一个在UI和商业逻辑之间的非常清晰的界限
WPF API是被管制的代码 但是大多数Win /MFC程序是非管制的C++代码 按著惯例 WPF API不能通过非常制程序调用 然后 通过使用VC编译器的/clr选项 我们可以建立一个由管制和非管制混合而面的系统 在这个系统中 我们可以使管制和非管制代码无缝地混合在一起
有一个要注意的是在C++工程中不允许编译XAML文件 因此 我们必须建立一个包含在本例中所需要的所有XAML而的C# DLL 然后在C++工程中包含这个Dll引用
有两种基本的技术可以融合WPF和Win /MFC代码
将WPF放到Win /MFC程序中 使用这种技术 开发人员可以使用WPF的高级图形能力来渲染Win /MFC应用程序
将Win /MFC放到WPF中 使用这种技术 开发人员可以在WPF中使用已经存在的
Win /MFC控件 并通过一定的机制来传递数据
在本文中将采用第一种方法
三 融合Win /MFC和WPF程序
上面部分所说的是本例的基本规则 下面在本节中将介绍如何编写具体的实现代码 在本例中 我首先会演示使用XAML和C#建立WPF内容 并在VC++中引用这个DLL
本例的目的是建立一个用于设置日期和时间的设置工具 其中动画部分使用WPF实现 程序的其他部分仍然使用MFC实现
这个演示程序由两部分组成 一个是MFCHostMPF(由VC++/MFC代码组成) 另一个是WPFControls(由XAML和C#代码组成) 这个MFCHostWPF工程将由WPFControls工程所产生的DLL作为一个外部的引用 如图 所示
向MFC工程中加入一个WPF引用 如图 和图 所示
三 在MFC应用程序中加入和WPF相关的代码
先提一下 gcnew关键字被用于建立一个管制类型的实例 在本例中将建立一个垃圾回收集合栈的实例 所有被gcnew分配的内存空间将被垃圾回收器自动管理 而开发人员并不需要为什么时间释放它们而 *** 心
为了使用WPF程序 关键是System::Windows::Interop::HwndSource类 这个类将在Win 窗口中使用WPF程序 因此 WPF程序可以作为MFC窗口的子窗口放到UI上 而在WPF对象和Win 窗口之间的通讯要通过引用C++程序中被存储的静态字段 这些静态字段的代码如下
ref class Globals { public: static System::Windows::Interop::HwndSource^ gHwndSource; static WPFControls::AnimClock^ gwcClock; };
HWND hwndWPF; // 和WPF相关的hwnd 为了建立一个HwndSource 首先需要建立一个HwndSourceParameters结构 这个结构需要如下的参数 类 窗口 窗口类型 窗口的初始位置 窗口的初始尺寸 父窗口 一但我们将HwndSourceParameters结构编写完 就可以将这个结构到HwndSource的构造方法HwndSource(HwndSourceParameters)中 最后 我们将WPF时钟的引用赋值给HwndSource对象的RootVisual属性 并通过调用Handle ToPointer()返回HwndSource的HWND 代码如下HWND GetHwnd(HWND parent int x int y int width int height) { System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters ( MFCWPFApp ); sourceParams >PositionX = x; sourceParams >PositionY = y; sourceParams >Height = height; sourceParams >Width = width; sourceParams >ParentWindow = IntPtr(parent); sourceParams >WindowStyle = WS_VISIBLE | WS_CHILD; Globals::gHwndSource = gcnew System::Windows::Interop::HwndSource(sourceParams); DateTime tm = DateTime::Now; Globals::gwcClock = gcnew WPFControls::AnimClock(); Globals::gwcClock >ChangeDateTime(tm Year tm Month tm Day tm Hour tm Minute tm Second); FrameworkElement^ myPage = Globals::gwcClock; Globals::gHwndSource >RootVisual = myPage; return (HWND) Globals::gHwndSource >Handle ToPointer(); }
因此 无论用户如何变化时钟 我们的MFC代码都会调用RefereshWPFControl()来刷新WPF时钟void RefreshWPFControl() { FrameworkElement^ page; DateTime tm = DateTime::Now; Globals::gwcClock >ChangeDateTime(tm Year tm Month tm Day tm Hour tm Minute tm Second); page = Globals::gwcClock; Globals::gHwndSource >RootVisual = page; return; }
现在我们已经有了大部分我们需要的功能了 而最后的任务是在MFC对话框代码中找个地方调用HwndSource实现创建函数 当然 有很多地方可以做这个工作 但是OnCreate也许是最好的位置 在OnCreate事件句柄中调用GetHwnd()函数的代码如下int CMFCHostWPFDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDialog::OnCreate(lpCreateStruct) == ) return ; hwndWPF = GetHwnd(this >GetSafeHwnd() ); return ; }
四 结论 lishixinzhi/Article/program/net/201311/11996
你可以尝试将构造函数和析构函数一起导出,并且,将编译DLL文件时生成的LIB文件添加到调用DLL的项目中
如果还不行,请将定义DLL的头文件贴出来分析
------------------------------------------------------------------
补充:
MFC扩展DLL只能由MFC的应用程序调用,请问你调用DLL的程序是什么类型
工程-》设置-》连接,中将对象/库模块填上 E:\组态王\kingvewclienddll ;
这里不是添加dll,而是要添加lib 。
而且最好要把dll文件拷贝到你的工程的debug目录下才好。
在主app类的InitInstance里面注释掉m_pMainWnd->ShowWindow(SW_SHOW);
然后加上m_nCmdShow = 0;,这个必须加在AddDocTemplate(pDocTemplate);之前,最好放在开头。
尝试以下办法:
右键VS2013图标,选择以管理员权限运行。
关闭VS2013,将工程目录复制到D盘,重新在D盘打开工程,完整重新编译后运行。
另外还有一个可能,注意查看编译过程是否有错误警告,如果有,需要先完善代码。
为什么我编译的MFC应用程序在其他电脑上不能运行?
因为其他的电脑上没有相关的运行库,因此无法运行。 但可以这样解决,打开工程或项目的属性,在常规选项卡中设置:使用MFC作为静态链接库(不同版本的描述不尽相同,但都有静态两个字),设置后再编译就可以了。
如何在其他电脑上运行VS2005编译的DEBUG版应用程序首先,通过菜单找到关于选项查询当前VS2005的版本,然后到自己电脑"$(Windows)/WinSxS/"目录下可以看到很多长长 名字的目录。第一个"_"前为平台,这里以x86为例,接下来找到带有"MicrosoftVC80DebugCRT" 和"MicrosoftVC80DebugMFC"字样的且包含上面版本号的目录。我的电脑目录如下:
x86_MicrosoftVC80DebugCRT_1fc8b3b9a1e18e3b_8050727762_x-ww_5490cd9f x86_MicrosoftVC80DebugMFC_1fc8b3b9a1e18e3b_8050727762_x-ww_257740a4
将这两个目录拷贝到目标电脑的"$(Windows)/WinSxS/"位置,进入"$(Windows)/WinSxS/Manifests/"目录,用上面的方法找到四个文件并拷贝到目标电脑的相同目录中,我的电脑文件如下:
x86_MicrosoftVC80DebugCRT_1fc8b3b9a1e18e3b_8050727762_x-ww_5490cd9fcat以及manifest文件
x86_MicrosoftVC80DebugMFC_1fc8b3b9a1e18e3b_8050727762_x-ww_257740a4cat以及manifest文件
最后一步,进入"$(Windows)/WinSxS/Policies/"目录,找到带有"MicrosoftVC80DebugCRT"和"MicrosoftVC80DebugMFC"字样的两个目录将其拷贝到目标电脑的相同目录,我的电脑目录如下:
x86_policy80MicrosoftVC80DebugCRT_1fc8b3b9a1e18e3b_x-ww_09e017b4
x86_policy80MicrosoftVC80DebugMFC_1fc8b3b9a1e18e3b_x-ww_a193936f
到 此,所有需要的文件都拷贝结束了,运行刚刚的应用程序,显示了我们熟悉的错误信息:"This application has failed to start because XXXdll was not found Re-installing the application may fix this problem"
编写好的C程序如何才能变成EXE应用程序在其他不装有C编译系统的电脑上运行?这个要看你是用什么样的编译器
Win-TC\projects的话 里头有编译好的 exe文件,不过复制出来以后就运行不了。因为TC是16位的,而WINDOWS是32位的
要是用vc60那就简单多了。
在“工程”->“设置”中的“常规”选项卡,
Microsoft基础类:
选择“使用MFC作为静态链接库”。
这样生成的EXE文件可以在没有安装VC++的电脑上运行了。
生成的EXE文件在Debug或者Release文件夹下。
其他的编译器我不清楚
VC编译的Win32应用程序不能在Windows 7运行,win32应用程序是什么,为什么叫Win32有点莫名其妙Windows 32位应用程序。
你一定用了什么非开放的API接口,所以不能用。
电脑C盘里的应用程序能不能防在其他盘里运行啊可以,但你得修改路径,注册表,非常麻烦,如果是单个的程序,你可以找到启动的图标然后发送到桌面系统程序一般还是不要乱动,别把除了系统程序之外的程序或软件给C盘安装,很容易感染C盘中毒的
在VS2005中用VC#编译的程序为什么在其他机器运行不了
编好后当然不能就直接用了,要对程序进行打包:创建项目→项目类型→其他类型→安装和部署→安装向导。
为什么Qt编译的程序不能在XP上运行使用qt57以下的版本,在xp下依赖库和其他 *** 作系统不同,好像有个windowsdll
MFC生成的exe程序不能在其他电脑上运行怎么办depend。exe 查一查你的程序依赖那些dll copy过去,否则请 静态 + release 重新编译
在其他店(电脑城里的)下载应用程序后 为什么无法从电脑itunes上下载应用程序到iphone首先,你需要注册账户(详细教程::hibaidu/wongstephanie/blog/item/4d57da14168f4bd9c3fd78bc)
然后对电脑进行授权(打开iTunes,点击“Store”—“对这台电脑授权”)才能安装应用程序;
其次,登录以后你点击应用程序购买然后下载安装就好了;
最后,当你使用自己的电脑的iTunes库同步时,你的iphone内原有的程序也会被抹掉的。
怎么我用c++ builder60编的一个小程序在其他电脑上不能运行在程序编译的时候,你需要把程序用到东西都打包到EXE文件中,如下 *** 作:
在Options 中,把Packages--build with runtime packages前的勾去掉
把linker-- use dynamic rtl前的勾去掉
另外,如果你用了数据库功能,那么,你必须把数据库支撑文件放到运行程序的电脑中,因为数据库支撑包不能与EXE文件一起封装
MFC可以通过调用SetWindowPos函数来实现对外部exe的置顶 *** 作,具体 *** 作步骤如下:
1 获取外部exe的句柄;
2 调用SetWindowPos函数,将第一步获取的句柄作为参数,并设置相应的属性;
3 通过调用UpdateWindow函数更新窗口,完成置顶 *** 作。
以上就是关于在MFC中使用WPF技术全部的内容,包括:在MFC中使用WPF技术、在VS2010中MFC扩展DLL导出CWnd的子类,外部程序调用时出现LNK2019错误,找不到构造和析构函数、现在只有一个外部程序中的dll文件,在VC++MFC中调用它获取数据等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)