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.
Comments
- Anonymous
January 23, 2006
"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."
Probably the best piece of advice to keep in mind, although abstract and less helpful.. so what's left? Pseudo-code? ;)
Here's the deal though, and no harm is intended.. I am having difficulty envisiging another layer taking another 30MB in total waste per app as it currently is with Windows Forms version of identical Win32 code (GDI or GDI+).
As if it wasn't enough mess out there with MFC, WTL, GTK, QT, FLTK, whatever - K ;)...
It simply doesn't add up, other issues like devices, form factors, just complicate it further. From a personal perspective, am attempting to come back to GUI issues roughly few decades post last pleasant play, sure advances on raster and hsync but still no clear model.
Yet it still feels pleasant thinking about the old day (no it's not subjective;).. Sure progress has been made, but nothing out there tells me OLE-like or not composition is any easier to do, or that knocking up an app is any easier than embedding a web-browser for the device in question.. But yes, it isn't about productivity all the way but efficiency too..
Or is there anything to say that some kind of investment can be preserved and at least some work sealed? Sure, responsibility of the developer side.. and sure, great work out there that USER32 and all Win32 GDI stuff is around.. but someone give me a good, valid reason why GDI(+) shouldn't benefit from the shader and other advances in hardware, or that old apps will render text slower on 'modern' OS-es..
I'd rather jump at something like XHTML and/or SVG equivalent, (compile the script whatever..) than yet another model. Or hey, why didn't anyone nail this Direct( X or Linux or CE or x) stuff with a portable base?
Nope, another app framework, another milestone, another worry, another hammer.
Anything will do but more bloat that simply isn't stable in sense of future programming models or investment.. so coming back, yep the advice seems just about the only thing we can do, and that's in this 'modern' day and age..
There, just my simple, foolish worry and rant (if it is, but wasn't intended) over..