【问题标题】:Problems with setting application icon设置应用程序图标的问题
【发布时间】:2010-10-16 22:55:05
【问题描述】:

(我使用的是 Visual Studio 2008,但我记得旧版本也有类似的问题。)

我尝试了几种不同的方法(其中许多在this other question 中提到),但我仍然遇到一些奇怪的问题:

  1. 当包含一个图标作为资源时,它会立即显示为可执行文件的图标,但要让图标显示在任务栏上,我必须重新启动计算机。在那之前,它会继续显示为之前的图标。清理解决方案,重新启动 VS,没有任何效果。不是一个真正的大问题,因为它不会影响已发布的 exe,但很高兴知道它将旧图标缓存在哪里以及如何摆脱它。

  2. 无论我做什么,alt-tabbing 时显示的图标都是默认的应用程序图标(方形和白色和通用)。这包括在可执行文件中嵌入图标,以及将ICON_BIG 设置为WM_SETICON

至于第二个问题,我的代码是这样的:

   hIcon = (HICON)(
      LoadImage( NULL, szFilename, IMAGE_ICON, 32, 32, LR_LOADFROMFILE ) );
   if( hIcon )
      SendMessage( hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon );

但是,发送WM_SETICONGetLastError() 后返回6,“句柄无效。”。 hWnd 是一个有效的窗口句柄,hIcon 似乎是一个有效的图标句柄。我已经尝试寻找WM_SETICON 可能导致该错误的原因,并且至少要弄清楚它认为哪个句柄无效,但还没有运气。我在调用SendMessage() 之前立即清除了错误代码,因此必须在消息处理过程中设置它。

我尝试了另一种方法,从 exe 本身加载图标,其中资源的 ID 是 101(它是第一个也是唯一包含的资源):

   hIcon = (HICON)(
      LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( 101 ),
      IMAGE_ICON, 48, 48, 0 ) );
   if( hIcon )
      SendMessage( hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon );

...但同样的事情也会发生;调用SendMessage() 后,GetLastError() 给出相同的错误状态。

我尝试了不同的尺寸(例如 48x48,所有这些都存在于图标文件中),但没有不同的效果。我知道它肯定会查找和加载图像,因为如果我指定不存在的大小或无效的资源 ID 或错误的文件名(取决于我加载它的方式),它会在 SendMessage() 之前很久就失败了。

奇怪的是,如果我指定ICON_SMALL 而不是ICON_BIG,则调用成功且没有错误状态,但是从the docs 开始,我需要使用ICON_BIG 来设置alt-tabbing 时使用的图标。此外,如果我使用 ICON_BIG 但加载 16x16 图标,我不会收到错误状态,但没有任何变化。

关于可能导致WM_SETICON 失败的任何想法?我发布的任何代码有什么严重错误(除了格式/样式/转换问题,因为它被简化为基础知识)?

【问题讨论】:

    标签: c++ visual-studio-2008 icons


    【解决方案1】:

    我已使用具有多种分辨率 16x16、32x32、48x48、96x96 的单个 .ico 文件作为应用程序图标,没有任何问题。然后窗口会选择正确的大小。

    windows shell 有一个icon cache,有一个trick 可以重新启动它,而无需重新启动或从当前会话中注销,或者从任务管理器中杀死 explorer.exe。

    【讨论】:

      【解决方案2】:

      我重新审视了这个,看看我是否可以结束我的问题。仅通过将应用程序的图标嵌入到可执行文件中,我无法让应用程序的图标显示在 alt-tab 列表中;它会显示在任务栏中,作为资源管理器中的文件图标,在其他地方就可以了。

      我想我会尝试一些更简单的手动设置图标,并改用LoadIcon(),如下面的代码所示:

      HICON hIcon = LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1) );
      if( hIcon )
      {
         SendMessage( GetHandle(), WM_SETICON, ICON_BIG, (LPARAM)hIcon );
         DestroyIcon( hIcon );
      }
      // ... Same for ICON_SMALL
      

      这似乎成功了。我真的不知道为什么,但到目前为止,这是唯一有效的变化。这真的不是我应该花更多时间解决的问题,所以我会继续这样做。

      【讨论】:

      • 我今天遇到了同样的问题。不幸的是,这对我不起作用。我必须在互联网上搜索其他解决方案。
      • LoadImage 方法对我来说很好,可以在alt + Tab 菜单中显示图标我遇到了我没有将BIG_ICONLoadImage 设置为的问题32x32,一旦我这样做了,它就像一个魅力。见:stackoverflow.com/a/24029664/1828637
      【解决方案3】:

      如果找到适合我的解决方案。我创建了一个不可见的 CFrameWnd 应用程序窗口,然后创建了几个其他主窗口(它们是对话框窗口)。神奇的无证规则是:您必须更改第一个创建的 CFrameWnd 中的大图标。虽然每个窗口都有自己的 ICON_BIG 实例,但它不使用它们。所以似乎不可能在一个应用程序中为不同的窗口显示不同的任务栏图标。

      【讨论】:

        【解决方案4】:

        好的,这对我来说是一种享受:

        HICON hIconSmall =(HICON)LoadImage(handleToYourApplicationInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,16, 16, 0);
        
        HICON hIconLarge =(HICON)LoadImage(handleToYourApplicationInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,256, 256, 0); // Big for task bar, small loaded otherwise.
        
        SendMessage(yourWindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall) ;
        
        SendMessage(yourWindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIconLarge) ;
        

        【讨论】:

          【解决方案5】:

          对于遇到同样困难的任何人,如果您要更改 ICON_BIG,您必须先发送带有 ICON_SMALL 的 WM_SETICON,然后再进行 ICON_BIG。

          例如:

          SetLastError(0);
          SendMessage(windowHandle, WM_SETICON, ICON_SMALL, (LPARAM)iconsmallHandle);
          [do error handling]
          SetLastError(0);
          SendMessage(windowHandle, WM_SETICON, ICON_BIG, (LPARAM)iconbigHandle);
          [do error handling]
          

          您需要在第一个 SendMessage 之后使用 SetLastError 来清除任何返回的错误。

          如果您只是设置 ICON_SMALL,则可以忽略 ICON_BIG。无论出于何种原因,在我的所有测试中,无论该图标是否需要更改,您都必须在尝试更改 ICON_BIG 之前设置 ICON_SMALL,否则您将始终收到错误代码 0x6(无效句柄)。

          【讨论】:

          • 非常感谢这个提示!这修复了错误“句柄无效”。为了大图标!
          猜你喜欢
          • 2018-03-18
          • 1970-01-01
          • 2022-07-28
          • 2019-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-01
          • 2011-07-18
          相关资源
          最近更新 更多