c# - 如何在 Windows 7 上删除 Java 程序的标题栏和任务栏图标?

标签 c# java winforms winapi windows-7

我编写了一个小应用程序,它可以在 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;
        }
    }
}

此代码似乎适用于 native Windows 应用程序。我现在唯一的问题是,Java 显然使用其应用程序图标的不同实例来显示在任务栏中。这意味着我的小应用程序删除了 Java 程序标题栏中的图标,但没有删除任务栏中的图标(Netbeans 就是一个很好的例子)。

如何解决这个问题?是否可以通过 JVM 将消息传递给这些程序,类似于我在 windows API 中使用的技巧,在运行 Java 应用程序时调用 JFrame.setIconImage() 或类似的东西?

编辑:我不仅限于 C#,我非常愿意在 java 中编写类似“帮助”应用程序的东西,如果有必要,我会在我的主应用程序中执行。

最佳答案

问题在于使用 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;
        }
    }
}

关于c# - 如何在 Windows 7 上删除 Java 程序的标题栏和任务栏图标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8927416/

相关文章:

java - 来自 Controller 的 Spring Boot 查询

c# - 尝试将焦点更改按钮从选项卡更改为在 C# Windows 窗体中输入

c# - 获取 radioGroup 中选定的 RadioButton 的索引

java - 如何正确编写 C# 帮助程序类以从单行读取多个整数?

c# - 在类级别抑制UnmanagedCodeSecurity

c# - 无法使用 ".Add()"插入新的 Entity Framework 实体

Java GC 概念 : CMSInitiatingOccupancyFraction

Java XML 修改

c# - 如何在 C# Windows 窗体中设置 ComboBox 的选定项?

c# - Windows 证书存储