The SystemParametersInfo function gives you access to a whole slew of user interface settings, and it is the only supported method for changing those settings.

I'm not going to list every single setting; go read the list yourself. Here are some highlights:

  • SPI_GETICONTITLELOGFONT lets you query the font that is used for icon labels; SPI_SETICONTITLELOGFONT lets you change it.
  • SPI_GETNONCLIENTMETRICS lets you query the fonts that are used for window captions, menus, status bars, and message boxes; SPI_SETNONCLIENTMETRICS lets you change them.

Here are some control panel settings.

  • SPI_SETKEYBOARDDELAY and SPI_SETKEYBOARDSPEED let you set the keyboard autorepeat parameters.
  • SPI_SETDOUBLECLICKTIME lets you set the mouse double-click speed.
  • SPI_SETMENUFADE lets you enable or disable the menu fade animation. [Typo fixed, 4pm.]
  • There is a whole series of SPI_SETxxxANIMATION settings that let you control which screen elements animate.

Notice that when using the SPI_SET* commands, you also have to choose whether the setting changes are temporary (lost at logoff) or persistent. The historically-named SPIF_UPDATEINIFILE flag causes the changes to be saved to the user profile; if you leave it off, then the changes are not saved and are lost when the user logs off. You should also set the SPIF_SENDCHANGE flag so that programs which want to refresh themselves in response to changes in the settings can do so.

The fact that there exist both temporary and persistent changes highlights the danger of accessing the registry directly to read or write the current settings. If the current settings are temporary, then they are not saved in the registry. The SystemParametersInfo function retrieves the actual current settings, including temporary ones. For example, if you want to query whether menus are being animated, and the user has temporarily disabled animation, reading the registry will tell you that they are being animated when in fact they are not.

Also, changes written to the registry don't take effect untll the next logon, because that is the only time the values are consulted. To make a change take effect immediately, you must use SystemParametersInfo.

It still puzzles me why people go to the undocumented registry keys to change these settings when there is a perfectly good documented function for doing it. Especially when the documented function works and the undocumented registry key is unreliable.

I remember one application that went straight for the undocumented registry keys (to get the icon title font, I think). Unfortunately for the application, the format of the registry key is different between Windows 95 and Windows 2000, and it ended up crashing. (It expected the Windows 95 format.) If it had used the documented method of retrieving the icon title font, it would have worked fine. In other words, this program went out of its way to go around the preferred way of doing something and got hoist by its own petard.