1

I have a C++ win32 program, and I'd like to edit the taskbar icon at runtime to display alerts, etc about the program, however I'm not too experienced with the win32 api, and I haven't been able to find anything online. The closest I've found is http://www.windows-tech.info/17/52a5bfc45dac0ade.php which tells how to load the icon off the disc at runtime and change it.

I would like to do what they do in this question: Create an icon in memory with win32 in python but in C++ and without an external library.

4

1 回答 1

7

我想做他们在这个问题中所做的事情:在 python 中使用 win32但在 C++ 中且没有外部库的情况下在内存中创建一个图标

由于接受的答案使用 wxWidgets 库,它只是 Win32 API 的包装器,因此该解决方案的翻译非常好。

您需要做的就是使用该CreateCompatibleBitmap函数在内存中创建一个位图。然后,您可以使用标准 GDI 绘图函数在该位图中绘图。CreateIconIndirect最后,您使用该函数创建图标。

最困难的部分是跟踪您的资源并确保在完成后释放它们以防止内存泄漏。如果它全部包含在一个使用 RAII 以确保正确释放对象的库中,那就更好了,但是如果你用 C++ 编写 C 代码,它看起来像这样:

HICON CreateSolidColorIcon(COLORREF iconColor, int width, int height)
{
    // Obtain a handle to the screen device context.
    HDC hdcScreen = GetDC(NULL);

    // Create a memory device context, which we will draw into.
    HDC hdcMem = CreateCompatibleDC(hdcScreen);

    // Create the bitmap, and select it into the device context for drawing.
    HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, width, height);    
    HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmp);

    // Draw your icon.
    // 
    // For this simple example, we're just drawing a solid color rectangle
    // in the specified color with the specified dimensions.
    HPEN hpen        = CreatePen(PS_SOLID, 1, iconColor);
    HPEN hpenOld     = (HPEN)SelectObject(hdcMem, hpen);
    HBRUSH hbrush    = CreateSolidBrush(iconColor);
    HBRUSH hbrushOld = (HBRUSH)SelectObject(hdcMem, hbrush);
    Rectangle(hdcMem, 0, 0, width, height);
    SelectObject(hdcMem, hbrushOld);
    SelectObject(hdcMem, hpenOld);
    DeleteObject(hbrush);
    DeleteObject(hpen);

    // Create an icon from the bitmap.
    // 
    // Icons require masks to indicate transparent and opaque areas. Since this
    // simple example has no transparent areas, we use a fully opaque mask.
    HBITMAP hbmpMask = CreateCompatibleBitmap(hdcScreen, width, height);
    ICONINFO ii;
    ii.fIcon = TRUE;
    ii.hbmMask = hbmpMask;
    ii.hbmColor = hbmp;
    HICON hIcon = CreateIconIndirect(&ii);
    DeleteObject(hbmpMask);

    // Clean-up.
    SelectObject(hdcMem, hbmpOld);
    DeleteObject(hbmp);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdcScreen);

    // Return the icon.
    return hIcon;
}

添加错误检查和代码以在位图上绘制一些有趣的东西留给读者作为练习。

正如我在上面的评论中所说,创建图标后,您可以通过向窗口发送WM_SETICON消息并将其传递HICONLPARAM

SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);

你也可以指定ICON_SMALL为了设置窗口的小图标。如果您只设置一个大图标,它会按比例缩小以自动创建小图标。但是,如果只设置小图标,窗口将继续使用默认图标作为其大图标。大图标的尺寸通常为 32x32,而小图标的尺寸通常为 16x16。但是,这并不能保证,因此不要对这些值进行硬编码。如果需要确定它们,调用GetSystemMetrics函数 with获取大图标的宽度和高度,或者SM_CXICON获取小图标的宽度和高度。SM_CYICONSM_CXSMICONSM_CYSMICON

此处提供了有关使用 GDI 在 Windows 中绘图的相当好的教程。如果这是您第一次这样做并且之前没有使用 GDI 的经验,我建议您仔细阅读它。

于 2013-05-10T00:09:15.433 回答