【问题标题】:Win32 Toolbar Custom and Default icons on same barWin32 工具栏自定义和默认图标在同一个栏上
【发布时间】:2014-10-13 23:02:07
【问题描述】:

我意识到 win32 工具栏图标问题在这里很常见,但没有一个与我的特定问题相关(最关心的图像列表,或与位图句柄相关联)。

我正在尝试将工具栏按钮与我的应用程序中的图标资源相关联。由于我使用 TB_ADDBITMAP(新建、打开、保存等)将其添加到已经具有默认图像的工具栏中,因此我无法使用图像列表,正如 MSDN 上的文章所说:

TB_SETIMAGELIST 消息不能与 TB_ADDBITMAP 组合。它也不能与使用 CreateToolbarEx 创建的工具栏一起使用,后者在内部调用 TB_ADDBITMAP。当您使用 CreateToolbarEx 创建工具栏或使用 TB_ADDBITMAP 添加图像时,工具栏在内部管理图像列表。尝试使用 TB_SETIMAGELIST 对其进行修改会产生不可预知的后果。

MSDN 说我应该能够直接使用 TB_ADDBITMAP 的资源,在 TBADDBITMAP::nID 字段下:

如果 hInst 为 NULL,则将此成员设置为带有按钮图像的位图的位图句柄。 否则,将其设置为带有按钮图像的位图的资源标识符

VS2008 资源编辑器显示单个 16x16 图标资源,ID 为 IDI_ARROWLEFT。 (我有一个截图,但由于我没有足够的“声誉”来发布图片,所以你必须相信我的话)

这显然是一个有效的图标,因为下面的代码使图标出现在主窗口的标题栏上:

wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ARROWLEFT));

问题是资源图标没有出现在窗口内的工具栏按钮上。下面是加载资源并将其应用到工具栏按钮的示例代码:

void populateToolbarTest()
{   
    int index = -1;

    TBADDBITMAP tbab;
    TBBUTTON tbb;

    ZeroMemory(&tbab, sizeof(TBADDBITMAP));
    ZeroMemory(&tbb, sizeof(TBBUTTON));

    SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);

    tbab.hInst = hInst;
    tbab.nID = IDI_ARROWLEFT;

    // SendMessage returns 0 when testing
    index = SendMessage(hWndToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbab);
    if (index == -1) return;

    tbb.iBitmap = index;
    tbb.fsState = TBSTATE_ENABLED;
    tbb.fsStyle = TBSTYLE_BUTTON;

    // result is set to 1 when testing
    LRESULT result = SendMessage(hWndToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbb);
}

此代码成功生成了一个按钮。但是,与我在 IDB_STD_SMALL_COLOR 中使用的默认值不同,没有显示图标

【问题讨论】:

  • wcex.hInstancehInst 指的是同一个模块吗?您是否尝试将wcex.hInstance 分配给tbab.hInst?另外,IDI_ARROWLEFT 是指BITMAP 资源还是ICON 资源? LoadIcon() 暗示后者,但TB_ADDBITMAP 需要前者。
  • 是的,wcex.hInstance 与 hInst 相同。它们都是应用程序实例。 IDI_ARROWLEFT 是 ICON 资源,而不是 BITMAP。但是,我也尝试过使用 PNG BITMAP 资源 IDB_ARROWLEFT 获得相同的结果。
  • PNG 和 BITMAP 不是一回事。
  • 我只是在想这个。我将尝试将图像转换为 MS BMP 格式,看看是否会更好。
  • 我尝试将其导入为 24 位 BMP 文件。仍然没有出现。

标签: winapi icons toolbar embedded-resource


【解决方案1】:

我终于让它工作了。原来,它与代码无关。

Microsoft 对所引用图像的确切格式极为挑剔。如果您将 TB_ADDBITMAP 与自定义图像一起使用,它必须是 256 色,它必须具有特定于 MS 的索引格式,并且我注册为透明的唯一颜色是黑色。在弄清楚这一点之前,我花了一个小时在 Photoshop 中处理不同的格式和颜色。

线索是 MSDN 上示例中的 CreateMappedBitmap 函数。 CreateMappedBitmap 上的页面有这样的声明:

此功能仅对带有彩色图的图像完全支持;也就是说,具有 256 种或更少颜色的图像。

它没有提到的是,不管你是否使用这个功能,这都是真的。我已经尝试了使用和不使用此辅助函数的每个场景,并尝试了所有其他 256 色 BMP 索引格式。其他一些格式也出现了,但它们被破坏了。

理论上,您可以使用 CreateMappedBitmap COLORMAP 指定黑色以外的透明颜色,但我对“6 级 RGB”格式不够熟悉,不知道如何指定确切的颜色。

(参考:http://en.wikipedia.org/wiki/List_of_software_palettes#6_level_RGB

除非您将自定义图标与默认图标混合使用,否则我建议您坚持使用 TB_SETIMAGELIST。根据我的阅读,它更加灵活(例如,它接受超过 256 种颜色。)

(参考:Win32 Toolbars and 24bit Images

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多