What are the best methods for storing user preferences and settings in Win32 Delphi applications?

I want to save user settings (colors, toolbars on / off, panel width in pixels) and application parameters (last 10 files, default save directory, default default directory) in my Delphi Win32 application. What is the best practice for this?

+4
source share
5 answers

You have two main options:

  • Save the settings in a file under the user profile. If your settings are simple enough, then .ini files work fine.
  • Save the settings in the registry under HKEY_CURRENT_USER , which is also part of the profile.

Personally, I prefer to use the registry because it provides free hierarchical memory. If you are using a file, you must do it yourself, which may be a binding for more complex data.

On the other hand, if you want to write a portable application, that is, one that can live on a memory card, then the user settings file that is next to the executable file is the way to go.

+11
source

As @David points out, you can use the registry, files, or, of course, a combination of them.

If you send files, they must be saved in the current user part of the file system. In fact, the fundamental principle is that one user should not affect any other system user, and Windows applies this (for example, you cannot save files in the Program Files directory when working without elevated privileges 1 ).

For example, my AlgoSim software can save its settings in

 C:\Users\Andreas Rejbrand\AppData\Roaming\Rejbrand\AlgoSim\2.0 

folder. This is a typical example. You get the first part of the catalog, i.e.

 C:\Users\Andreas Rejbrand\AppData\Roaming 

by requesting the operating system for the application data folder for each user. You can use the SHGetKnownFolderPath function to find this. Use the folder identifier FOLDERID_RoamingAppData . If you need to support older versions of Windows, you can use SHGetFolderPath and use the constant CSIDL_APPDATA .

The rest of the path usually follows a pattern

 Manufacturer Name\Product Name\Product Version 

What files to store? Well, the easiest way is to use old-fashioned INI files, but you can also use XML, text files in your own format, or even binary files of your own design.

The second approach is to use the registry instead of files. You probably already know how to do this. If not, you will learn which of the examples is easy. For example, I can save the settings for each user in

 HKEY_CURRENT_USER\Software\Rejbrand\AlgoSim\2.0 

1 In this case, the operating system is smart enough to “emulate” the “Program Files” folder for each user. Although the program thinks it reads and writes to the Program Files folder, it actually reads and writes to the folder in the current user part of the file system. Thus, old and poorly managed applications continue to work even in new versions of the Microsoft Windows operating system, and in addition, they begin to support settings for each user, which they should have done first. I really think this is a +1 major for Microsoft, as I could say before.

+3
source

INI files always work well for me. There is TIniFile , so you can easily read and write files without much effort, you can assign default values ​​to nonexistent values, and the INI file is in a readable format so that the user can view and edit it if he wants.

Other solutions are possible, such as storing values ​​in the registry, but are often OS-specific and slightly more complex. I would use this if the user could not see / edit the values, but the application settings you specified are not "secret".

+2
source

I avoid storing anything in the registry whenever possible. My applications can easily be moved to another machine by simply copying the file from the CSIDL_APPDATA user folder.

... and I offer a component that helps: the TrsStorage library from www.deepsoftware.ru. In addition to providing simple save methods for a wide range of data types (including both small and large data types - strings, ints, float, streams, buffers, etc.), they have a component that you can omit on a form that refers to the published properties of all components in the form ... you simply mark the individual properties that you want to keep. No, this does not work for everything - like your "last 10 files". But it should work for your colors, on / off toolbars, panel width, default save directory, default open directory, etc.

TrsStorage has many manual methods for storing data and workarounds. I used them to implement a kind of inheritance tree for the report parameters, which makes it easy to send reports to the “descendants” to store settings that override the ancestor’s parameters, such as the default report font and font size. (The settings simulate the hierarchy of objects of my report types.) You can manually save the list of "last 10 files" using one of these manual method calls; in fact, there are ReadText / WriteText procedures that should work to store / retrieve the list of "last 10 files" if you store it in a TStrings object.

TrsStorage reads / writes from / to your choice of data file type: .INI, .XML or native .BIN format. And events are available to intercept write / read from a file and divert the stream to another place: we use it sometimes, for example, to store record settings in the BLOB field of the database table.

Finally, I have no connection with these people, but I have successfully used their TrsStorage components for many years.

+2
source

If this is a database application (uses a database), then also save the user settings in the database. I prefer to have a BLOB table in users, where I store user preferences in INI format. The main reason (using one BLOB per user) is that using the right normalization will probably slow down the launch of the application. One small caveat is that VCL TIniFile does not support loading content from TStream, you need to use some third party class or collapse your own to avoid saving data temporarily to disk.

0
source

All Articles