Thursday, 29 March 2012

WPF Interop: COM, ActiveX OCX and PDF fun

Here is an application that displays a PDF file inside a WPF window. 

To do this, the easiest way is to interop with the Adobe Reader COM ActiveX (OCX) control.

image

So how does WPF deal with COM and ActiveX (OCX controls), given the disparity between how classic Win32 and WPF handles HWNDs.

Classic Win32: One HWND per control
WPF: One HWND per window/dialog


Containers

The solution is to create:

  • a WPF window containing
  • a WindowsFormsHost control containing
  • a WinForms User Control containing
  • the ActiveX control


For our example we’ll be using the Adobe Acrobat Reader and you will need this installed if you wish to run the code and application.

Please note:
You cannot use this COM component outside of the main UI thread as the OCX is not thread-safe.

Here are the steps I took:

Add WinForms User Control

image

Add COM Reference to the project

add-COM-references

“Add Tab” to the Toolbox called Adobe, “Choose Items…” and add the Adobe PDF Reader

add-adobe-tab    choose-itemsCOM-components

You can now drag and drop the Adobe PDF Reader control from the Toolbox onto the WinForms User Control.

Drag-COM-OCX-component-to-WinFormUserControl

By dragging the control onto the surface it ensures the OCX is correctly registered by the form.

What C# code does that actually produce?

Add your code behind to the WinForms User Control

Finally, add a WindowsFormsHost control to your WPF window and add the WinForms UserControl as a child

To print just right click on the document and select Print.

Here is the same solution with a notify event raised by the WinForm User Control, to enable communication with the Wpf window:

Source code: http://stevenhollidge.com/blog-source-code/PdfViewAndPrint.zip

Source code:  http://stevenhollidge.com/blog-source-code/PdfViewAndPrint_with_event.zip

No comments:

Post a Comment