【问题标题】:How to change app icon in taskmanager如何在任务管理器中更改应用程序图标
【发布时间】:2013-10-29 10:18:01
【问题描述】:

我有一些windows应用程序可以改变他的图标,使用win api函数

SendMessage(hwnd, WM_SETICON, ICON_BIG, icon_handle);
SendMessage(hwnd, WM_SETICON, ICON_SMALL, icon_handle);

Shell_NotifyIcon(...);

它改变了任务栏和托盘(任务栏通知区域)中的图标,但 taskmanager 中的图标仍然没有改变。 如何更改任务管理器中的图标?有可能吗?

【问题讨论】:

    标签: c++ windows winapi icons taskmanager


    【解决方案1】:

    来自this SO answer

    更改所有图标很重要,包括应用程序,无论大小:

    //Change both icons to the same icon handle.
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, hIcon);
    SendMessage(hwnd, WM_SETICON, ICON_BIG, hIcon);
    
    //This will ensure that the application icon gets changed too.
    SendMessage(GetWindow(hwnd, GW_OWNER), WM_SETICON, ICON_SMALL, hIcon);
    SendMessage(GetWindow(hwnd, GW_OWNER), WM_SETICON, ICON_BIG, hIcon);
    

    编辑

    根据this SO answer,图标需要是图标编辑器创建的.ICO文件; this SO article 还提到您需要将消息发送到应用程序的最顶部窗口。

    我可以通过
    切换任务栏、alt-tab和任务管理器中的图标 a) 使用 Visual Studio 资源编辑器创建图标
    b) 使用 HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
    之类的代码加载图标 c) 将WM_SETICON, ICON_SMALL 发送到最顶层窗口——我使用的是 MFC SDI 应用程序,所以我将消息发送到主框架窗口 (AfxGetApp()->m_pMainWnd)

    注意:MSDN Docs for WM_SETICON 中的评论提及

    系统不会复制图标。销毁窗口前不要销毁图标

    【讨论】:

    • 我更改了两个图标。我已经更新了问题。 SendMessage(hwnd...) 和 SendMessage(GetWindow(hwnd, GW_OWNER)...) 有什么区别?我添加了这两个功能,它仍然没有改变任务管理器中的图标。
    • GW_OWNER 是当有another window that owns this window 时,它可能不适用于您的情况。我已经用更多细节编辑了我的答案
    【解决方案2】:

    这是一个常见的 Windows 错误。任务管理器和资源管理器会在很长一段时间内记住与文件关联的图标。如果您的图标在 exe 中的 ID 最低,它应该在任务管理器(根节点)中显示为应用程序图标。但是,如果您最近更改了它,它可能无法正常工作。窗口本身的图标是完全不同的 - 如果它没有显示,你的代码是错误的。

    【讨论】:

      【解决方案3】:
      BOOL sendWndIconToTaskbar(HWND hWnd,HICON hIcon) 
      { 
          BOOL ret = TRUE; 
          ASSERT(hWnd); 
          if(!::IsWindow(hWnd)) 
              return FALSE; 
          CWnd* pWnd; 
          pWnd = pWnd->FromHandle(hWnd); 
          ASSERT(pWnd); 
          if(!pWnd) 
              return FALSE; 
          if(pWnd->GetParent())
          {
              if(::SetWindowLong(hWnd,GWL_HWNDPARENT,NULL) == 0) 
                  return FALSE; 
          }
      
      
          if(!(pWnd->ModifyStyle(NULL,WS_OVERLAPPEDWINDOW))) 
              ret = FALSE; 
          pWnd->SetIcon(hIcon,TRUE); 
          pWnd->SetIcon(hIcon,FALSE); 
      
          return ret; 
      } 
      
      HICON hIconSm = (HICON)LoadImage(NULL, "default.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
      sendWndIconToTaskbar(pOcxDlg->m_hWnd,hIconSm);
      

      【讨论】:

        猜你喜欢
        • 2016-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-12
        • 2013-08-12
        • 1970-01-01
        • 2018-08-06
        • 1970-01-01
        相关资源
        最近更新 更多