How to programmatically remove icon shadow (in C#) – SystemParametersInfo function

Last week some users complained, that desktop icon shadow is not preperly rendered. As you can see some icons have got shadows and some don’t:

visual_effects_2

So we decided to remove the shadow at all. It’s very simple – you just have to go to “System Properies” -> “Advanced” -> “Perormance settings“. On “Visual Effects” tab you just have to uncheck “shadows” options.

visual_effects_1

That’s great, but what if we block those option for users. We can always make a GPO policy and set it, when users is logging in. But these solution will work after second logon (after first logon settings will be set into registry, and will be applied for user after next logon). But in out environment we are deleting user local profile every day. So user will never get these option correctly applied.

I decided, to make it programmatically. Here is the system API function that controls many system parameters (get and set property):

BOOL WINAPI SystemParametersInfo(
  _In_     UINT uiAction,
  _In_     UINT uiParam,
  _Inout_  PVOID pvParam,
  _In_     UINT fWinIni
);

Documentation you can always find on MSDN page.

So now we have the function, but many examples, that I’ve found on the net was written in C++. I have some basics with those language but I prefere to use C#. So here it is. C# code:

using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace IconShadowRemover
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SystemParametersInfo(
            uint uiAction,
            uint uiParam,
            bool pvParam,
            uint fWinIni
        );

        const uint SPI_SETDISABLEOVERLAPPEDCONTENT = 0x1041;
        const uint SPIF_UPDATEINIFILE = 0x01;
        const uint SPIF_SENDWININICHANGE = 0x02;

        public Form1()
        {
            InitializeComponent();

            try
            {
                SystemParametersInfo(SPI_SETDISABLEOVERLAPPEDCONTENT, 0, true, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
            }
            catch(Exception e)
            {
                MessageBox.Show("IconShadowRemover: " + e.ToString());
            }

            Environment.Exit(0);
        }
    }
}

You have to import user32.dll and define SystemParametersInfo function. After that you can call it with specific parameter. It’s the console application so when you run it program will show CMD window. If you want to do this transparently you can always change application type to normal window application and hide form.

Put compiled application to “Start up” folder and get that effect:

visual_effects_4

instead of that:

visual_effects_3

Post author

There are 1 Comment

  1. Posted by Andreas Nahr Reply

    This is very helpful. I need to check the “Smooth-scroll list” checkbox programatically

    I’m a systems engineer, and programming is limited to powershell… so, do you know how to set
    SPI_SETUIEFFECTS
    SPI_GETLISTBOXSMOOTHSCROLLING = TRUE
    From https://msdn.microsoft.com/en-us/library/ms724947(v=vs.85).aspx about 3/4 the way down…

Leave a Reply