Random migration and interop thoughts

I haven't been real good about reposting questions that came up in private conversation, here's some of the more interesting ones from the last month:

What's the deal with OLE and WPF?   Short answer is, we don't have any plans for something like OLE-style in-place editing -- eg menu merging, compound documents, etc. OLE continues to work, and although we don't provide a managed code wrappers for it, you can use it with WPF using hwnd interop.

I got a big VB 6 app, should I jump first to WinForms then to WPF, or straight to WPF?   I don't think there's a one size fits all answer, it really depends on your timeline for deploying a WPF version, what intermediate releases you have, and what functionality you want to leverage in your new platform(s).  In terms of the work involved, migrating directly from VB 6 to WPF is going to be harder than VB6->WinForms, but easier than VB6->WinForms->WPF.  I think of VB6->WinForms as two separate chunks of work -- UI and everything other than UI (language changes, data manipulation, server communication, etc.).  The UI portion is mostly a matter of mapping the VB 6 code to the WinForms equivalent.  WinForms->WPF avoids all the language and non-UI issues, but the UI changes probably more fundamental, at least if you want to take full advantage of WPF.  Both VB 6 and WinForms are ultimately hwnd-based, and it takes a different mindset to take advantage of WPF features like control composition, styling, and templating.

How can I write WinForms applications to make it easier to migrate to WPF?   The first step is writing in WinForms -- good for you!  It's much easier to migrate WinForms code than MFC or Win32 code or VB6, since all you have to worry about it is the UI -- you don't need to worry about the language or your business logic or anything else.  Beyond that, really the only advice is to keep your code modular -- separate your UI from your business logic, and as much as possible isolate one piece of UI from another so you can migrate your UI piecemeal. 

Separating UI from business logic is easier said than done, but it's definitely possible to make at least some of your business logic UI-independent.  John Gossman (architect for Sparkle) has an interesting series of posts about how to do this in WPF, his basic point is that if you write your business logic ("model") completely abstracted away from any notion of UI ("view"), then your view can't really talk directly to the model because there's too much impedance mismatch.  So the solution is an intermediary he calls a "viewmodel" -- by using this architecture, your view does most of its communication through data binding and commands, and your model is completely pure. 

John wrote this in the context of WPF, but WinForms applications can also use this architecture to help migration -- when you migrate to WPF you can keep your model and view model and only worry about rewriting the view.  (WinForms is more limited than WPF in terms of commands and data binding, so in WinForms your UI will probably contain a little more glue code and less data binding/commanding than the WPF version)

HwndHost doesn't support drag-and-drop?   It does, in the same way that it supports mouse input -- by using Win32 APIs on the underlying hwnd.

I took your Hwnd inside WPF sample, and changed it to use my (Win32) message loop, and now my TranslateAccelerator/TranslateChar/OnMneumonic doesn't get called.   At some point I'll add a chapter to the interop white paper about this, but here's the abbreviated version: Win32 doesn't really have any notion of componentized tabbing, accelerators, and mnemonics, the Win32 assumption was that the message loop has global knowledge of the application and thus can implement this functionality. But global knowledge is not a real great assumption for componentized software like WPF, so we created IKIS (IKeyboardInputSink) to componentize this. But we need help of the message loop to call IKIS methods; WPF's message loops provide this functionality, but a pure, unmodified win32 message loop does not.  This is where the ComponentDispatcher (CD) class comes in -- the message loop calls CD, and top-level IKIS'es can plug into the CD to listen to events.   (parent IKIS's are also responsible for calling child IKIS's at the right time)  If you don't hook up CD/IKIS, you still get normal WPF input events like KeyDown, you just lose the IKIS virtuals.