Choose Folder Dialog Box

2010-01-18

I know that whenever you start learning a new platform, you discover surprising omissions, but still I was shocked at something I learned recently about C#. As one of my first C# programs, I decided to write a little app that sets a random desktop background based on the files within a given folder. To my surprise, C# doesn’t give you a decent-looking dialog box to choose a folder. There is SaveFileDialog and OpenFileDialog, and even FontDialog and ColorDialog. These all seem pretty good. But then there is FolderBrowserDialog. It’s a tiny box with a tree-view that lets you navigate around the filesystem. Clicking those little plusses and minusses feels like setting DIP switches. You can’t start the user in whatever folder you want; he’s got to begin in one of a few pre-defined locations like My Documents or Desktop. It doesn’t seem to be very smart about shortcuts. You can’t see the path. There is no list along the left-side of commonly-visited places, as we have come to expect in every filesystem dialog these days. This is such a nasty, unprofessional bit of UI, I’m amazed it is still around and Microsoft hasn’t fixed it just to relieve the embarrassment. Certainly I’d be embarrassed to use it in one of my programs. Others must find it pretty bad also, because several replacements exist for it, including at least two commercial ones. I suspect Microsoft is pretty embarrassed about it, too, because they use something else for Word and Visual Studio–something that looks a lot like OpenFileDialog, but that lets you select a folder. I wonder how many times Microsoft has implemented this thing? But that just makes the ugly little FolderBrowserDialog more a mystery. If Microsoft keeps implementing a nice version of this dialog, one that looks like it actually belongs and wasn’t written by a kid for a school project, why don’t they push it into the API?

So anyway, I set out to find a better folder dialog. At first I thought about writing my own, but soon I decided it’d be easier to use an existing implementation. I liked the look of XFolderDialog, written in C++, so I figured I’d just compile it as a DLL and then call it with C#‘s DLLImport. I figured I could simplify things by exporting just a single function, something like this: int OpenDialog(LPCTSTR initialFolder, LPCTSTR title, CWnd* parentWindow, LPTSTR selectedPath) { XFolderDialog d(initialFolder, 0, parentWindow); d.SetOsVersion(CXFolderDialog::XFILEDIALOG_AUTO_DETECT_OS_VERSION); d.SetTitle(title); int result = d.DoModal(); if (result == IDOK) { wcscpy(selectedPath, (LPCTSTR)d.GetPath()); } return result; } Unfortunately it has all proved not so easy! I still haven’t quite worked everything out yet, but I have learned a ton about C# Interop, Windows DLLs, this new thing called “Managed C++” (now C++/CLI), and Visual Studio. There are so many lessons I’ve had to learn, I thought I’d better start this blog so I could remember them and sort them all out. The next few posts will go through them one-by-one. I can’t promise a happy ending, though. If all my efforts fail, I may have to fall back on a 100% C# implementation like this one here.

blog comments powered by Disqus Prev: Hello world! Next: Calling a C++ DLL from C#