【问题标题】:How can I remove titlebar and taskbar icons of Java programs on Windows 7?如何在 Windows 7 上删除 Java 程序的标题栏和任务栏图标?
【发布时间】:2012-02-14 04:37:09
【问题描述】:

我编写了一个小应用程序,它可以在 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 中编写类似“帮助”应用程序的东西,如果有必要,我会在我的主应用程序中执行。

【问题讨论】:

  • 我很好奇...你为什么要去掉那些提供简单视觉区分应用程序的方法的图标
  • @Diego 那会有什么帮助?
  • 任务栏上出现的不想换图标的窗口有窗口文字theAwtToolkitWindow

标签: c# java winforms winapi windows-7


【解决方案1】:

这是你要找的吗?:

[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;
        }

【讨论】:

    【解决方案2】:

    您可以使用Windows API Code Pack 覆盖任务栏图标。 Here are some examples。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 当然,您需要进行一些小的修改以使代码正确,但您明白了...
      • 枚举系统所有窗口是不是太慢了?
      • @remio 它在我的电脑上运行得非常快,这就是他想要做的......除非你有更有效的解决方案。
      猜你喜欢
      • 1970-01-01
      • 2011-04-29
      • 2012-02-29
      • 1970-01-01
      • 2011-02-12
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      相关资源
      最近更新 更多