SystemParametersInfo (user32)
Last changed: -212.117.77.91

.
Summary

C# Signature:

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, String pvParam, uint fWinIni);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, ref ANIMATIONINFO pvParam, uint fWinIni);

User-Defined Types:

SPI, ANIMATIONINFO

VB.Net

    Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Integer, _
      ByVal uParam As Integer, ByVal lpvParam As Integer, _
      ByVal fuWinIni As Integer) As Integer

Notes:

None.

Tips & Tricks:

When using the SPI_GETANIMATION or SPI_SETANIMATION actions, the uiParam value must be set to (System.UInt32)Marshal.SizeOf(typeof(ANIMATIONINFO)).

Sample Code:

    // This code works for SPI_GETFOREGROUNDLOCKTIMEOUT, the above signature doesn't. (Ken)

    [DllImport("user32.dll", EntryPoint="SystemParametersInfo", SetLastError = true)]
    public static extern bool SystemParametersInfoGet(uint action, uint param, ref uint vparam,     uint init);

    [DllImport("user32.dll", EntryPoint="SystemParametersInfo", SetLastError = true)]
    public static extern bool SystemParametersInfoSet(uint action, uint param, uint vparam,     uint init);

    // get current lock timeout value
    uint timeout = 99;
    bool retVal = SystemParametersInfoGet(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref timeout, 0);
    // set current lock timeout value to 0, so focus can be grabbed
    SystemParametersInfoSet(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0);

SPI_GETNONCLIENTMETRICS is a good way to get user-defined preferences for fonts, colors, icons, etc. There is no other way to do this in .NET as far as I know!

    // We can overload this definition, since that's in effect what the unmanaged
    // API does anyway.
    [DllImport("user32", CharSet=CharSet.Auto)]
    private static extern int SystemParametersInfo(int uAction,
        int uParam, ref NONCLIENTMETRICS lpvParam, int fuWinIni);

    private const int LF_FACESIZE = 32;

    // A "logical font" used by old-school windows
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    private struct LOGFONT
    {
        public int lfHeight;
        public int lfWidth;
        public int lfEscapement;
        public int lfOrientation;
        public int lfWeight;
        public byte lfItalic;
        public byte lfUnderline;
        public byte lfStrikeOut;
        public byte lfCharSet;
        public byte lfOutPrecision;
        public byte lfClipPrecision;
        public byte lfQuality;
        public byte lfPitchAndFamily;

        /// <summary>
        /// <see cref="UnmanagedType.ByValTStr"/> means that the string
        /// should be marshalled as an array of TCHAR embedded in the
        /// structure.  This implies that the font names can be no larger
        /// than <see cref="LF_FACESIZE"/> including the terminating '\0'.
        /// That works out to 31 characters.
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=LF_FACESIZE)]
        public string lfFaceName;

        // to shut it up about the warnings
         public LOGFONT(string lfFaceName)
        {
            this.lfFaceName = lfFaceName;
                  lfHeight = lfWidth = lfEscapement = lfOrientation = lfWeight = 0;
                  lfItalic = lfUnderline = lfStrikeOut = lfCharSet = lfOutPrecision
                  = lfClipPrecision = lfQuality = lfPitchAndFamily = 0;
         }
    }

    private struct NONCLIENTMETRICS
    {
        public int cbSize;
        public int iBorderWidth;
        public int iScrollWidth;
        public int iScrollHeight;
        public int iCaptionWidth;
        public int iCaptionHeight;
        /// <summary>
        /// Since <see cref="LOGFONT"/> is a struct instead of a class,
        /// we don't have to do any special marshalling here.  Much
        /// simpler this way.
        /// </summary>
        public LOGFONT lfCaptionFont;
        public int iSMCaptionWidth;
        public int iSMCaptionHeight;
        public LOGFONT lfSMCaptionFont;
        public int iMenuWidth;
        public int iMenuHeight;
        public LOGFONT lfMenuFont;
        public LOGFONT lfStatusFont;
        public LOGFONT lfMessageFont;
    }

    private const int SPI_GETNONCLIENTMETRICS = 41;

OK, so here is how you query for the NONCLIENTMETRICS

    NONCLIENTMETRICS metrics = new NONCLIENTMETRICS();
    metrics.cbSize = Marshal.SizeOf(metrics);
    SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, ref metrics, 0);

Now you can use the font info however you want. Here's how to return a GDI+ Font corresponding to the MessageBox font selected by the user. Note that the height is always negative and always returns "world" units.

    return new Font(Metrics.lfMessageFont.lfFaceName,
                    -Metrics.lfMessageFont.lfHeight,
            GraphicsUnit.World);

Changing the wallpaper. Note, only works for BMP. Must convert to BMP format if using JPEG, GIF, etc.

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, String         pvParam, UInt32 fWinIni);
    private static UInt32 SPI_SETDESKWALLPAPER = 20;
    private static UInt32 SPIF_UPDATEINIFILE = 0x1;
    private String imageFileName = "c:\\sample.bmp";

    public void SetImage( string filename )
    {
        SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, filename, SPIF_UPDATEINIFILE);
    }

Return type of some native methods like SystemParametersInfo is bool. They should be marked by System.Runtime.InteropServices.MarshalAsAttribute.

    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SystemParametersInfo(SystemParametersInfoActions uAction, uint uParam, ref uint lpvParam, uint fuWinIni);

Alternative Managed API:

The System.Windows.Forms.SystemInformation managed class, which uses SystemParametersInfo internally, has many (but not all) static properties containing user information, system setup, and preferences.

Also, System.Drawing.SystemFonts contains all the font settings which can be returned by SystemParametersInfo.

Documentation