您的位置:首页 > 其它

在MFC下调用WPF控件的总结

2009-07-04 12:30 483 查看
为了在原有MFC程序上支持WPF的Ink功能,看了N天的.Net相关知识。我的机器上,开发环境实在是令人发指,如果有人碰到了我现在的问题,希望这篇文章能够对他有所帮助。

我安装了Visusal Studio 2005,.Net Framework 2.0, 3.5, 以及不知道啥时候装的3.0版本(我怀疑是安装3.5时候带进来的版本)。在我的2005的开发环境里面,找不到WPF的模版。去网上搜索,说是需要安装2005的一个extension for wpf。我很辛苦的找到了这个extension(在MS的官网上没有找到能够下载的链接),安装时候告诉我没有Framework 3.0(实际上我的磁盘上有这个版本的所有dll)。我又尝试了下载 .Net Framework3.0,安装时候告诉我已经有了更高的版本(3.5),不能继续安装3.0了。接下来我就没有继续尝试其他动作了(想先卸载3.5来着,怕影响其他project,没有这么做)。

ok,看看如何在上面这个环境下来开发WPF程序:
1,创建一个C# 应用程序。(我选择的是Console)
2,添加一个xaml页面(new或者add exist)
3,添加一个对应的c#页面(new或者add exist)
4,添加对Framework的引用,分别是PresentationCore, PresentationFramework, WindowsBase。它们应该在C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\下面。

5,Unload Project。
6,右键单击被关闭的项目,选择编辑对应的工程文件(*.csproj)。
7,找到响应的xaml文件名字,把它前面的<None 改为 <Page 。
8,找到最后面这样一行:
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
在它下面添加一行:
<Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />
9,保存工程文件,关闭。右键点击关闭的项目,选择 Reload Project

在Reload的时候,有可能visual studio 2005会提示工程文件格式的有关问题,你需要选择继续。

这样之后,就能正常编译xaml文件了。

在能够正常编译WPF项目之后,可以把该项目的输出类型更改为:类库,这样我们才能在MFC程序里面调用C#编写的WPF控件。
下面是如果在MFC程序里面调用WPF控件的步骤:

1,打开你原有的MFC程序,或者新创建一个MFC应用程序。
2,打开工程属性面板,把配置属性-常规-公共语言运行库支持(CLR)的属性更改为“公共语言运行库支持(/clr)”;
3,在通用属性里面,添加对 .Net Framework 3.0相关的运行库的引用。(和上面第四个步骤一样)
4,添加下面这段代码:
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Media;
using namespace System::Runtime;
using namespace System::Runtime::InteropServices;
using namespace System::Windows::Interop;
ref class Globals {
public:
static System::Windows::Interop::HwndSource^ gHwndSource;
static TuioInk::TuioInkCanvas^ inkCanvas;
};
HWND hwndWPF; //The hwnd associated with the hosted WPF page
HWND GetHwnd(HWND parent, int x, int y, int width, int height)
{
System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters ("TestMFCWPF");
sourceParams->PositionX = x;
sourceParams->PositionY = y;
sourceParams->Height = height;
sourceParams->Width = width;
sourceParams->ParentWindow = IntPtr(parent);
sourceParams->WindowStyle = WS_VISIBLE | WS_POPUP;
//sourceParams->ExtendedWindowStyle = (int)WS_EX_TRANSPARENT;
sourceParams->UsesPerPixelOpacity = true;
Globals::gHwndSource = gcnew System::Windows::Interop::HwndSource(*sourceParams);
Globals::inkCanvas = gcnew TuioInk::TuioInkCanvas();
//Globals::inkCanvas->Background = System::Windows::Media::Brushes::Transparent;
//Globals::gHwndSource->CompositionTarget->BackgroundColor = System::Windows::Media::Colors::Transparent;
FrameworkElement^ myPage = Globals::inkCanvas;
Globals::gHwndSource->RootVisual = myPage;
return (HWND) Globals::gHwndSource->Handle.ToPointer();
}

5,在你的MFC窗口的OnCreate事件里面,调用GetHwnd函数获取控件窗口句柄。

OK,做完上面这些事情,基本上就能够编译运行了。如果出现编译错误,看看是不是编译选项冲突,去网上找找就能知道如果解决这些编译选项冲突了。

在MFC下调用WPF程序,关键的类是HwndSource,可以去MSDN上查一下这个类的说明,以便做更深入的了解。MS的msdn官网上也讲了如何做MFC与WPF的混合编程(我忘记了地址)。

另外上面代码里面有2行很关键:
sourceParams->WindowStyle = WS_VISIBLE | WS_POPUP;
sourceParams->UsesPerPixelOpacity = true;
如果不是WS_POPUP的类型(比如WS_CHILD),那么透明的效果也不会出现,表现的结果很是怪异。

如果尝试的过程中有问题,可以在博客上给我留言,我们可以进一步探讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: