【问题标题】:How to permanently change window icon at runtime?如何在运行时永久更改窗口图标?
【发布时间】:2017-07-17 12:51:32
【问题描述】:

我试图让我的应用程序的用户设置他们自己的自定义图标,但是通过 LoadImage 函数加载图标文件并通过 WM_SETICON 消息设置它似乎并不能解决问题。 Windows 资源管理器中的图标不会更新,每次运行程序时任务栏和左上角的图标都会重置(用户必须重新设置它们)。当我使用资源时,这些问题都没有发生,但是我在编译程序后无法更改 .rc 文件,是吗?我究竟做错了什么?我有一个菜单函数,它调用 GetOpenFileName 来获取图标文件,然后通过 LoadImage 加载它并通过 SendMessage 设置。

这是我的代码(我跳过了检查函数的返回值以缩短代码)

void DoFileIcon(HWND hwnd)
{
    OPENFILENAME ofn;
    char szFileName[MAX_PATH] = "";

    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = hwnd;
    ofn.lpstrFilter = "Icons (*.ico)\0*.ico\0All files (*.*)\0*.*\0";
    ofn.lpstrFile = szFileName;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    ofn.lpstrDefExt = "ico";

    if(GetOpenFileName(&ofn))
    {
        HICON hIcon, hIconSm;
        hIcon = LoadImage(NULL, szFileName, IMAGE_ICON, 32, 32, 
        LR_LOADFROMFILE);
        SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
        hIconSm = LoadImage(NULL, szFileName, IMAGE_ICON, 16, 16, 
        LR_LOADFROMFILE);
        SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
    }
}

【问题讨论】:

  • UpdateResource() 等人可以通过重写内部资源来做到这一点,创建应用程序的快捷方式并通过 IShellLink 修改它可能更明智:stackoverflow.com/questions/35665476/…
  • @AlexK。击败我的 IShellLink 建议。

标签: c++ winapi icons


【解决方案1】:

我认为 Windows 资源管理器中的图标是指 shell 与 .exe 文件关联的图标。这始终被确定为文件中的第一个图标资源。除非您准备好允许修改 .exe 文件,否则您将无法更改它。我强烈建议您不要在部署后修改 .exe 文件。这可能会导致损坏,并且会被反恶意软件视为可疑。

至于与您的主窗口关联的图标,这很简单。您已经知道如何改变它,发送WM_SETICON 消息。或者在注册窗口类时注册自定义图标。您的问题似乎只是您的程序在启动时不执行这些操作,而是仅在您调用DoFileIcon 时执行。系统不会为您记住自定义图标,您需要编写代码来做到这一点。将信息存储在注册表或应用程序配置文件中。然后在应用程序启动时,读取此配置,并应用自定义图标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多