YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   Home Products | Purchase Support | Downloads  
View in English
View in Japanese
View in
참고
View in Français
View in Italiano
View in 中文(繁體)
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
VX++ Cross-Platform C/C++
Overview
Download
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET

Hosting WPF Content in an VC++ MFC Application.

Introduction

This article will showcase the technique to host WPF content in an MFC-based application. The main usage of this implementation is to enhance the graphical appearance of conventional Win32/MFC-based applications. The demo program that comes along with this article will host an animated WPF clock in an MFC dialog program.

Development Tools & Library

 
To build and run the demo program, the following components must be installed:

 

  • MS Visual Studio 2005 or above
  • MS .NET Framework 3.0 or above (download)

Platforms

The .NET Framework 3.0 supported only in the following platforms:

  • Windows Vista
  • Windows XP SP2
  • Windows Server 2003 SP1

Prerequisites

If you are a C++ developer and want to use WPF as an add-on to enhance the graphical UI of your existing Win32/MFC applications, this article is written for you. To get the most out from this article, you should be familiar with VC++/CLi, MFC, XAML, and C#. But, if you don't know C# or XAML, you can still proceed just by referencing the generated DLL and make use of it in your MFC application.

What Is WPF?

WPF stands for Windows Presentation Foundation. It's a subsystem of Microsoft .NET Framework 3.0. It allows developers to productively create visually appealing applications and improve user experience. The deployment of WPF enables richer control, design, and development of the visual aspects of Windows programs. It aims to unify a host of application services: user interface, 2D and 3D drawing, fixed and adaptive documents, advanced typography, vector graphics, animation, data binding, audio, and video. WPF also provides a consistent programming model for building applications and provides a clear separation between the UI and the business logic.

WPF APIs are managed code, but most existing Win32/MFC programs are coded in unmanaged C++. Conventionally, WPF APIs cannot be called from a true unmanaged program. However, by using the /clr option with the VC++ compiler, you can create a mixed managed-unmanaged program where you can mix managed and unmanaged API calls seamlessly.

One thing to note is that you are not allowed to compile XAML files into a C++ project. So, you have the following options to handle this.

  • Create a C# DLL that contains all your XAML pages as a compiled assembly, and then have your C++ executable include that DLL as a reference.
  • Drop XAML and write all your WPF in code, building up the element tree from application.

This article will use the first approach.

Interoperation Basics

There are two basic techniques for interoperation between WPF and Win32/MFC code:

  • Host WPF in Win32/MFC: With this technique, developers can use the advanced graphics capabilities of WPF within the framework of standard Win32/MFC applications.
  • Host Win32/MFC in WPF: With this technique, developers can use an existing custom Win32/MFC control in the context of other WPF content, and pass data across the boundaries.

This article will be based on the first technique.

Getting Started

Those are all the basic ground rules you should know; it'd time to get to the code. Here, I will show you WPF content created in XAML and C#, and the generated DLL will be referenced in VC++.

The idea is to create a simple Date & Time setting tool with the animated clock part implemented as a WPF content. The rest of the program still will be coded in MFC.

Project Division

This demo program is constructed by two parts; one is MFCHostWPF (coded in VC++/MFC) and the other is WPFcontrols (coded in XAML and C#). The MFCHostWPF project will take the DLL generated by WPFcontrols project as an external reference.

Adding WPF as a Reference Library in an MFC Project

 

Hosting WPF Content in an MFC Application

Adding WPF-Related Code to an MFC Application

For your information, the gcnew keyword is used to create an instance of managed type; this will create the instance on the garbage collected heap. All memory allocated by gcnew will be managed automatically by the garbage collector and developers will not need to worry about freeing them up.

To host WPF content, the key is on the System::Windows::Interop::HwndSource class. This class will take care of wrapping the WPF content in a Win32 window, so that the WPF content can be incorporated into your user interface (UI) as a child window. Communication with the WPF content object is done by using the reference stored in the static fields. They're declared as static to prevent them from being inadvertently garbage collected.

ref class Globals
{
public:
   static System::Windows::Interop::HwndSource^ gHwndSource;
   static WPFControls::AnimClock^ gwcClock;
};

HWND hwndWPF;    //The hwnd associated with the hosted WPF page

 

 
 
To create an HwndSource, first create an HwndSourceParameters structure and populate it with the following parameters:

 

  • Class, window, and styles
  • Initial position of the window
  • Initial size of the window
  • The parent window

Once you have populated the HwndSourceParameters structure, pass it to the HwndSource(HwndSourceParameters) constructor for the HwndSource.

Then, you create your WPF clock class by calling its constructor WPFControls::AnimClock(). You also initialize the date & time by calling its ChangeDateTime() method.

Finally, you assign the reference of the WPF clock object to the HwndSource object RootVisual property and return the HWND of the HwndSource by calling Handle.ToPointer().

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();
}

So, whenver the user makes date or time changes, your MFC code will call RefereshWPFControl() to refresh the WPF clock.

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;
}

Now that you have all your needed functions set, the last tucancode.net is to find a place in your MFC dialog code to call the HwndSource instance creation function. There are a few possible locations to call it; one good place is in the OnCreate event handler.

Handle the WM_CREATE notification

Call the GetHwnd() function in the OnCreate event handler when the application first starts.

int CMFCHostWPFDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CDialog::OnCreate(lpCreateStruct) == -1)
      return -1;

   hwndWPF = GetHwnd(this->GetSafeHwnd(), 20, 28, 205, 130);

   return 0;
}

Conclusion

As you can see now, by applying WPF in Win32/MFC applications you can add lots of "perks" to the overall user experience while the program logics remain coded in the Win32/MFC style.

Downloads

News:

1 UCanCode Advance E-XD++ CAD Drawing and Printing Solution Source Code Solution for C/C++, .NET V2023 is released!

2 UCanCode Advance E-XD++ HMI & SCADA Source Code Solution for C/C++, .NET V2023 is released!

3 UCanCode Advance E-XD++ GIS SVG Drawing and Printing Solution Source Code Solution for C/C++, .NET V2023 is released!

 


Contact UCanCode Software

To buy the source code or learn more about with:

Next--> Promotional personalized database document printing Solution

Ask any questions by MSN: ucancode@hotmail.com Yahoo: ucan_code@yahoo.com


 

Copyright ?1998-2023 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net