如何在Windows 7上移除Java程序的标题栏和任务栏图标?

33

我写了一个小应用程序,使用C#可以禁用Windows操作系统中所有窗口的标题栏和任务栏图标。以下是代码:

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

namespace IconKiller
{
    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 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, int wParam, IntPtr lParam);


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

        // Windows API standard values
        const int IMAGE_ICON = 1;
        const int LR_LOADFROMFILE = 0x10;
        const int WM_SETICON = 0x80;
        const int ICON_SMALL = 0;        

        static void Main(string[] args)
        {
            // Load the empty icon 
            string strIconFilePath = @"blank.ico";
            m_pIcon = LoadImage(IntPtr.Zero, strIconFilePath, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);

            // Setup the break condition for the loop
            int counter = 0;
            int max = 10 * 60 * 60;

            // Loop to catch new opened windows            
            while (counter < max)
            {
                // enumerate all desktop windows
                EnumDesktopWindows(IntPtr.Zero, new EnumDesktopWindowsDelegate(EnumDesktopWindowsCallback), IntPtr.Zero);
                counter++;
                System.Threading.Thread.Sleep(100);
            }

            // ... then restart application
            Application.Restart();
        }

        private static bool EnumDesktopWindowsCallback(IntPtr hWnd, int lParam)
        {
            // Replace window icon
            SendMessage(hWnd, WM_SETICON, ICON_SMALL, m_pIcon);

            return true;
        }
    }
}

这段代码似乎在本地Windows应用程序中运行良好。我唯一的问题是现在Java显然使用不同的应用程序图标实例来在任务栏中显示。这意味着我的小应用程序会删除Java程序标题栏中的图标,但不会删除任务栏中的图标(Netbeans是一个很好的例子)。

如何解决这个问题?或许可以通过JVM向这些程序传递消息,类似于我在Windows API中使用的技巧,在运行的Java应用程序上调用JFrame.setIconImage(),或者采取类似的方法?

编辑:我并不只局限于使用C#,如果必要的话,我也非常愿意编写像Java中的“辅助”应用程序,我会在主应用程序中执行它。


2
我很好奇...你为什么想要去掉那些提供视觉区分应用程序的图标? - Gus
你试过这个吗?https://dev59.com/YnVD5IYBdhLWcg3wNY1Z - Diego
@Diego 那会有什么帮助呢? - user743382
出现在任务栏上且不想更改图标的窗口具有窗口文本“theAwtToolkitWindow”。 - ecle
3个回答

1
问题在于使用EnumDesktopWindows而不是EnumWindows。以下代码在我的电脑上运行良好:
using System;
using System.Runtime.InteropServices;

namespace IconKiller
{
    class Program
    {
        /// Import the needed Windows-API functions:
        // ... for enumerating all running desktop windows
        [DllImport("user32.dll")]
        static extern bool EnumWindows(EnumDesktopWindowsDelegate lpfn, IntPtr lParam);
        private delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);

        // ... 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, int wParam, IntPtr lParam);


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

        // Windows API standard values
        const int IMAGE_ICON = 1;
        const int LR_LOADFROMFILE = 0x10;
        const int WM_SETICON = 0x80;
        const int ICON_SMALL = 0;

        static void Main(string[] args)
        {
            // Load the empty icon 
            string strIconFilePath = @"C:\clicknrun.ico";
            m_pIcon = LoadImage(IntPtr.Zero, strIconFilePath, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);

            // Setup the break condition for the loop
            int counter = 0;
            int max = 10 * 60 * 60;

            // Loop to catch new opened windows            
            while (counter < max)
            {
                // enumerate all desktop windows
                EnumWindows((EnumDesktopWindowsCallback), IntPtr.Zero);
                counter++;
                System.Threading.Thread.Sleep(100);
            }

            // ... then restart application
            Console.WriteLine("done");
            Console.ReadLine();
        }

        private static bool EnumDesktopWindowsCallback(IntPtr hWnd, int lParam)
        {
            // Replace window icon
            SendMessage(hWnd, WM_SETICON, ICON_SMALL, m_pIcon);

            return true;
        }
    }
}

当然,你需要进行一些小的编辑,以使代码合适,但你已经理解了其中的意思... - Chibueze Opata
枚举系统所有窗口会不会太慢了? - remio
@remio 在我的电脑上它运行得很快,而且这正是他想要的...除非你有一个更高效的解决方案。 - Chibueze Opata

0
这是您正在寻找的内容吗?:
[DllImport("user32.dll")]
        static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsDelegate lpfn, IntPtr lParam);
        private delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);

[DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder title, int size);
        [DllImport("user32.dll")]
        private static extern bool IsWindowVisible(IntPtr hWnd);

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

[DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

static IntPtr m_pIcon = IntPtr.Zero;

static string[] m_astrFilter = new string[] { "Start", "Program Manager" };

        static void Main(string[] args)
        {

        string strIconFilePath = @"H:\IconEmpty.ico";
        const int IMAGE_ICON = 1;
        const int LR_LOADFROMFILE = 0x10;
        m_pIcon = LoadImage(IntPtr.Zero, strIconFilePath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
        while (true) 
        { 
        EnumDesktopWindows(IntPtr.Zero, new EnumDesktopWindowsDelegate(EnumDesktopWindowsCallback), IntPtr.Zero);                       System.Threading.Thread.Sleep(100); 
        } 
                Console.ReadKey();
        }

private static bool EnumDesktopWindowsCallback(IntPtr hWnd, int lParam)
        {

        StringBuilder title = new StringBuilder(256);
            GetWindowText(hWnd, title, 256);
            string strTitle = title.ToString();
        bool bVisible = IsWindowVisible(hWnd);

if (bVisible && // ... visible
               !String.IsNullOrEmpty(strTitle) && // ... has title
               !m_astrFilter.Contains(strTitle)) // ... not in filter list
            {

        SendMessage(hWnd, 0x80, IntPtr.Zero, m_pIcon);
        }

            return true;
        }

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接