If I had a dollar for every time I’ve been “teased” about TSmiley, I could finance my own startup.
TSmiley, for those of you that don’t know or haven’t heard, is maybe the very first third-party VCL component ever. I built it for the first time way back in the fall of 1994 when I was on the original Delphi 1 beta. The VCL was brand new and in development, and the notion of building a component in Pascal was so cool, I couldn’t resist. (Remember, those were the days when the only “components” were VBX controls, used in Visual Basic, but written in C++. Remember when Delphi actually could consume VBX controls?)
I couldn’t wait to write components, and of course, half the battle is coming up with an idea – not always easy. Windows95 was brand new at that time, and so was MineSweeper. Remember the old school Minesweeper version, with the little smiley face up there? It was a fun game. I used to play on the smallest size and see how fast I could clear the board. Anyhoo – I thought it was cool that it has this little smiley on there that would make faces at you if you lost, etc. So I decided to build a Delphi-based version of this little control.
I built the thing with two purposes in mind: to learn how to build components and to create something that others could learn from. It started out as a descendant of TImage (made sense at the time — trust me) and I did a few things like override protected methods that fire events, trap and handle Windows messages, etc. I even figured out how to build a property editor for it.
I posted it on the Compuserve forums, and the next thing I know, Charlie Calvert, David I, and the Borland gang were all using it in demos all over the world. It became a pretty good running joke (to this day, Xavier Pacheco still teases me about it. Let it go, X….) and I sort of ran with it. I had a press release, I said things like “The usefulness of TSmiley cannot be measured” and I generally rode that handy little component to fame and glory. Okay, maybe not much fame and glory, but it was fun, and I do believe that folks learned a thing or two from it. I mean, the thing was basically useless (though I did have people tell me that they used it in production apps……) but it did show some interesting ways to build components.
Recently, someone on the newsgroups asked if there was a version that worked with Delphi 2010. So I scrounged around and found the code. I had to blow a few layers of dust off of it, but there it was, sitting on my backup/archive hard drive. I cracked it open, and man, was it embarrassing. Talk about code that was clearly written back in the early days before I could even pretend that I knew what I was doing. (At least I had changed it to descend from TGraphicControl) I mean, it worked, and for the time it was written it was pretty well done, but over the years, the “best practices” of component Delphi development have changed, and so it was time to update.
So, update I did. Here’s a summary of the updates that I made, and some discussion about why. Hopefully there are some tips in there.
- First thing I did was notice that I hadn’t followed the DRY (Don’t Repeat Yourself) principle. There was common code all over, and the bitmaps themselves were in both the runtime and the design-time packages. It would have been a real pain to add another TSmiley mood, so I added the bitmaps as resources to the runtime packages, I ensured that the design-time package got all of its needed information from the runtime package, and tried to refactor code patterns that repeated themselves. Hopefully thinks are much more efficient.
- I added a mini-API to TSmiley in the form of some class methods. These allow you to get a bitmap, a name, and a description for a given Mood from TSmiley without need an actual instance. (For instance, that’s how the
- I declared all the strings as resourcestring to help anyone that wants to localize TSmiley
- I updated the Mood property editor. The original property editor was a series of fixed speedbuttons with the bitmaps on them as glyphs. This was utterly inflexible, because you had to add another speedbutton if you added a new mood. Now, the Property Editor is a ListView that dynamically loads up the graphics, names, and descriptions without caring how many there are. This makes it much easier to add a mood as the new mood will automatically be added to the property editor.
- I made DoMoodChange virtual. This means you can more easily override it and add any functionality you might want to a descendent class. It is a good practice to have your events fired in a stand alone, virtual method. That way, you allow descendent components to easily augment the behavior if desired. If you have an event called OnMoodChange, it’s good to have a DoMoodChange method that is virtual and does nothing more than fire the event.
- I stopped trapping and handling WM_PAINT and simply overrode the Paint method. No need to illustrate how to do that anymore – too old school.
- I published a bunch of events from TControl that didn’t get published by TGraphicControl. Now you can provide handlers for events like OnMouseOver, OnDblClick, etc.
- I added the ClickMood property. The original TSmiley would wink at you if you clicked on it, but I figured that the face that shows up when you click should be configurable, so now you can set what mood you want to appear when a user clicks on TSmiley.
- I added two constant arrays, one for the Mood name and one for the Mood description. TSmiley will automatically update its own hint with the <short hint>|<long hint> pattern when the Mood is set.
- I added a small test/demo application that shows how TSmiley might be used, and to verify functionality. Nothing much – it just creates a TSmiley on the fly and toggles the mood, as well as displaying the hints.
That’s all I can remember right now – there are probably a lot of other subtle changes as well. I tooled around with it for a while until I felt comfortable with the code. I’m not claiming it’s any great chunk of code, but it looks “clean” and well organized to me.
In any event, hopefully this will bring TSmiley into the modern age. So, how do you get it? Well, I’ve put TSmiley up on SourceForge, making it easy for you to get and easy for to enhance, fix, and update. I’m totally open to enhancement ideas, bug reports, etc.
TSmiley is freeware, so have at it. And don’t worry, I can take all the teasing. After all, one really can’t describe how useful TSmiley is.