Hosting a WPF Control in MFC and Enable Cut-and-Paste

Source: Microsoft Support

RAPID PUBLISHING

RAPID PUBLISHING ARTICLES PROVIDE INFORMATION DIRECTLY FROM WITHIN THE MICROSOFT SUPPORT ORGANIZATION. THE INFORMATION CONTAINED HEREIN IS CREATED IN RESPONSE TO EMERGING OR UNIQUE TOPICS, OR IS INTENDED SUPPLEMENT OTHER KNOWLEDGE BASE INFORMATION.

Symptom



It is possible to host a Windows Presentation Foundation (WPF) Control in the client area of an MFC Application and to enable Cut-and-Paste event handling in MFC that can cut-and-paste text in the WPF controls.


WPF controls do not have window handles therefore you will need to use WPF API's in the MFC event handling code to cut and paste the text.


This article will outline the basic steps to enable this in a simple MFC SDI application.

Resolution

  1. Create a new MFC SDI app named MFCWPF - From the File menu, choose New, and then Project to start the New Project wizard.
    1. In the Visual C++, MFC Project types, select the MFC Application template.
    2. Name the new application MFCWPF and click the OK button.
    3. In the MFC Application Wizard, select the Application Type and click the Single document Application type. Then select the MFC Standard Project style.
    4. Click the Advanced Features section and uncheck the Printing and print preview checkbox.
    5. Click the Finish button to create the solution.
  2. In the newly created project, set the compiler options to build a mixed native/managed application:
    1. From the Project menu, select MFCWPF Properties.
    2. In the Configuration Properties, select the General section.
    3. Set the Common Language Runtime support property to Common Language Runtime Support (/clr). Do this for both the Debug and Release configurations of the project.
    4. In the Common Properties section, click the Add New Reference... button and add references for the following .NET assemblies - PresentationCore, PresentationFramework, System, and WindowsBase.
  3. In the Solution Explorer window, open the MFCWPFView.cpp file
  4. After the #include statements for the header files, add the following code. This will reference the required managed namespaces and implement a function which creates a simple WPF object:
  5. using namespace System;
    using namespace System::Windows;
    using namespace System::Windows::Controls;
    using namespace System::Windows::Media;
    using namespace System::Runtime;
    using namespace System::ComponentModel;
    using namespace System::Runtime::InteropServices;
    using namespace System::Windows::Interop;
    using namespace System::Windows::Input;

    HWND GetHwnd(HWND parent, CMFCWPFView* view, int x, int y, int width, int height)
    {
         // Create an HwndSource WPF object 
         System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters ("WPFSourceWindow");
         sourceParams->PositionX = x;
         sourceParams->PositionY = y;
         sourceParams->Height = height;
         sourceParams->Width = width;
         sourceParams->ParentWindow = IntPtr(parent);
         sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD;
         HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams);

         // Create a textbox object and set it as the RootVisual
         view->m_wpfTextBox = gcnew System::Windows::Controls::TextBox();
         view->m_wpfTextBox->Width=100;
         view->m_wpfTextBox->Height=20;
         view->m_wpfTextBox->Text = "Some WPF Text";
         source->RootVisual = view->m_wpfTextBox;

         return (HWND) source->Handle.ToPointer();
    }
  6. In the Solution Explorer window, open the MFCWPFView.h header file. Add the following class member declarations:
  7. class CMFCWPFView : public CView
    {
         HWND m_wpfHostWindow;
    public:
         gcroot<System::Windows::Controls::TextBox^> m_wpfTextBox;
    ...<the rest of CMFCWPFView class>..
  8. Add a WM_CREATE OnCreate handler to the CMFCWPFView class
    1. In the Class View, select the class CMFCWPFView
    2. Select the Properties tab
    3. Click the Messages button at the top of the Properties page.
    4. Find the WM_CREATE message and select the dropdown arrow. Select the <add> OnCreate selection to create the OnCreate handler.
  9. In OnCreate, add a call to the GetHwnd method created earlier:
  10. int CMFCWPFView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
         if (CView::OnCreate(lpCreateStruct) == -1)
         return -1;

         // TODO: Add your specialized creation code here
         m_wpfHostWindow = GetHwnd(this->GetSafeHwnd(),this,0,0,200,200);

         return 0;
    }
  11. Add handlers for the ID_EDIT_CUT and ID_EDIT_PASTE events.
    1. From the Class View window, select the CMFCWPFView class. Click the Properties window
    2. Select the Event icon at the top of the Properties page.
    3. Expand the tree node for ID_EDIT_CUT and ID_EDIT_PASTE.
    4. Add COMMAND and UPDATE_COMMAND_UI handlers for both of these events.
  12. Add the following WPF code to the cut and paste handlers to enable cut-and-paste operations in the WPF code:
  13. void CMFCWPFView::OnEditCut()

         RoutedCommand^ command = ApplicationCommands::Cut; 
         UIElement^ target = (UIElement^) Keyboard::FocusedElement; 
         if(target != nullptr && command->CanExecute(nullptr,target)) 
              command->Execute(target,nullptr);
    }

    void CMFCWPFView::OnUpdateEditCut(CCmdUI *pCmdUI)

         UIElement^ target = (UIElement^) Keyboard::FocusedElement; 
         pCmdUI->Enable(1);
    }

    void CMFCWPFView::OnEditPaste()

         RoutedCommand^ command = ApplicationCommands::Paste; 
         UIElement^ target = (UIElement^) Keyboard::FocusedElement; 
         if(target != nullptr && command->CanExecute(nullptr,target)) 
              command->Execute(target,nullptr);
    }

    void CMFCWPFView::OnUpdateEditPaste(CCmdUI *pCmdUI)

         UIElement^ target = (UIElement^) Keyboard::FocusedElement; 
         pCmdUI->Enable(1);
    }
  14. Build and run the application. You should see a WPF textbox appear in the client area. You can use the CTRL+X and CTRL+V accelerator keys and MFC toolbar buttons as well as the Edit menu picks to cut and paste text into the WPF textbox. Also note that the MFC UI will update as appropriate for the cut-and-paste operations.


 


 


DISCLAIMER

MICROSOFT AND/OR ITS SUPPLIERS MAKE NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY, RELIABILITY OR ACCURACY OF THE INFORMATION CONTAINED IN THE DOCUMENTS AND RELATED GRAPHICS PUBLISHED ON THIS WEBSITE (THE “MATERIALS”) FOR ANY PURPOSE. THE MATERIALS MAY INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS AND MAY BE REVISED AT ANY TIME WITHOUT NOTICE.


TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND/OR ITS SUPPLIERS DISCLAIM AND EXCLUDE ALL REPRESENTATIONS, WARRANTIES, AND CONDITIONS WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO REPRESENTATIONS, WARRANTIES, OR CONDITIONS OF TITLE, NON INFRINGEMENT, SATISFACTORY CONDITION OR QUALITY, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE MATERIALS.
Eigenschappen

Artikel-id: 959082 - Laatst bijgewerkt: 20 okt. 2008 - Revisie: 1

Feedback