CodeGuru
Earthweb Search
Login Forums Wireless Jars Gamelan Developer.com
CodeGuru Navigation
RSS Feeds

RSSAll

RSSVC++/C++

RSS.NET/C#

RSSVB

See more EarthWeb Network feeds

follow us on Twitter

Member Sign In
User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

Become a Marketplace Partner

jobs.internet.com

internet.commerce
Partners & Affiliates
















Home >> Visual C++ / C++ >> C++ >> C++/CLI >> Interop


Hosting WPF Content in an MFC Application
Learn to host graphical-appearing WPF content in an MFC application.
Rating:

Kevin Choong (view profile)
January 18, 2008

Environment:  VS2005, VC++/CLi, MFC, VC#, MFC, XAML

Go to page: Prev  1  2  

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.


(continued)




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 task 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.

Comments

All suggestions and corrections are welcome.

About the Author
Kevin is a C++ & C# developer with proven ability to architect, program, and optimize code. He has more than 10 years programming experience for business solutions. He also has the passion for both playing and developing video games. Kevin can be reached via kevin.choong@hotmail.com.

Go to page: Prev  1  2  

Downloads

  • MFCHostWPF-Bin.zip - Executable Files
  • MFCHostWPF-Src.zip - Project Source Code

    Tools:
    Add www.codeguru.com to your favorites
    Add www.codeguru.com to your browser search box
    IE 7 | Firefox 2.0 | Firefox 1.5.x
    Receive news via our XML/RSS feed







  • RATE THIS ARTICLE:   Excellent  Very Good  Average  Below Average  Poor  

    (You must be signed in to rank an article. Not a member? Click here to register)

    Latest Comments:
    No Comments Posted.
    Add a Comment:
    Title:
    Comment:
    Pre-Formatted: Check this if you want the text to display with the formatting as typed (good for source code)



    (You must be signed in to comment on an article. Not a member? Click here to register)

    internet.commediabistro.comJusttechjobs.comGraphics.com

    Search:

    WebMediaBrands Corporate Info

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | Shopping | E-mail Offers | Freelance Jobs