More IDE Omissions

This one was enough to warrant an adventure in continuity.

I’m making an application in WPF to get a feel for how some of the technology works, since so far I’ve been using it in little sandbox applications.  I got all my data classes made and decided it was time to make the UI.  I want to make a dialog, so I figure it’s like how I’d do it in Windows Forms: "Right-click project>>Add Window", right?  Wrong.

I can add a Windows Form from the right-click menu.  If I just go to "Add>>New Item…", I can add a WPF User Control, but apparently no one thought you’d want more than one Window per project.  I believe the right-click menu issue is because I’m not using an Application Definition but a Main method to kick off my application.  It’s still aggravating.  Once again, the IDE is punishing me because my approach to application architecture isn’t what VS considers the "right" way.  Now I have to manually add a XAML file (as an XML file, then rename it and add the Window element manually) and a code-behind file, making sure that I get the x:Class attribute right and import the correct namespaces.  Tell my why we paid for an IDE again?

IDEs considered harmful?

Jeff Putz mentions a post about a person who switched from an IDE to a text editor and why it isn’t such a good idea.  I’m not sure where I stand.

On the one hand, there’s no denying the utility of features like Intellisense and integrated debugger support that he mentions.  I would argue that several "text editors" these days support such features, but I will concede that many of them fall short of a really good experience.

On the other hand, I can also agree with many of Charles Petzold‘s points.  When you use Visual Studio, it forces you to structure your programs in a specific way.  I’ll discuss the hiding of designer code and the lackluster support for WPF file types and why I believe they exemplify a case where an IDE hurts users as opposed to a text editor.

Starting with VS 2005, designer code is hidden away in partial classes.  In C#, you are more aware of this because the designer files are displayed along with a separate code file, so it’s clear you’re working on a class spread across several files.  In VB .NET, VS pretends like there’s only one file, and since the user can’t see any evidence of designer code one can assume the designer works by magic. One of the main reasons I see cited for this is so the user doesn’t accidentally edit code in a location that’s subject to be modified at the designer’s leisure.  There’s really no way to force the designer code into the main class, but it does seem like if you open a file that already has designer code in it, then the designer does the right thing and doesn’t insist you create a partial class. 

I care about this because no programmer should ever believe the tools she uses are magic, and forcing the designer code to be hidden enforces this belief, particularly among VB users.  I’m very active on a VB .NET programming forum, and I generally see one or two questions a month that either directly ask for information about dynamically creating controls or for which the most elegant solution is dynamically creating controls.  More often than not, the poster is completely ignorant of the fact that the VS designer generates code that they could write themselves; sometimes they literally state, "How do I programmatically invoke the designer so I can put some buttons on the form?"  Reading through one of Charles Petzold’s books on .NET is a good way to avoid this if you’re a .NET newbie: Petzold tends to start in the code and discourages you from using the designer until you understand what the designer does for you.  I wish more beginning programming texts would start this way; the designer-first approach seems to produce programmers that believe there’s a drag-and-drop solution to every problem, and anything without such a solution is not possible. 

I don’t argue that there shouldn’t be a designer, but I do argue that the designer code shouldn’t be so well-hidden from the user.  I learned how to use several controls by configuring them with the designer, then looking at the code that was generated in VS2003; it’s a shame that many people don’t even know this is possible.  What’s interesting is in WPF, you pretty much have no choice but to write code for your layout whether it’s XAML or imperative code, so it seems perhaps this evil practice will fade away.

The next thing I want to discuss is the lackluster support for WPF file types in VS 2008.  How do you think I create a loose XAML file in WPF?  The use case isn’t necessarily uncommon; suppose I want to create a window and I don’t need a code-behind file, or I want multiple themes for a custom control.  I have two choices: I can create a WPF window and delete the code-behind file and edit the XAML file to be what I want, or I can create a new XML file, name it with the XAML extension, and remove the XML document declaration.  There’s no way to add just a loose XAML file, even though it’s a fairly common need.  I feel like this can lead a new WPF developer to believing silly maxims like, "All Windows must have a XAML and code-behind file". 

So while I agree that an IDE can provide utility to a programmer, I also feel that the more code your IDE writes for you or the more templates you use then the more your architecture will be dictated by the tools you use, rather than the needs of your application.  I don’t suggest a wholesale switch to text editors, but I do feel like if you can’t use a text editor to write your code then you aren’t familiar enough with your language. 

Programmatically Creating Windows File Associations

A user on the VB Development Forum I’ve visited for a few years asked a question about creating file associations.  I chuckled and assumed that a Google search would return a wealth of information about the subject.  I was wrong; by my fifth combination of search terms I had found one site that had the minimal steps to get it done, and it wasn’t even correct.  The rest of the results were happy to discuss using the File Types tab of the Folder Options dialog to accomplish the task; this is not programmatic and not what the user wanted.  I remembered having a heck of a time trying to figure out how to make an association for all files (so I could have a right-click->Edit with hex editor option) so I decided I’d write up what I know.  Shame on you, internet, for letting the information get buried.

To start off, my example is technically incorrect.  I’m working with HKCR, but apparently the content here is generated based off of HKCU\Software and HKLM\Software. I assume this is so you can have per-user and global associations; I wrote my example using HKCR directly but you should probably use one of these two; please understand when I say HKCR I mean one of the other two locations.

I found the File Associations documentation, but haven’t had time to look over it properly.  For now, this should do.  In order to make it so that when you double-click a file your application opens you need three things:

  1. Your application should support opening a file from the command-line in some way.
  2. You need a registry key to associate a file type with the extension.
  3. You need a registry key to associate a program with the file type.

The first one is up to you; I can’t tell you how to do it.  The registry key to associate a file type with an extension is pretty easy.  File extensions are listed in HKCR under keys named after the extension (including the period!) The value of these keys is a string that defines the file type associated with the extension.  I tend to not use spaces in these, but I have no idea if spaces are unsupported; it will end up being the name of a subkey later and I’m too lazy to check if spaces are supported in subkey names.  For example, text files have the extension txt, and the key that specifies the file type is HKCR\.txt.  It’s default value is txtfile.

Now that there’s a file type associated with the extension, you need a registry key that tells the shell how to handle operations on the file type.  There’s lots of things to implement here, but I only know the basics.  File types are declared in subkeys of HKCR named after the file type; their subkeys and default values vary based on exactly how the file type is to be handled.  All I’m going to discuss is handling the "open" verb, which is generally invoked by double-clicking a file in the shell.  To add support for this verb, a tree of subkeys need to be created under HKCR\filetype. Working with our Notepad example above, we see HKCR\txtfile\shell\open\command.  It has a value that represents the path to Notepad and the replacement string %1 for the file that was selected.

Example time

Suppose we want to associate Notepad with the file extension .zzz.  We’ll start by defining a key for the file type:

HKCR\.zzz
Value="MyEditorFile"

Now, we create the file type key and associate the "Open" verb with notepad:

HKCR\MyEditorFile\open\shell\command
Value="%SystemRoot%\system32\NOTEPAD.EXE %1"

Note that though there are no quotes in the value for the open key, I’ve had trouble in the past when this string didn’t have anything that could possibly contain a space quoted. For example, I’m used to using:
"C:\Program Files\My Program\program.exe" "%1"
I’m not sure why Notepad’s special and doesn’t require this.   That’s really all I have to say on this topic for now; I am still looking over the documentation.