Shareware Beach

Thursday, 13 December 2007

Features and Customers

Filed under: Just Great Software — Jan @ 17:48

Last month I had the pleasure of meeting Bob Walsh at the European Software Conference. The evening after the conference, a bunch of us had dinner at a Mexican-Italian eatery near the Dom in Cologne.

During our conversation, Bob mentioned that EditPad Pro has been his favorite text editor for quite some time. He said that he got the impression that for the version 6 upgrade, I seemed to have focused on “ticking all the boxes” when comparing EditPad Pro with other popular text editors. Fact is, I hardly ever look at competing products.

My vision is that if I spend too much time looking at other products, I’ll just end up with copy-cat design for my own. It’s easier to design something new when starting with a blank slate than with starting with how things have been done before. At least it is for me. Just like it’s easier to learn a new habit than to unlearn a bad habit.

So how did I decide what to put in EditPad Pro 6 and what not? Easy: customer feedback. Many years ago, I spent an afternoon or two to hack together a simple bug and feature tracking database. It’s just four tables for products, versions, and issues in a master-detail relationship. The fourth table is the reason I rolled my own instead of using an off-the-shelf product. At the time, I couldn’t find anything that could keep a list of customers for each issue being tracked. So if Joe requests feature X, I email Joe a boilerplate “thank you for your feedback”, enter issue X into the database, and paste his email as a vote for issue X. That gives me a good idea of how many people care about X. That in turn allows me to estimate a cost/benefit ratio of implementing X.

It’s not a democratic system where issues with most votes get implemented. Reproducible bugs always get fixed, even if nobody complained, or “Just Great Software” wouldn’t be what it says on the box. Major new features or UI redesigns always get pushed ahead to the next major upgrade. While new features sell, product stability sells too. But when deciding what we have time for, and what needs to wait, customer feedback is a very useful metric.

Of course, Bob wasn’t completely off the mark. EditPad Pro 6 did add a lot of features that are, in some form, available in other text editors. Our customers have seen or even used those editors. “Product Z has X. When will EditPad have it?” is a very common request. But instead of just downloading product Z and plagiarizing the whole feature, I look at why the customer wants the feature. Most customers motivate their requests. Entering the relevant details into the feature tracking database helps to improve the feature’s design. E.g. when people were requesting built-in FTP for EditPad, it was obvious that the need was speed and convenience. The power of a stand-alone client wasn’t needed, because everybody already has one. Hence EditPad 6 got FTP as a sidebar that can stay connected to multiple servers for quick online editing. While that certainly ticks “FTP” on the feature matrix, such comparisons don’t show how happy people are with the feature’s implementation. E.g. had EditPad Pro 6 implemented FTP in a modal dialog, it would have been even less convenient than an external client. (Not that I ever considered such horrible design.)

The cherry on the cake is that collecting email addresses as votes gives you a very valuable means to contact your customers. When a new release fixes a bug or adds a feature that Joe emailed us about, Joe will get an automatic email saying the latest release implements X. Even though the message isn’t very polished (and it apologizes for being so), customers really appreciate this bit of attention.

My recommendation is to worry about making your customers happy rather than ticking all the boxes. Word-of-mouth is far more powerful than a doctored comparison from your marketing department hat.

Sunday, 9 December 2007

Nice Lens, Baby!

Filed under: Photography — Jan @ 17:57

As I’ve been taking my photography hobby more seriously, I’ve started to run up against the limitations of the Fuji F30 I’ve been using for the past two years. It’s a great pocket camera, but in the end it is a pocket camera. Particularly the tiny dragon-eyes-inducing flash you find on any pocket camera doesn’t cut it.

So the Olympus E-510 became my first SLR camera. Besides the fact that it has all the features I could want, I really like the fact that it’s relatively small and light. Particularly the kit lenses are very light, yet are optically just as good as kit lenses from other brands. If there’s anything I remember from my very first camera purchase, a 35mm film “compact”, is that a camera sitting on the shelf because it’s too big or too bulky doesn’t take many good pictures. I can easily walk around all day with the E-510 and FL-36 flash on it, without it starting too feel heavy. In fact, I did just that at the ESWC last month. I got good results, but also found I still have much to learn.

Besides the flash hotshoe, another key benefit of an SLR is that you can change the lens. As a beginner, I’m particularly interested in trying new creative options and exploring the capabilities of my tool. So I got myself a Lensbaby 2.0, which is a lens that you can bend. There’s absolutely no electronics in it. You focus by compressing it. You change aperture by swapping aperture discs. With no disk it’s f/2.0. f/2.8, f/4, f/5.6 and f/8 round aperture discs are supplied. I also purchased the creative aperture kit, which includes a star-shaped and a heart-shaped f/4 disc, as well as solid discs for you to cut up. (But heed the manual: don’t cut your fingers–you need those to focus the Lensbaby!) Specular highlights will take the shape of the aperture.

Here’s a shot of the low-hanging fruit on the mango tree in our garden. Sunlight, which I overexposed, comes through between the leaves.

Low-hanging fruit on a mango tree.  Taken with E-510, Lensbaby 2.0 and star-shaped aperture.

The main creative ability of the Lensbaby is that only a certain part of the image will be in focus, depending on how (or if) you bend the lens. Here’s a more typical shot that the Lensbaby is great for. Notice how Samira’s left eye (to the right in the picture) and nose are (nearly) in focus. There’s plenty of depth of field for her face. Yet, her right eye (at the left) and chin are out of focus. In the background there’s a bush with mostly red and some green leaves. Only a little bit of sunlight is coming through between the leaves.

Samira.  Taken with E-510, Lensbaby 2.0 and heart-shaped aperture.

I did not do any post-processing to either picture, other than shifting the exposure a little bit on the mango tree shot. The E-510 meters through the Lensbaby in P mode, but it seems not as well as through the Olympus lenses.

Tuesday, 27 November 2007

Don’t Lie to Me

Filed under: Software Development — Jan @ 7:50

If there’s one thing that I dislike more than helpless software that throws up error messages, it’s error messages that lie. After freshly booting my computer on a sunny Tuesday morning, Thunderbird tells me:

Thunderbird is already running but not responding.  To open a new window, you must first close the existing Thunderbird process, or restart the system.

Duh. I did just start up the system. There’s only one Thunderbird process. And it’s a big fat liar.

The actual problem is that I’m keeping my email on an encrypted volume. On sunny Tuesday mornings, it happens that I forget to mount it. Then of course Thunderbird can’t access my user profile and mailbox. In fact, the whole drive isn’t available until I retrieve the password from my dusty braincells.

How hard would it be for Thunderbird to give me a helpful error message? It notices it can’t access the profile, and that there isn’t another Thunderbird instance that it can bring to front. Check if the file exists. If it doesn’t, tell me the profile can’t be found, show me the path it’s trying to access, tell me why the profile is needed, and offer to cancel, retry or create a new profile. If it does exist, explain that the profile is locked, most likely due to another Thunderbird process having opened it and then gone the way of the Dodo. Apologize for the stuck process (as that could only be a bug), and suggest to kill it via the task manager or restart.

If you’re selling a product that pulls stunts like this, it’s costing you sales. Somebody will run into this on day two of their trial, reboot three times as the error message suggest, uninstall your product in frustration, and tell twenty-five people that you suck. Don’t expect your prospective customers, who are very unfamiliar with your software, to realize that they’ve shot themselves in the foot. So try to make those error messages helpful.

What does your software tell me when I select a recently used file from the “reopen” menu, and the file doesn’t seem to exist? Most software throws up its hands in despair: “File is gone–OK”. Well, that’s not OK. Here’s what you get in EditPad:

c:\I'm a goner.txt does not seem to exist any longer--Cancel--Retry

If I want to give up, clicking Cancel takes no more effort than clicking OK. But if I forgot to pop in the CD or mount the network drive that holds the file, I can do so and be on my way in a jiffy without having to go through the Reopen menu again.

Thursday, 22 November 2007

TMainMenu and Screen Readers

Filed under: Software Development — Jan @ 17:31

I figured out why screen readers don’t read the menu bar in EditPad Pro 6, even though it’s a plain vanilla Delphi TMainMenu. Since the menu uses images, it is an “owner-drawn” menu. That means that the Delphi code in Menus.pas does the drawing, rather than Windows. Screen readers apparently don’t like that.

There are several ways to fix this in your application. A simple fix is to set TMainMenu.Images and TPopupMenu.Images to nil as a user preference.

A more elegant fix, requiring no user intervention, is to call SystemParametersInfo(SPI_GETSCREENREADER, 0, @ScreenReaderActive, 0); where ScreenReaderActive is a variable of type BOOL. If the call sets it to True, the user has a screen reader, and menu Images should be set to nil.

A permanent fix is to edit Menus.pas to never owner-draw anything. Then you can’t forget removing the images from any menu. Define var ScreenReaderActive: BOOL; near the top of the unit’s implementation section. Put the SystemParametersInfo(SPI_GETSCREENREADER, 0, @ScreenReaderActive, 0); call in the initialization section. That handles the detection.

Then find the TMenuItem.AppendTo procedure. There’s a line:

IsOwnerDraw := Assigned(ParentMenu) and

Change it to:

IsOwnerDraw := not ScreenReaderActive and Assigned(ParentMenu) and

In TMenuItem.AdvancedDrawItem, below the (long) nested procedures, there is a line:

if (ParentMenu <> nil) and (ParentMenu.OwnerDraw or (ImageList <> nil)) and

Append not ScreenReaderActive and to this line.

Finally, change the TMenu.IsOwnerDraw function to:

Result := not ScreenReaderActive and (OwnerDraw or (Images <> nil));

Now your menu items will never be owner drawn when there’s a screen reader active.

P.S.: For Delphi to actually use a unit you’ve edited, you’ll need to delete its .dcu files from the \lib and \lib\debug folders in your Delphi install folder, and copy or move the modified .pas file to a folder that’s on Delphi’s library path. You can edit the implementation section of any unit with impunity. Editing the implementation section will cause the compiler to refuse any units that are linked from .dcu files rather than compiled from a .pas file that have the modified unit in their uses clause.

« Previous PageNext Page »