I love a technical challenge

| | Comments (6)

Someone reported on the lists recently that the ComboBox doesn't autocomplete on Windows. I thought, "well hey, there must be some sort of standard control for this."

And so the search began.

At first, I hacked in a quick and dirty solution where I'd capture the WM_KEYDOWN messages (before we translated them via the TranslateMessage call in the event pump). Capturing this message would let me search the combo box for matching strings using the CB_FINDSTRING and CB_SELECTSTRING messages. If there was a match, it would automatically select it as the text.

Well, this was really annoying. Let's say you had two strings "silly" and "sample" in the combo box. Well, typing "s" would bring you to silly, and then typing "a" would do nothing because nothing matched the a. Le stupid.

So then I checked out the SHAutoComplete API to see whether it would do the trick. However, this API is not a very good general purpose API since it only lets you do autocompletion of things like your internet history, recent files and file system items. Don't get me wrong, it's damn powerful at what it does and is a useful API. However, it's not useful in the general case.

But that got me thinking -- there has to be some other way to do this using COM. Most of the Shell functionality is implemented as COM objects after all.

Then I found the IAutoComplete interface. Bingo! It lets me enable and disable (on the fly) whether a particular edit field autocompletes. And since a ComboBox is comprised of an EditField and a ListBox (essentially) at the OS level, this would work perfectly.

The only problem was, I needed to remember how to implement a COM interface. It's been years since I've monkeyed with COM, so I basically had to go back and re-teach myself a lot of material. Needless to say, while educating myself, I remember just how ugly and worthless MFC is as a toolkit API. I actually got a small headache from looking at people's MFC code, that's how ugly I find it.

In any event, it didn't take long to get back in the swing of things. So I created a helper class that could be a COM-enumerable list of strings. Then I made the combo box contain one of these lists of strings which it would update on the fly. So when you call AddRow, it'd add the row to the physical ComboBox widget as well as internally udpate this list of strings.

Finally, it boiled down to creating an IAutoComplete object, getting its IAutoComplete2 interface from it (so that I could set the options I wanted) and initializing things. Once that was done, then BAM! Instant gratification.

There's nothing more satisfying that being given a technical challenge and solving it with such nice visual results. The combo box behaves just like you'd expect it to on Windows.

Huttah!

6 Comments

Excellent! And I gotta say "Holy crap you code fast!" :P

Some things are much easier to code up than others. In terms of brain-power, this was a middle of the road problem to solve. I just thought it was a nice challenge because it's been so long since I've played with COM at this level.

Fun stuff! Some days, I just looooove coding.

I second that! :)

BTW, have did you start to move into your house last night?

Yeah, I got the first load moved into the garage last night about 9pm. I think I've got another two loads to get done before all my stuff is over. Not certain when I'll move the office over, perhaps in the next day or two.

Are you already starting to live/sleep there?

I'm hoping to start living there tonight after work. :-D

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.