Giving Users What They Want (Including Respect)


I’m going to make a bold statement here. Bear with me:

RULE

Don’t assume your users understand the full inner workings of the computer (and don’t hold that against them). But don’t assume they’re stupid, either.

Here’s an example of where Microsoft messed up and assumed people are of a slightly lesser intelligence than they really are—and ultimately damaged many hard drives. The key sentence is “Hide extensions for known file types.” Does this sentence ring a bell? Most likely, since you’re a programmer, you have seen this sentence before.

When you first install Windows on a computer (any version these days), by default, the icons in the folders do not have their filename extension showing. So instead of ThisIsCool.exe, you will simply see ThisIsCool. The idea is that the icon itself should be a clue as to the type of program. If the file is ThisIsCool.doc, the icon will be that of Microsoft Word, since .doc files are normally associated with Microsoft Word. The users will then (supposedly) know what type of program the file goes with.

But the problem is icons are easy to fake. I could create a file called ThisIsCool.exe and embed a Microsoft Word icon inside it, making it look like a simple Word document, when in fact the file could be a virus. Very bad. Or, the icon might be meaningless to a user, and the user has no idea that he is opening an executable file. Not good at all.

And so we more experienced computer users always open the Folder Options dialog box on a new system (or on a friend’s computer), click the View tab, and uncheck the Hide Extensions For Known File Types option, as shown in Figure 1.3. (It’s checked by default!)

click to expand
Figure 1.3: The users can choose whether to hide extensions for known file types.

The idea was a noble one: Microsoft felt that users shouldn’t have to worry about the filename extensions, since that’s more of an internal issue. Who cares what the file type is? What matters is what’s inside the file! Right? Wrong. And now lots of users have been hit with viruses and inadvertently ran them without realizing they were executable files.

You can see that you have to find a balance: Don’t assume your users are stupid and can’t handle things, but don’t require your users to possess a complete knowledge of the intricate workings of the computer. Microsoft felt it was unnecessary to make the users understand what a .dll or .exe extension is. A little knowledge is important, and knowing what a .dll or .exe file is is important.

Software Libraries and Required Knowledge

These assertions about assuming that your users aren’t stupid but not making them understand the internals apply even if you’re creating software for other programmers. Suppose you’re creating a library of C++ classes. With this library you will ship a set of header files, possibly the source code, and likely a library file containing the linkable object code, either in the form of a static library with a .lib extension or a dynamic library with a .dll extension.

Now with such a library, don’t force your users (the programmers) to learn completely how the library works from the inside. They need to know how to use the library. If the library uses Newton’s Method to calculate a root of a polynomial, then definitely let the users know the algorithm used. That way they can decide whether it’s right for them. But don’t require them to understand that you used a stack structure and to know the names of the internal variables you used in your function. Do you see where the line is?

Of course, some users might want to know (or need to know!) such information. For those users, you can give them access to the source code of your Newton’s Method function. (However, you might not want to; it’s up to you.)

Just like with user-oriented software, keep your software libraries simple to use without requiring an advanced knowledge, but don’t make the advanced users suffer by not giving them the access they need.

start sidebar
The Private versus Protected Debate in Software Libraries

When you design a class library in a language such as C++, you have the option of declaring members of your class private rather than protected. (Remember, the only difference is that derived classes can access protected members but not private members.) This has been a great source of debate over the years. If you are designing a library, always give a lot of thought to whether you really want your class members, especially member functions, to be private. The reason is that people using your library might want to derive their own newer, refined classes from your classes. By making some of the members private, you might prevent these new classes from calling some important functions. By making them protected, the functions are still secure from being called by outside routines; however, the derived classes can call them when necessary.

end sidebar

Asking Too Many Questions

One sure-fire way to annoy your users is to program your software to ask too many questions. Remember, your users are intelligent people, and you’re safe making certain assumptions. And for those assumptions you’re not sure about, choose some answers that seem safe, and place these answers in a user preferences section. Then the users can change the preferences if they’re not happy with your answers.

In this section, I provide you with some questions that are annoying and you should avoid.

Are You Sure You Want to Quit?

Before you include a question such as “Are you sure you want to quit?” in your program, think about what would happen if you don’t include such a question. Here’s an example:

click to expand

For fun I included two extra windows that answer my question, “Why is it such a big deal?”

Suppose Happy User is using your program, and then she decides to quit. She saves the file she was working on and chooses File Close. The program shuts down.

But then she realizes she forgot to do something before quitting. Would the “Are you sure” question have helped here? Not really, if you look at it from a practical standpoint. What did she lose? Nothing. No data was lost. No problems ensued. All she has to do is restart the program and reload the previous document. No big deal. By having an “Are you sure you want to quit?” message, you are not giving any help to your users. If they mess up and really didn’t want to quit, let them go back in. Better that than frustrate the users by always having to click the “Yes I’m Sure!” button.

One popular online messaging program opens a dialog when you quit, warning you that the program will no longer function if you quit. Not only is that annoying, it is, frankly, insulting. If you’re going to choose to annoy your users, fine, but don’t insult them on top of it all. Annoyed users don’t like to be insulted. (And remember the ragingus maniacus hiding inside.)

Do You Want to Save Your Changes?

Although a question about whether you really want to quit is annoying, a question about whether to save the changes before quitting is important, unless you follow some important tips that I provide later on in this section. If a user has been working on a file and then quits the program and forgets to save, you want your program to warn the user and give him a chance to save the work.

However, a dialog box asking whether to save before exiting has the potential to be extremely confusing. Look at this:

click to expand

This dialog box has three buttons: Yes, No, Cancel. To us initiated folks, we know exactly what this means. But the reason I have a problem with it is that the beginner has to stop for a while and contemplate what this means. “Let’s see” he thinks. “Yes, I want to save changes.” Or “No, I don’t want to save them.” But what happens if you click No? Does that mean the program will not save but will quit? To us, we know that’s exactly what will happen. But to the beginner this isn’t necessarily clear. And what about Cancel? What does that mean?

Now you might argue that this is just an idiom; deal with it, and move on. But it’s not. Here’s why. I’ve fallen victim to the following dialog:

click to expand

This dialog box is diametrically opposed to the previous example and, therefore, not just a little bit evil but 100 percent evil. If I click Yes, this means the program will not save my work, whereas in the previous example, the program will save my work. The programmer who created this program was doing his duty by ensuring that work will not be lost. But the person messed up by flipping the logic from what we’re accustomed to.

Here’s a better dialog box:

click to expand

Unfortunately, this one is not standard. People who use Microsoft products all day long will have trouble with it, even though it’s a perfectly good solution. Oh, what to do? Instead, try this:

click to expand

This is a slightly modified version from what Microsoft Word uses, for example. This one conforms to the Windows way of doing things but gives the beginner a bit more help. If the user is confused, she has three ways to proceed:

  • She can click the Help button.

  • She can hold the mouse over the different buttons and see a tooltip.

  • She can click the little question-mark button and then click a button.

Now the tooltip and the question-mark button might seem a bit unintuitive to the beginning user. So these two choices are for the users who have explored Windows a bit and are familiar with these two conventions. The Help button, however, is a safe place for all users.

However, I personally feel this is not the best option. I think the previous option (with the radio buttons) was clearer. This is a case where you have to choose between clarity and conforming to the standard. What would I personally do? I’d prefer to take the Fifth on this, although I have a feeling I’d probably choose the radio button version.

But you have another option, as I alluded to at the beginning of this section. Instead, you can automatically save the file when the user quits the program. To a lot of programmers, this might seem like a shocking thing to suggest. But I would encourage you to explore it, because some programs already do it with success. Microsoft Outlook is one example. When you exit Outlook, you don’t have to save your changes. Instead, all your e-mail is saved automatically, and when you exit, you just exit.

But in the case of a word processor, this option might seem a bit strange. Here’s how you can make this work. First, remember that when the user is working on a document, most likely the work he’s doing is intentional. (He doesn’t just randomly hit a bunch of keys.) After the user works for about 10 minutes (or 30 seconds if the user presses Ctrl+S obsessively as I do!), you can assume that the work the user did was intentional, and if the user exits, you can simply save his work automatically for him, no questions asked.

But what about the .01 percent of the time where the user didn’t want to save his work? You can provide two approaches for these users:

  • Allow the users to open a copy of a file. Then, when the user exits your program, the program will save the changes to a new (possibly unnamed) file. (Of course, the very first time, you might want the user to type in the name of the file.)

  • Save a backup file before saving the new file.

  • Possibly include the undo list with the file itself. That way the user can undo any changes that were made prior to exiting the program. (I like this idea the best, because it really allows you to continue working the next time you come back to the document.)

Remember, your goal is to make the majority of the users happy. Occasionally a user might have a strange situation. She might have wanted to do all this work without saving it. In that case, include in your online help instructions for getting the old version back. But for the other thousands of times, the users really did want to save the work, and there was no reason for you to ask before doing so, each and every single time.

If you don’t believe me, think about this: How often do you save your work just before exiting? And if you don’t, how many times in your life have you seen the dialog box asking if you would like to save before exiting? And now think how much time you wasted by having to click that dialog box or by manually requesting a save just before exiting.

Questions That Yield an “I Don’t Know!” Answer

A question that yields an “I don’t know!” answer is typical during installation programs. Here’s an example of a question that most of us, even a skilled programmer, might sit and stare at for several moments, wondering what to do:

click to expand

Although I made this window myself, I based it on a dialog box that I actually saw the other day. First of all, the choice of “Yes” and “No” is rather arbitrary. Better buttons would be “Install New” and “Keep Old”, because “Yes” and “No” could easily result in a mistake.

But worse is the question itself. How should I know if I should install a newer version? A typical end user would have no clue and would just randomly pick one option. And for me, a programmer, I know that some other program might need the version that’s currently on the disk and won’t be able to run with the newer version (but I don’t know what program that is), and the program I’m installing might need the newer version and won’t be able run with the older version!

And if I’m feeling particularly ornery, I might even ask, “Why are you installing files in my System32 directory? Keep out!”

Don’t ask questions like this when you write an installation program. Put the files in your own directory, and the issue won’t even come up. And if you’re working with Windows and have to register an OLE component, either make your own version of the OLE component or know what the differences between versions are so you can be more specific in your questions.

Would You Like to Restart Windows Nowor Later?

After installing a software package, if the program tells me I need to restart the computer, I usually laugh and say “No” and run the program anyway just to see what happens. Maybe that’s a bit too impish, but I’ve reached a point in my computer life where I’m a bit fearless. I mean really now, what could possibly go wrong? Will I see an image of a little beastie go across the screen eating up all the bits on my hard drive because I forgot to restart Windows? Will my monitor start leaking poisonous fumes? What could go wrong?

Yet time and again, I’m told I need to reboot Windows. Here’s a typical dialog box:

click to expand

In addition to the fact that the beginning user might wonder what the Cancel button does (does it undo the installation?), there’s no reason for this dialog. Don’t make your users reboot Windows. If you make changes to the Registry, those changes take effect automatically. If you register an OLE component, those changes take place immediately. Don’t make them reboot. It’s not nice. (I will concede that there might be some exceptions to this, and that’s primarily when you’re installing lower-level software such as device drivers. However, make sure you absolutely have to, because these days even device drivers can be loaded and unloaded without having to reboot Windows!)

Tip of the Day

Although this isn’t a question, a Tip of the Day box is just as annoying as most unnecessary questions. Since the mid-1990s, the Tip of the Day dialog box has become popular. Here’s an example of one:

click to expand

Don’t use these. Period. Although in theory the idea is great (what better way to convey important information?), the reality is the Tip of the Day dialog box breaks every imaginable rule. First, very few people read them. They either always click OK or the first time the thing opens they click the Don’t Show This Again box. The information in the box is wasted, as is the time and energy you (the programmer) spent creating the box.

But worse, just what are the chances that your Tip of the Day dialog box is going to give the users some information that actually pertains to what they are going to do today? If I’m using a word processor to write a letter to a client, why would I need to see a Tip of the Day that explains how to import clip art? The Tip of the Day is wasted time and wasted space. Don’t bother with it.

Saving User Preferences

One way to minimize the use of annoying questions is by implementing a user preferences system, as I mentioned earlier. In the user preferences section, you can allow your users to customize your software through the use of a User Preferences dialog box.

But don’t go overboard; a User Preferences dialog box with 20 tabs and a million controls is frustrating, too, if the user is searching for a particular preference. Keep your User Preferences dialog box simple and easy to use.

Here are the steps you use for User Preferences:

  1. When the software opens, read the user preferences, either from a file or from the Registry, a database, or wherever you stored them.

  2. If the preferences are not found, set some defaults.

  3. When the user opens the User Preferences dialog box and clicks OK, save the preferences internally. (As for whether to save them to the file or the Registry at this point is up to you.)

  4. When the user shuts down your program, save the preferences to the file or the Registry.

You have some choices in implementing this kind of a system. For one, you might save only those preferences that are not defaults. If you’re writing software for the PalmOS, for example, where space is tight, this might be a good idea. Also, you have different ways in which you can allow access to the user preferences. Microsoft products typically have a Tools menu, with an Options dialog box underneath it. This is pretty much standard, although some other big software packages (most notably Netscape Navigator) use other means, such as putting Preferences under the Edit or File menu. Since Microsoft has created many of the standards we see on Windows, then if you’re writing a Windows program, I recommend following the Microsoft approach.

Tip

If you are programming for Microsoft Windows, make use of the Registry. You can save your preferences in the HKEY_CURRENT_USER area. In this area you will find a key called Software. Under this key you can create a key for the name of your company, and under the company key you can create a key for your product name. Standard practice is to have version numbers under the product name key. Finally, under the version numbers you can place your user preferences.

Another issue that comes up is that of multiple people using your program. You have various ways to handle this, too. If you’re storing your preferences to a file, you can save the file in an area specifically designated for the particular user. However, be careful with this approach. I don’t like it when a program dumps a file in the C:\documents and settings\jeff directory on my Windows computer. (I have a bad habit of purposely deleting such files!) Instead, under this same directory is another directory called Application Data. Under that directory, you’re free to create your own directory (again, don’t put the file right in the Application Data directory), and inside your own directory, you can put your file. The advantage there is then you know what the file is if you go poking through these directories.

For example, right now I see this file on my computer: C:\Documents and Settings\jeff\Application Data\dmqr.ini. I have no idea what this file is, but it’s the only file in this directory. Everything else in this directory is a subdirectory with the name of a company or product. I think I’ll go delete it (but if you put it there, please expect a support call from me when your program doesn’t work; but don’t worry, I’m friendly and don’t bite).

Tip

Remember that multiple people may well use your program. Therefore, if you have a user preferences system, save the preferences on a per-user basis, not just on a system-wide basis. When programming for Microsoft Windows, you can save on a per-user basis by saving the preferences in the HKEY_CURRENT_USER area of the system Registry and not the HKEY_LOCAL_MACHINE area.

Remember the Keyboard?

A long time ago when Windows 3.1 was the great new thing, I wrote a memo to several coworkers explaining that the notion of a keyboard shortcut was stupid, and it’s safe to assume at that day and age (roughly 1993) that every computer running Microsoft Windows had a mouse attached to it.

What was I thinking!

Hey, I had 10 years less experience than I do now, and I had a lot to learn about life. (Sounds like a song.) Needless to say, I no longer agree with the notion that keyboard shortcuts are not needed. In fact, I use them all the time. Lots of people do. Why? Because:

  • They’re faster if you’re a fast typist (like me and all the piano players of the world).

  • They’re more convenient than reaching over to grab the mouse, moving it to where it needs to go, and clicking it.

  • They’re configurable; I can make Ctrl+Alt+S do what I want it to do, which is something you can’t say about clicking with the mouse.

However, these points are true only when the software application includes a decent keyboard shortcut interface. What makes for a decent keyboard shortcut interface? Here I list what I personally expect out of one. (And trust me, I use keyboard shortcuts a lot, so for now, consider me your favorite user.)

Note

People used to use the term hot key for keyboard shortcut. Somewhere along the lines, Microsoft instilled the term keyboard shortcut into our vocabulary, and these days, that’s what most people say. I still prefer hot key, because I like shorter words, and the word shortcut is overused in Microsoft products: A shortcut on a desktop is a symbolic link to another program; a shortcut in Internet Explorer is a hypertext link.

The Shortcut System Is Implemented.

You want to make sure you actually implemented the keyboard shortcut system. For starters, most better programs include shortcut keys on the menu items. The Mac often uses the Apple key for its shortcut keys. Windows often uses the Ctrl key. On both the Mac and Windows you can see the shortcut key for a menu item by clicking on the menu; the shortcut key is shown to the right of the menu item name.

Further, on Windows, you can add an additional shortcut key for the menu bar. Put an ampersand, &, inside the text for the menu, and the letter following the ampersand will show up underlined. For example, if you call your first menu &File, the menu will show up as File. Then, when the user holds down Alt and presses F, the File menu will open.

For menu items under the menu, you again use an ampersand to specify which letter is underlined. But for these shortcuts, the user first must open the menu (such as by pressing Alt+F) and then type the underlined letter (with or without the Alt key).

The Dialog Boxes Make Use of the Tab Ordering.

As a self-professed keyboard shortcut whiz, I find the lack of tab ordering always frustrating. Yet, it’s amazing how many software designers and testers completely overlook this. Again and again I find software where the tab ordering is all messed up.

When a dialog box opens, typically you will want the focus to be on the control closest to the upper-left corner of the dialog box. For example, if that’s an edit control, then the user doesn’t have to first click that edit control to type text into it. The user simply starts typing and the text appears, because that’s the control with the focus.

Then, if the user presses Tab, the focus should move to the next control to the right, if there is one, and down if there’s not one to the right. The focus should move from right to left and top to bottom, just like the words in your code editor.

However, the Enter key is special, and so is the Esc key. When you design a dialog box, you can specify which button is the active one. The active button shows up with a dark border around it, like the OK button shown here:

Regardless of which control has focus, if the user presses Enter, the OK button should click. Pressing Esc should be the same as clicking the Cancel button. (Doing so is in line with the standard idioms that people expect of your software.)

Standard Keyboard Shortcuts Mean What They Usually Do.

Prior to version 2000 of Microsoft Outlook, many of us had a problem with sending e-mail midway through the composition of the e-mail. Why was that? Because Microsoft made a blunder. For quite some time, Microsoft has always used Ctrl+S as the keyboard shortcut for Save. And so those of us who had “Save Early Save Often” beat into our heads would press Ctrl+S almost obsessively. (I do to this day. In fact, I better go do it right now. There, I feel much better. Never know when a power outage might come and I’ll lose the last three words.)

But not with Outlook 97. In Outlook 97, Ctrl+S was the shortcut for none other than Send. And so during the composition of an e-mail, many of us would out of sheer reflex, about half-way through the e-mail, press Ctrl+S. And much to our shock, the message window would disappear and we’d see the little words “Sending Message 1 of 1” appear at the bottom of our Outlook screen.

See, Microsoft violated a standard idiom. We all knew that Ctrl+S meant Save. And guess what? In Outlook 2000 and beyond, Ctrl+S now saves the e-mail into your Drafts folder. It doesn’t send the message. Whew!

Remember that most people expect various keyboard shortcuts to mean something. Please don’t rearrange these, because you’ll frustrate users like me who operate out of 90 percent reflex. The big ones are:

  • Ctrl+S = Save

  • Ctrl+C = Copy

  • Ctrl+V = Paste

  • Ctrl+X = Cut

  • Ctrl+F = Find

  • Ctrl+R = Replace, although Microsoft these days usually insists on Ctrl+H. Should we listen to them or not? This one is your call.

And some people like to use Ctrl+Q to quit. That’s fine, if you like that one. We all have slightly different opinions on these. Just don’t make Ctrl+S send e-mail. Please?

Keyboard Shortcuts Should Be Configurable.

Even though I just listed the “big ones,” some people still get frustrated at these. But that shouldn’t be a problem, because you’re about to make your keyboard shortcuts configurable. Include some sort of dialog box that allows me (the user) to choose what I want the keyboard shortcuts to do.

The common way to do this is by developing a set of use cases for your product, which are basically the elemental things that people can do with your product. Some people call these commands. If you start one of the Microsoft Office products, and right-click on a toolbar or menu and choose Customize, you’ll see a dialog box listing all the commands. For example, in Microsoft Word, you’ll find a command for pretty much everything you can do, such as Toggle Italic; Toggle Bold; Insert Column Break; and so on.

When you design your software, if you divide the functionality into use cases or commands and then break each of these into its own function (or member function if you put it in a class), then you can easily create a configurable system. All you have to do is list all the names of the commands in a dialog box and for each one let the user choose a keyboard sequence. The sequence can include the Ctrl key, the Alt key, or the Shift key, or any combination thereof. For example, you might want to assign Ctrl+Shift+I to the command Toggle Italic.

And how do you implement this? Through function pointers, of course. Use a common function prototype for each function, and it’s a snap: Store the function pointers in a table of keyboard shortcuts (or some other list or array), and then when the user presses a key sequence such as Ctrl+Shift+I, look up the function that goes with that key (such as the address of toggleItalic) and call the function. Since all the functions have the same function prototype, you will know exactly what to pass to the function.

This is actually easier than it sounds. Although this part of the book doesn’t focus so much on coding, here’s a sample design pattern in C++ that does the trick using the C++ standard library’s map class. I wrote the code from scratch and compiled it using the gnu gcc compiler:

 #include <iostream>  #include <map>  #include <string>  using namespace std;  typedef void (*command)();  // Here are the commands  void toggleItalic() {      cout << "italic toggled" << endl;  }  void toggleBold() {      cout << "bold toggled" << endl;  }  // Here’s the class for the shortcuts  class Shortcuts {  protected:    map<string, command> shortcuts;  public:    void CallCommand(string sequence);    void ReplaceCommand(string oldsequence,      string newsequence, command cmd);  };  void Shortcuts::CallCommand(string sequence) {    if (shortcuts[sequence] != NULL) {      shortcuts[sequence](); 

   }  }  void Shortcuts::ReplaceCommand(string oldsequence,    string newsequence, command cmd) {    if (oldsequence != "")      shortcuts[oldsequence] = NULL;    shortcuts[newsequence] = cmd;  } 

Then, using this code is easy. To assign the keystroke Ctrl+I to the function called toggleItalic, call keys.ReplaceCommand("", "cI", &toggleItalic) (where keys is the name of the object). Then when the user presses Ctrl+I, simply call keys.CallCommand("cI"). Here’s a sample main demonstrating this:

 int main(int argc, char *argv[])  {    Shortcuts keys;    keys.ReplaceCommand("", "cI", &toggleItalic);    keys.ReplaceCommand("", "cB", &toggleBold);    // Assume user pressed Ctrl+I. Then call this:    keys.CallCommand("cI");    // Assume user pressed Ctrl+B. Then call this:    keys.CallCommand("cB");    // Assume user pressed something unassigned:    keys.CallCommand("aQ");    // User reconfigures italic to be Alt+I:    keys.ReplaceCommand("cI", "aI", &toggleItalic);    // Now user presses Alt+I    keys.CallCommand("aI");    return 0;  } 

Once you implement a design pattern such as this, keyboard shortcuts (and menus and toolbar buttons) all become a snap. You can use the same interface for a menu; instead of mapping keyboard shortcut names such as “caI” to a function, you map menu item IDs to a function. And similarly with toolbars, you would map toolbar button IDs to a function.

Such a system is incredibly easy to implement, provided you know how to program various design patterns and that you fully understand your programming language.




Designing Highly Useable Software
Designing Highly Useable Software
ISBN: 0782143016
EAN: 2147483647
Year: 2003
Pages: 114

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net