Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

SystemParametersInfo (user32)
 
.
Summary

C# Signature:

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

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

User-Defined Types:

SPI, ANIMATIONINFO

Notes:

None.

Tips & Tricks:

Please add some!

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);

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.

Documentation

Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

 
Access PInvoke.net directly from VS:
Terms of Use
Find References
Show Printable Version
Revisions