C++中调用WPF

心已入冬 提交于 2019-12-09 04:14:01

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

1创建工程

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

1)    打开VS2008,菜单File->New->Projects…, 左面选择Visual C++->Win32,右面选择Win32 ConsoleApplication,给工程起个名字CTest_WPF, Ok进入下一步。

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

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

Ø  删除CTest_WPF.cpp和CTest_WPF.h文件

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

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

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

Ø  用同上的方法添加CWnd派生类,Class name为CTest_WPFMainWnd,Base class为CWnd。

Ø  修改工程属性。将属性中的System->SubSystem从Concole改成Windows。

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

4)    为CTest_WPFMainWnd添加代码;

添加创建窗口函数,函数如下:

头文件:

//  创建窗口函数
BOOL CreateMainWnd(const CRect &rect, DWORD dwStyle, DWORD dwStyleEx);

源文件:

BOOL CTest_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("__CTest_WPF_MainWnd__");

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

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

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

头文件:

protected:
virtual void PostNcDestroy();

源文件:

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

             

5)    为CTest_WPFApp添加代码

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

Ø  定义theApp, 即CTest_WPFApp theApp,定义到类体外

Ø  实现InitInstance()

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

    CTest_WPFMainWnd *pMainWnd = new CTest_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程序就已经建立起来了,大家可以对窗口添加想要的风格。这里就不做详细说明了。

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

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

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

点击Add New Reference按钮,顺次添加如下.NET dlls。          

 

到现在位置,这个工程就已经完全支持WPF了。              

3)    添加显示WPF的部分

Ø  创建一个XAML文件。

Ø  动态读取XAML文件

Ø  把WPF的PageHost到MFC的窗口中。完整代码如下    

在Test_WPFMainWnd.cpp中添加,别忘了在头文件中声明CreateWPFWnd():

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 CTest_WPFMainWnd::CreateWPFWnd()
{
    FileStream^ pStream = File::OpenRead("Page1.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;
}

Ø  在CTest_WPFMainWnd::OnCreate中调用上面的CreateWPFWnd()函数。

Ø  编译运行,一切Ok了。

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

运行效果如下:

说明:源码在我的资源中[C++中开发WPF],部分内容来自博客园

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!