by Tandy Trower
January 6, 1996
Human beings function best in an environment in which they feel in control of their circumstances. They also prefer a working environment in which things remain as they were left.
Imagine how disruptive it would be if you carefully arranged papers and books on your desk for a particular task, only to return the next day to find that someone had rearranged them. Yet most applications are designed exactly this way. When a user restarts Windows, documents that were open when the system was last shut down are rarely restored. Similarly, reopening a document's window rarely redisplays the window in the same location or size, let alone restores its previous selection and scroll position.
Where applications do retain information, such as content, they typically put the burden of retaining state on the user's shoulders. Users choose an explicit command (for example, Save) to retain their data; otherwise they lose whatever changes or additions they made.
This is an unnatural model, a tradeoff designed primarily to handle technology limitations. In the non-PC world, the act of creation implies persistence. For example, writing down a set of notes with pen and paper doesn't require clicking a Save button. Information automatically persists. Removing it requires an explicit action. With such a reversed model, it is not surprising that many new computer users find PC applications difficult to understand. However, this need not be the case, especially with some of the new conventions in the Windows 95 operating system.
Have you noticed that, on startup, Windows automatically restores folder windows that were open when the user shut down the system? This is a good example of persistence. What you may not be aware of is that your application can support the same model. It just takes a bit of extra work.
When a user clicks the Shut Down command or chooses to log off, your application gets a WM_ENDSESSION message from the system. At this point, in addition to saving the user's data, you can also store the state of the application and its window. For example, consider storing the position and size of the window, view type, scroll position, current selection, and probably the location and configuration of any toolbars and any supporting windows such as floating palette windows. You can store this state data in the registry in a subkey entry you create under:
HKEY_CURRENT_USER\Software
\CompanyName\ProductName\Version
where the entries in italics represent your application. The structure you create under this subkey is up to you. Use the registry rather than an .INI file because the registry allows you to tailor what you are saving to the specific user who has logged on.
Then, add a data name-value pair entry to the RunOnce subkey of HKEY_CURRENT_USER. You may have to add the subkey if it doesn't already exist (under the CurrentVersion subkey). The data name-value pair should correspond to a unique application identifier and appropriate command line to restart your application with the appropriate data. You may want to support a command-line parameter for starting up from system startup. For example:
HKEY_CURRENT_USER Software Microsoft Windows CurrentVersion RunOnce WordPad Document 1 = C:\Program Files\WordPad.exe Letter to Bill /R
When the system restarts, and the corresponding user logs on, your command line will be executed. When your application starts, you can use the command line you stored here and the state data you stored in your application's CompanyName \ ProductName \ Version subkey to restore the application to its previous state. Once executed, the RunOnce entry is removed by the system, which means you have to write this entry into the registry each time you handle the shutdown message.
Be careful not to confuse the RunOnce entry under HKEY_CURRENT_USER with the RunOnce entry available under HKEY_LOCAL_MACHINE. This latter entry runs the associated command line before Windows starts and affects all users who use the computer.
You need not limit preservation of state to system shutdown. Recording and restoring the state can be applied between any opening and closing of a file. Of course, in this scenario you need to consider further how you will store state. While you can still use your registry entries, you don't want to store state for every file the user opens. Instead, you might want to cache some limited number, just as the system retains only a limited number of files for the Documents submenu in the Start menu. Alternatively, consider storing the state in the file itself.
In general, the principle of returning to the previous state when a user reopens a window can be applied to secondary windows as well. For example, if the user displayed a palette window at a particular location, closed it, and then reopened it, place it at the same location. Similarly, it is usually best to set an Open dialog box to the same location as the last file that was opened. When supporting tabs (tabbed pages) in property sheets or other secondary windows, it is usually best to return to the last page a user accessed, rather than always return to one particular page, because most property-oriented activities are repetitive.
As with most rules, there are exceptions to the principle of using persistence to display information. If the structure of a task benefits users by always starting with a fixed presentation, it is appropriate to use that model instead. For example, "wizard" user assistance-style designs (as you find in Windows 95 when you install a new printer) always begin at the starting page. For sequential processes, this makes more sense.
Similarly, the context of how something appears may affect how you present information. For example, if the resolution or orientation of the screen changes, you may need to adjust where a window appears. Obviously, you don't want a window appearing offscreen. Likewise, pop-up context-sensitive Help windows need to be positioned based on what they describe. In addition, message box windows are usually better displayed in a consistent location (centered relative to the screen) than where the user may have moved the last message box window.
For file-oriented applications, you should consider evolving toward a continuous save model where changes are automatically saved. For example, no one assumes that you have to choose a Save command after changing the contents of a folder to preserve those changes. Similarly, Microsoft Schedule+ presents a model where new entries or changes to existing appointments are automatically updated. This is a great model because users never have to think about preserving their changes. The system automatically handles this for them.
However, continuous or transparent saving of changes is not the full story. Applications that attempt continuous save without supporting the ability to revert may result in users inadvertently losing data since they often modify or experiment with existing data. In some scenarios, users may wish to make changes and still return to their previous state. For these situations, you will still want to provide users with the ability to roll back changes either through an Undo facility or some type of automatic backup support (or both) that allows them to return to their original or last checkpoint.
This doesn't mean that existing applications looking to evolve toward a continuous save model need to abandon their existing Save command. The command can still be used for creating checkpoints and supporting the transition to a more automated model.
There may be exceptions to automatically maintaining state, but it is still an important model that needs to be considered. Too often the easy way out is to ignore the issue or leave the user with the burden of preserving state. The objective of good software design should be to improve users' ease of use and efficiency in accomplishing their tasks.
Tandy Trower was, is, and persistently continues to be the director of user interface design at Microsoft, although friends think of him as the Secretary of State.