What are the best practices for storing user prefe

2019-02-11 00:01发布

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

5条回答
唯我独甜
2楼-- · 2019-02-11 00:40

I avoid storing anything in the Registry whenever possible. My apps are easily moved to another machine, by just copying a file from the user's CSIDL_APPDATA folder.

...and I'll suggest a component that helps: TrsStorage library from www.deepsoftware.ru. Besides providing easy persistence methods for a wide range of data types (including both small and large data types--strings, ints, floats, streams, buffers, etc.), they have a component you can drop onto a form, which accesses the published properties of all components on the form...you just check mark the individual properties you want to persist. No, it doesn't work for everything--like your "last 10 files" requirement. But it should work for your colors, toolbars on/off, panel widths, default save directory, default open directory, etc.

TrsStorage has lots of manual data storage & traversal methods as well. I've used those to implement a sort of inheritance tree for report settings--making it easy for "descendant" reports to store settings which override "ancestor" settings such as the default report typeface & font size. (The settings mimic the object hierarchy of my report types.) You could manually save your "last 10 files" list using one of these manual method calls; in fact, there are ReadText/WriteText procedures that should work for storing/retrieving your "last 10 files" list if you keep it in a TStrings object.

TrsStorage reads/writes from/to your choice of data file type: .INI, .XML, or its own .BIN format. And events are available for intercepting the write to/read from the file, and diverting the stream elsewhere: we use that sometimes for, say, storing per-record settings in the BLOB field of a database table.

Finally, I have no connection with these folks, but I've successfully used their TrsStorage components for years.

查看更多
霸刀☆藐视天下
3楼-- · 2019-02-11 00:48

INI files always work good for me. There's TIniFile, so you can easily read/write the files without much work, you can assign default values to non-existant values and the INI file is in a human-readable format so the user can have a look at it and edit it if he wants.

Other solutions like storing values in the registry are possible, too, but often OS-dependant and a bit more complicated. I'd use such if the user shouldn't be able to see/edit the values, but the application settings you mentioned aren't much of a "secret".

查看更多
Explosion°爆炸
4楼-- · 2019-02-11 00:57

You have two main options:

  1. Store the settings in a file under the user profile. If your settings are simple enough then INI files work perfectly adequately.
  2. Store the settings in the registry, under HKEY_CURRENT_USER which is also part of the profile.

Personally I prefer to use the registry since it provides hierarchical storage for free. If you use a file, then you have to do that yourself which can be a bind for more complex data.

On the other hand, if you want to write a portable app, i.e. one that can live on a memory stick, then a user settings file that sits alongside the executable is the way to go.

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-02-11 00:57

If it is a database app (uses database) then store user preferences into database too. I prefer to have an BLOB in users table where I store users's preferences in INI file format. The main reason (using one BLOB per user) is that using proper normalization would likely slow down app's startup. One small caveat is that VCL's TIniFile doesn't support loading content from TStream, you have to use some thirdparty class or roll your own to avoid saving the data temporarily on disk.

查看更多
Juvenile、少年°
6楼-- · 2019-02-11 01:05

As @David points out, you can use the registry, files, or -- naturally -- a combination of those.

If you go for files, you have to store them in the current user's part of the file system. Indeed, it is a fundamental principle that one user should not affect any other user of the system, and Windows enforces this (for instance, you cannot save files in the Program Files directory when running without elevated privileges1).

For instance, my AlgoSim software could store its settings in the

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

folder. This is a typical example. You get the first part of the directory, that is,

C:\Users\Andreas Rejbrand\AppData\Roaming

by asking the operating system for the per-user app data folder. You can use the SHGetKnownFolderPath function to find this. Use the FOLDERID_RoamingAppData folder ID. If you need to support older versions of Windows, you can use SHGetFolderPath instead, and use the CSIDL_APPDATA constant.

The rest of the path normally follows the pattern

Manufacturer Name\Product Name\Product Version

What files to store? Well, the simplest way is to use old-fashioned INI files, but you can also use XML, plain-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. This you probably already know how to do. If not, you'll learn that from examples easily. For instance, I could store my per-user settings in

HKEY_CURRENT_USER\Software\Rejbrand\AlgoSim\2.0

1 In this case, the operating system is smart enough to 'emulate' a per-user 'Program Files' folder. While the program thinks that it is reading from and writing to the Program Files folder, it is in fact reading from and writing to a folder in the current user's part of the file system. This way, old and badly behaved applications continue to work even in newer versions of the Microsoft Windows operating system, and, in addition, they begin to support per-user settings, which they should have done in the first place. I really think this is a major +1 to Microsoft, as I might have said before.

查看更多
登录 后发表回答