1
votes

My question is - Is it possible to wrap a GDI based MFC View class for use in C# .Net managed code.

Background :

I am currently working on a legacy app that was developed in MFC. It does same GDI based drawing through MFC's document view framework. It's all simple stuff, like drawing lines and bliting bitmaps. However, since it is an MFC app, the code for drawing is C++ MFC, implemented by extending the CView class, and adding drawing code to OnDraw() member function of the extended View class.

Now, I want to put on a nice UI on top of the application, so I was planning to use a thin C++/CLI wrapper, by keeping all the guts of my application in MFC, but simply using WPF for GUI - how controls are presented to the user. In order to save coding time and also to avoid marshalling, I would like to retain my extended MFC View class, and its GDI based drawing code. Is this possible? Or do I have rewrite the drawing code if I want to use WPF for GUI?

1
@Admins, is the question posted and visible? It has received surprisingly few number of views. - The Vivandiere
Do you have the option of wrapping your MFC view in a control, either MFC or ATL? (My preference is ATL...although my experience mixing ATL with MFC is a little lacking.) - Markus
Oh, also, I can see your question and I am no one special, so take that for what it's worth. - Markus
Yes it's possible, I have ported MFC CView derived classes to ATL and then implementend in a HWndHost using C++/CLI. It was easy and works well, although you will have airspace issues (i.e. you cannot overlay WPF content on the native view). - Roger Rowland
is your component able to draw on a given DC? is it possible for you to share a sample of your component with some explanation to use it? but I would recommend to adopt WPF for your UI, you'll have same performance with better maintainability, unless you are developing frame hungry games. - pushpraj

1 Answers

0
votes

Yes, we do exactly this in our application. We settled on creating a DIB memory block and selecting that into the DC before drawing and getting the bits into the WPF window by having an InteropBitmap in a main Grid control.

You can also use a WriteableBitmap and Lock + copy bits into that but the synchronization is a bit different than InteropBitmap. One does double-buffering (InteropBitmap I believe) so the memory usage is doubled but there's no chance of a black flash from the WPF render thread sending an un-filled/empty image to the screen.

We needed to hook the CompositionTarget.Rendering notification and treat that as our WM_PAINT/OnShow trigger.

During the WPF window creation, I believe we also watch for the HwndSource creation and at that point hook up the CView to the HWND created.

I will also mention that we also have a C++/CLI layer as mentioned in one of the comments. So I create WPF controls in the UI in code instead of XAML. We can pass the Window object to C# for manipulation as well but the C++/CLI makes it an easier port IMO.