示例代码

使用C++来开发WPF,主要是如何在MFC(Win32)的窗口中Host WPF的Page。下面我就做个详细的介绍.

一、创建工程, 由于MFC的Wizard会生成很多用不到的代码,所以我准备从一个空的工程开始创建一个MFC的工程。

a)         打开VS2005,菜单File->New->Projects…, 左面选择Visual C++->Win32,右面选择Win32 Console Application,给工程起个名字CPlusPlus_WPF, Ok进入下一步。见Figure 1

Figure 1 Create Project 1

b)        工程基本配置,在Application Setting中选择Console Application和MFC.。Finish进入下一步。见Figure 2

Figure 2 Application Setting

c)        修改工程,使工程变成MFC Windows程序。

i.              删除CPlusPlus_WPF.cpp和CPlusPlus_WPF.h文件

Figure 3 Remove no used files

ii.              添加CWinApp派生类, 在工程上点击鼠标右键,Add=>Class…

Figure 4 Add New Class Menu

在弹出的对话框中,左边选择MFC,右面选择MFC Class,点击Add进入下一步

Figure 5 Create New Class Dialog

在弹出的对话框中输入类名: CCPlusPlus_WPFApp, 基类选择CWinApp

Figure 6 Add CWinApp Derived Class

i.              用同上的方法添加CWnd派生类,Class name为CCPlusPlus_WPFMainWnd, Base class为CWnd。

ii.              修改工程属性。将属性中的System->SubSystem从Concole改成Windows,见Figure 7

Figure 7 Change property

到这一步,一个基本的MFC程序所需要的两个类CWinApp和CWnd派生类就添加完了。我们的程序可以顺利编译通过,但是还不能运行,请继续看下一步

d). 为CCPlusPlus_WPFMainWnd添加代码;
    l         添加创建窗口函数,函数如下:

BOOL CCPlusPlus_WPFMainWnd::CreateMainWnd(const CRect &rect, DWORD dwStyle, DWORD dwStyleEx)
{
    WNDCLASS wndClass;
    memset(&wndClass, 0, sizeof(WNDCLASS));                                            
    wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wndClass.lpfnWndProc = ::DefWindowProc; 
    wndClass.hInstance = AfxGetInstanceHandle();
    wndClass.hIcon = NULL;
    wndClass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wndClass.lpszMenuName = NULL;
    wndClass.lpszClassName = _T("__CPlusPlus_WPF_MainWnd__");

if(!AfxRegisterClass(&wndClass))
    {
        return FALSE;
    }

return CWnd::CreateEx(dwStyleEx, wndClass.lpszClassName, _T("C++ && WPF"), dwStyle, 0, 0, rect.Width(), rect.Height(), NULL, NULL);
}

l         继承CWnd类的PostNcDestroy函数,这个函数是CWnd类中的虚函数,是在窗口退出后,最后一个被调用的函数,我们在这个函数里还删除自己。

void CCPlusPlus_WPFMainWnd::PostNcDestroy()
{
    delete this;
}

e)       为CCPlusPlus_WPFApp添加代码

l         把构造函数改由protect改为public

l         定义theApp, 即CCPlusPlus_WPFAp theApp

l         实现InitInstance()

BOOL CCPlusPlus_WPFApp::InitInstance()
{
    CWinApp::InitInstance();

CCPlusPlus_WPFMainWnd *pMainWnd = new CCPlusPlus_WPFMainWnd();
    if (!pMainWnd->CreateMainWnd(CRect(0, 0, 800, 600), WS_OVERLAPPEDWINDOW, 0))
        return FALSE;

m_pMainWnd = pMainWnd;

pMainWnd->CenterWindow();
    pMainWnd->ShowWindow(SW_SHOW);
    pMainWnd->UpdateWindow();

return TRUE;
}

编译运行,可以看到窗口了,到这步位置,一个基本的MFC程序就已经建立起来了,大家可以对窗口添加想要的风格。这里就不做详细说明了。

二、              进一步修改工程,使其支持WPF

1.         修改工程属性,在工程属性的General的Common Language Runtime Support中选择/Clr, 这个选项可以让这个工程支持Common Language Runtime. 这样我们的工程里就可以写C++/CLI的代码,用来操作WPF了。

Figure 8 Support clr
        2.         添加References,在工程属性中的左面的树上选择,Common Properties->References(C++程序员好像机会很少用到)。

Figure 9 Add References

点击Add New Reference按钮,弹出如下对话框

 

顺次添加如下.NET dlls. 到现在位置,这个工程就已经完全支持WPF了
                
 
        3.         添加显示WPF的部分
            a)         创建一个XAML文件,我已经上传一个,Clock.XAML,这段XAML在Windows SDK中也可以找到。
            b)        动态读取XAML文件
            c)        把WPF的Page Host到MFC的窗口中。完整代码如下

using namespace System;
using namespace System::IO;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Markup;
using namespace System::Windows::Interop;

void CCPlusPlus_WPFMainWnd::CreateWPFWnd()
{
    FileStream^ pStream = File::OpenRead("Clock.XAML");
    if(pStream == nullptr)
        return;

Page^ pMainPage = (Page^)XamlReader::Load(pStream);

pStream->Close();

CRect rcClient;
    GetClientRect(&rcClient);

Rect^ rect = gcnew Rect(0, 0, rcClient.Width(), rcClient.Height());

HwndSourceParameters^ sourceParams = gcnew HwndSourceParameters(gcnew String("WPFWnd"));
    sourceParams->PositionX = Int32(rect->X);
    sourceParams->PositionY = Int32(rect->Y);
    sourceParams->Height = Int32(rect->Height);
    sourceParams->Width = Int32(rect->Width);
    sourceParams->ParentWindow = System::IntPtr(m_hWnd);
    sourceParams->WindowStyle = WS_VISIBLE|WS_CHILD|WS_CLIPCHILDREN;

HwndSource^ source = gcnew HwndSource(*sourceParams);
    if(source == nullptr)
        return;

source->RootVisual = pMainPage;
}

d)        在CCPlusPlus_WPFMainWnd::OnCreate中调用上面的函数。
             e)         编译运行,一切Ok了。

当然,这只是基本的步骤,在这个基础上就可以利用C++和WPF来开发一个完整的软件了

C++开发WPF,Step by Step的更多相关文章

  1. WPF Step By Step 系列-Prism框架在项目中使用

    WPF Step By Step 系列-Prism框架在项目中使用 回顾 上一篇,我们介绍了关于控件模板的用法,本节我们将继续说明WPF更加实用的内容,在大型的项目中如何使用Prism框架,并给予Pr ...

  2. WPF Step By Step 完整布局介绍

    WPF Step By Step 完整布局介绍 回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的 ...

  3. WPF Step By Step 控件介绍

    WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子 ...

  4. WPF Step By Step 系列 - 开篇 ·

    WPF Step By Step 系列 - 开篇 公司最近要去我去整理出一个完整的WPF培训的教程,我刚好将自己学习WPF的过程和经验总结整理成笔记的方式来讲述,这里就不按照书上面的东西来说了,书本上 ...

  5. WPF MVVM 架构 Step By Step(6)(把actions从view model解耦)

    到现在为止,我们创建了一个简单的MVVM的例子,包含了实现了的属性和命令.我们现在有这样一个包含了例如textbox类似的输入元素的视图,textbox用绑定来和view model联系,像点击but ...

  6. WPF Step By Step 自定义模板

    WPF Step By Step 自定义模板 回顾 上一篇,我们简单介绍了几个基本的控件,本节我们将讲解每个控件的样式的自定义和数据模板的自定义,我们会结合项目中的具体的要求和场景来分析,给出我们实现 ...

  7. Step by Step: 基于MFC下的COM组件开发-Helloworld

    http://blog.csdn.net/sybifei/article/details/45008745 [这篇文章有问题, 仅供参考] http://blog.csdn.net/define_us ...

  8. enode框架step by step之框架的物理部署思路

    enode框架step by step之框架的物理部署思路   enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by s ...

  9. Step by step Dynamics CRM 2011升级到Dynamics CRM 2013

    原创地址:http://www.cnblogs.com/jfzhu/p/4018153.html 转载请注明出处 (一)检查Customizations 从2011升级到2013有一些legacy f ...

随机推荐

  1. 单独配置secondarynamenode

    一.配置说明 这是在我之前yarn框架上通过加入节点,改动相关的配置文件,使得secondarynamenode独立出来的,所以这里前期的一系列琐碎配置请參考我之前的博客: http://blog.c ...

  2. unity3d-地图制作之光照贴图Lightmapping

    今天无聊随便翻看了暗黑战神的场景资源,发现了一个以前没怎么注意的静态场景优化问题. 什么是静态场景,也就是说这个场景是不会变化.比如MMO游戏中选择人物的场景. 就拿默认的暗黑战神的选择人物场景来看, ...

  3. 利用Mircosoft URLRewriter.dll实现页面伪静态

    一,获得Mircosoft URLRewriter.dll: 获得Mircosoft URLRewriter.dll可以到http://www.microsoft.com/china/msdn/lib ...

  4. LaTeX中的数学公式

    因为想在过年之前把论文写出来(虽然现在看来似乎痴人说梦),用word写PDE的公式简直是自己找虐,就想说自己研究一下LaTex,用起来发现这东西写格式性的文档真心甩word几个陈景润啊,出来的公式不仅 ...

  5. Qt学习之对话框与主窗口的创建

    Qt中的信号与槽机制 qt中槽和普通的C++成员函数几乎是一样的--可以是虚函数,可以被重载,可以是共有的,保护的或者私有的. 槽可以和信号连接在一起,在这种情况下,每当发射这个信号的信号,就会自动调 ...

  6. leetcode414-第三大的数

    给定一个非空数组,返回此数组中第三大的数.如果不存在,则返回数组中最大的数.要求算法时间复杂度必须是O(n). 示例 1: 输入: [3, 2, 1] 输出: 1 解释: 第三大的数是 1. 示例 2 ...

  7. QT For Android 运行的时候找不到手机怎么办?

    [解决方法] 如果是Android手机,那需要下载这个: http://community.kde.org/Necessitas

  8. 解决Sublime包管理package control 报错 There are no packages available for installation

    解决Sublime包管理package control 报错 There are no packages available for installation 真的是哔了狗了,要不是我机智的重新安装了 ...

  9. OAuth 2.0 Authorization Framework RFC

    Internet Engineering Task Force (IETF) D. Hardt, Ed.Request for Comments: 6749 MicrosoftObsoletes: 5 ...

  10. [Node.js] Load balancing a Http server

    Let's see how to do load balancing in Node.js. Before we start with the solution, you can do a test ...