示例代码

使用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. Java heap space 解决方法(转)

      因为程序要从数据读取近10W行记录处理,当读到9W的时候就出现 java.lang.OutOfMemoryError: Java heap space 这样的错误. 在网上一查可能是JAVA的堆栈 ...

  2. jaxb使用

    一.前言 JAXB——Java Architecture for XML Binding,是一项可以根据XML Schema产生Java类的技术.JAXB提供将XML实例文档反向生成Java对象树的方 ...

  3. 解决sqoop报错:java.lang.OutOfMemoryError: Java heap space

    报错栈: -- ::, INFO [main] org.apache.sqoop.mapreduce.db.DBRecordReader: Executing query: = ) AND ( = ) ...

  4. 【BestCoder】【Round#41】

    枚举+组合数?+DP+数学问题 http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=582 QAQ许久没打过比赛,来一发BC,结果还是只 ...

  5. connection to sys should be as sysdba or sysoper 解决的方法

    连接时提示: 出现了例如以下的情况:EXP-00056;遇到ORACLE错误28009. ORA-28009:connection   to   sys   should   be   as   sy ...

  6. HBase性能优化方法总结(转)

    原文链接:HBase性能优化方法总结(一):表的设计 本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客. ...

  7. OBjective-C:文件管理类NSFileManager

    文件管理类NSFileManager类:对文件进行创建.复制.重命名.删除等,一般不对文件内容进行操作. NSData类和NSMutableData类:相当于数据缓冲区  NSFileManager是 ...

  8. Maximal Rectangle leetcode java

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones ...

  9. 12款程序员们最爱的Bootstrap模板

    如果你还没有开始使用Bootstrap模板,那你可真是有够OUT,这是一个帮助你快速开发的工具,Bootstrap是基于jQuery框架开发的,它在jQuery框架的基础上进行了更为个性化和人性化的完 ...

  10. C# Lambda表达式 基础

    什么是Lambda 表达式? "Lambda表达式"实际上是一个方法,只不过该方法是一个匿名方法(就是没有名字的方法(函数),就是说只有在定义的时候能调用,在其他地方就不能调用了) ...