Click here to Skip to main content
15,896,201 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi,

I'm a fairly competent java developer, but have next no knowledge about c#.

For my own personal use, I'd like to code an app that disables the icon on the upper left of the window titlebars and in the taskbar of ms windows (only works in java with needless detours). This is how it should look when it's done: TBarIconBlanker (this little autohotkey script is broken in win 7)

EDIT: Appearently my question is a little ambiguous. I want to disable the icons on the titlebars of all visible windows of the os. I want all icons of the taskbar gone (exept the system tray area). That's why I use PInvoke to enumerate all visible windows to send a message to them to replace their icon by a blank one.

This is what I got so far from various code sniplets I found on the interwebs:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace IconKiller
{
    class IconKiller
    {
        /// <summary>
        /// filter function
        /// </summary>
        public delegate bool EnumDelegate(IntPtr hWnd, int lParam);

        /// <summary>
        /// check if windows visible
        /// </summary>>
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsWindowVisible(IntPtr hWnd);

        /// <summary>
        /// return windows text
        /// </summary>
        [DllImport("user32.dll", EntryPoint = "GetWindowText",
        ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

        /// <summary>
        /// enumarator on all desktop windows
        /// </summary>
        [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows",
        ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

        /// <summary>
        /// Load icon
        /// </summary>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr LoadImage(IntPtr hInst, string lpsz, IntPtr uType, IntPtr cxDesired, IntPtr cyDesired, IntPtr fuLoad);

        /// <summary>
        /// send message to windows
        /// </summary>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

        /// <summary>
        /// entry point of the program
        /// </summary>

        private const string FILE = "blank.ico";
        private const UInt32 WM_SETICON = 0x80;
        private const int IMAGE_ICON = 1;
        private const int LR_DEFAULTSIZE = 0x40;
        private const int ICON_SMALL = 0;
       
        static void Main(string[] args)
        {
            // Load external icon file
            IntPtr icon = LoadImage(new IntPtr(0), FILE, new IntPtr(IMAGE_ICON), new IntPtr(0), new IntPtr(0), new IntPtr(LR_DEFAULTSIZE));

            // Enumerate all windows
            EnumDelegate filter = delegate(IntPtr hWnd, int lParam)
            {
                // Get the windows title
                StringBuilder strbTitle = new StringBuilder(255);
                int nLength = GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
                string strTitle = strbTitle.ToString();

                // Choose all active windows with a title
                if (IsWindowVisible(hWnd) && string.IsNullOrEmpty(strTitle) == false && strTitle != "Start" && strTitle != "Program Manager")
                {
                    // Output the windows title and send a message to replace the icon
                    Console.WriteLine(strTitle);
                    SendMessage(hWnd, WM_SETICON, new IntPtr(ICON_SMALL), icon);
                }
                return true;
            };

            Console.Read();
        }
    }
}


Getting the strings from the multiple titlebars works (I did that to see which windows are getting messages sent to), but the icons stay the same. Maybe someone with a little bit more C# and WinAPI know-how could help me out? Thank you in advance.

ISOmorph
Posted
Updated 11-Jan-12 22:32pm
v2
Comments
johannesnestler 11-Jan-12 10:20am    
wow - no need for any PInvoke - look at OriginalGriffs solution (ShowIcon, ShowInTaskbar). I just want to give you a hint to other related Form properties: MinimizeBox, MaximizeBox, ControlBox, FormBorderStyle, WindowState - all you need.

Hi TheISOmorph,

Sorry for missreading your question. I can offer you a half solultion (code only replaces application icons, not taskbar...) So you were on the right way with PInvoke, .NET just doesn't give you the tools to replace the application icons - good old windows API helps. Here we go: (simple .NET 4 Console Application)


C#
using System;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace RemoveAllApplicationIcons
{
    class Program
    {
        // Import the needed Windows-API functions:

        // ... for enumerating all running desktop windows
        [DllImport("user32.dll")]
        static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsDelegate lpfn, IntPtr lParam);
        private delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);

        // ... for getting window informations only from a handle
        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder title, int size);
        [DllImport("user32.dll")]
        private static extern bool IsWindowVisible(IntPtr hWnd);

        // ... for loading an icon
        [DllImport("user32.dll")]
        static extern IntPtr LoadImage(IntPtr hInst, string lpsz, uint uType, int cxDesired, int cyDesired, uint fuLoad);

        // ... for sending messages to other windows
        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        // Setup some "global" variables

        /// Pointer to an empty icon used to replace all other application icons.
        static IntPtr m_pIcon = IntPtr.Zero;

        // List of filter window-titles
        static string[] m_astrFilter = new string[] { "Start", "Program Manager" };

        static void Main(string[] args)
        {
            // Load the empty icon (from a file in this example)
            string strIconFilePath = @"H:\IconEmpty.ico"; // Replace with a valid path on your system!
            const int IMAGE_ICON = 1;
            const int LR_LOADFROMFILE = 0x10;
            // edit: IntPtr pIcon = LoadImage(IntPtr.Zero, strIconFilePath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
            m_pIcon = LoadImage(IntPtr.Zero, strIconFilePath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);

            // enumerate all desktop windows
            EnumDesktopWindows(IntPtr.Zero, new EnumDesktopWindowsDelegate(EnumDesktopWindowsCallback), IntPtr.Zero);

            Console.ReadKey();
        }

        private static bool EnumDesktopWindowsCallback(IntPtr hWnd, int lParam)
        {
            // Get window title
            StringBuilder title = new StringBuilder(256);
            GetWindowText(hWnd, title, 256);
            string strTitle = title.ToString();

            // Get window visibillity
            bool bVisible = IsWindowVisible(hWnd);

            // window meets all criteria?
            if (bVisible && // ... visible
               !String.IsNullOrEmpty(strTitle) && // ... has title
               !m_astrFilter.Contains(strTitle)) // ... not in filter list
            {
                // replace icon now
                SendMessage(hWnd, 0x80, IntPtr.Zero, m_pIcon);

                // Console.WriteLine(title); // for debugging only
            }

            return true;
        }
    }
}


I hope you can extend it and also manage to remove the taskbar icons - let me know!

best regards
 
Share this answer
 
v4
Comments
TheISOmorph 16-Jan-12 5:10am    
Hi Johannes,

Sorry for the late reply, I didn't have the chance to try this out until just now. Thank you for this solution.
I hope this isn't a problem on my end, but this code isn't working for me either. I get all the windows I want to send a message to (titles appear in the output) and the screen flashes when I execute the compiled exe, but all the icons remain unchanged (I changed the .ico path and uncommented the console output).
Did you test this on a win 7 system?

EDIT: Just tried this out on my colleagues PC, and it didn't work eiter (both our machines run win 7 x64)

Best regards,
ISOmorph
johannesnestler 16-Jan-12 7:32am    
so I found it - it wasn't the environment but a simple bug when I copied the code (sorry for that). - I updated the solution (didn't load the file correctly). Now it should work.
TheISOmorph 16-Jan-12 8:15am    
Amazing! It's finally working. Even the taskbar icons are gone.
All that is left for me to do is to find a way to check for new window opening events to re-execute the method. Vielen Dank Johannes.
johannesnestler 16-Jan-12 8:26am    
I'm glad it works now. Sorry for the bug...
johannesnestler 16-Jan-12 8:30am    
I'm not shure about window opening events... - maybe this helps: http://stackoverflow.com/questions/848618/net-events-for-process-executable-start
In C#, it is pretty simple - just put two lines in your form constructor:
C#
ShowIcon = false;
ShowInTaskbar = false;
 
Share this answer
 
Comments
fjdiewornncalwe 11-Jan-12 11:18am    
That almost looks like an Easy button. +5.
TheISOmorph 12-Jan-12 4:25am    
I'm sorry but this isn't what I am looking for.
Maybe I just didn't present the problem clearly enough. I want to disable the titlebar and taskbar icons systemwide, not only for my app.
I'm well aware that this task is trivial for my own application. That's why I posted a link to an app that does what I want, sadly it doesn't work on win 7 anymore.

Thank you very much for your response though.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900