Friday, May 01, 2009 

Einstellung

As I mentioned in previous posts, one of the projects I've been recently involved with is a complete rewriting of the GUI layer for a rather large system. We want to move from an MFC-based framework to .NET, mostly to improve productivity.
Initially, we'll basically move the GUI as-is, without re-designing the human-computer interaction. Therefore, it would pay to recover as much information as possible from the existing system, and do it automatically.

Among other things, we have about 250 dialog boxes to port, so I thought it would be a good idea to write a translator from the Win32 RC format to whatever new format we need. This way, we can recover layout (positioning and sizes) and also translate each control to their nearest equivalent.

That means, of course, that we know the target, and today, the .NET game boils down to choosing between Windows Forms and WPF. The choice is rather hard, althogh I know many programmers would jump immediately on the WPF bandwagon. Anyway, as we discussed the translator above, the project manager observed that WinForms stores everything in code. If we ever have to do this kind of change again, she said, we will miss the simplicity of RC. XAML would make layout and controls easier to move to another technology, just as RC.

That's true; I don't particularly like the idea of having to parse C# to recover layout information, control initialization parameters, and so on.

Funny thing is, for a while I got trapped in this parsing concept. I guess it has to do with education. Any computer scientist will recognize this as a parsing and translation problem. It's a well known problem frame. And that calls for a parser, of course :-).

It took me a while to realize I didn't have to write a parser at all: I could just use reflection! To test the idea, I wrote a simple C# program (about 60 lines of code) which takes a form and recursively dumps layout and initialization parameters in an XML format.

For instance, given this form:



where the blue rectangle is a panel, and the label and button are nested controls, I'll get this XML.

The idea is pretty simple: I dump every property without a Browsable(false) attribute, that is, everything that you can change at design-time. If the Controls collection is not empty, I'll recurse into it. The nice part is that it could be made to work also for dynamic controls, created at run-time and not a design-time. Just call the translator after all the controls have been created, and that's it.

Things could be easily improved. Right now, I don't handle collections (see bindings), non-visual components, and I dump every single property. It would be useful, perhaps, to dump only values that have been changed. That's easy, just create a control of the same class on the fly, and check for differences. Piece of cake.

Now, I wish I could say I thought of this through my understanding of the forcefield :-). But I can't. It just came to me. Dunno how. The problem, of course, is moving past the Einstellung effect of education. What can I say? Keep your mind open, practice lateral thinking, never give up :-). And yeah, well, keep an eye on that forcefield, as that may help too...

Labels: , ,

Comments:
This is only because You're not so
well accustomed in Java, where *reflection* is used for almost everything...

... ah, and Java is a far more superior language to C/C++/C#, more
complete, more professional, free.

C# is the involution of C and VB.

Cheers.

K
 
yeah sure man, whatever... : )
 
Post a Comment

<< Home