我正在寻找正常的方式(即微软在创建其API时考虑的方式)来加载纯C程序中命令的标准图标,例如用于保存的软盘映像等
互联网上似乎没有答案。我知道 commctl32 的工具栏可以接收
TB_LOADIMAGES
消息,该消息用标准图标填充图像列表,但如果我的应用程序中不需要工具栏怎么办?我想要另一个控件中的图标,比如说所有者绘制按钮或菜单项。有没有一种方法可以填充图像列表而不创建无用的工具栏?或者更好的是,获取 HICON
或 HBITMAP
句柄以避免 commctl32 依赖?
微软的文档和网络上对此保持沉默,让我认为不存在这样的功能。也许当使用 Microsoft 工具开发应用程序时,应用程序创建者会将开发人员在预定义列表中选择的默认图标作为资源注入可执行文件中?我无法检查它,因为我只使用类 Unix 编译器,有人可以确认这一点和/或告诉我有关 Windows 下默认图标使用情况的更多信息吗?
此外,假设我们可以加载像
shell32.dll
这样的库来使用其嵌入的图标(就像 kernel32.dll
、`user32.dll,...中永远可用的所有好旧功能一样)是否可靠?我的意思是,是否可以保证库中的图标在未来版本的 Windows 中保留其语义和索引?
几天后发布我选择的最终解决方案,以防万一有人需要使用相同的解决方案。显示命令图标的最常见方法是将它们嵌入到应用程序中,因此尽管对虚拟控件的创建不满意,我还是使用临时工具栏来加载全局图像列表中的图标。这不太可能失败,但由于图标有时可能是唯一向用户指示小部件功能的东西,因此我通过在出现问题时运行回退代码的能力来强化条件。
加载图标的函数被命名为
WIN32_initIcons()
,因为它应该与类 Unix 平台的 GTK_initIcons()
或 X11_initIcons()
对应函数一起实现。
HIMAGELIST WIN32_imglst16 = NULL;
HIMAGELIST WIN32_imglst24 = NULL;
bool WIN32_initIcons(void) {
bool def16 = false;
bool def32 = false;
HWND hWnd;
WIN32_imglst16 = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 80, 16);
WIN32_imglst32 = ImageList_Create(24, 24, ILC_COLOR32 | ILC_MASK, 80, 16);
if (hWnd = CreateWindowA("ToolbarWindow32", NULL, TBSTYLE_LIST, 0, 0, 0, 0, NULL, (HMENU)0, GetModuleHandle(NULL), NULL)) {
if (WIN32_imglst16) {
SendMessage(hWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)WIN32_imglst16);
if (!SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL)) def16 = true;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 15) def16 = false;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 27) def16 = false;
if (ImageList_GetImageCount(WIN32_imglst16) != 32) def16 = false;
}
if (WIN32_imglst24) {
SendMessage(hWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)WIN32_imglst24);
if (!SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_STD_LARGE_COLOR, (LPARAM)HINST_COMMCTRL)) def24 = true;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_VIEW_LARGE_COLOR, (LPARAM)HINST_COMMCTRL) != 15) def24 = false;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_HIST_LARGE_COLOR, (LPARAM)HINST_COMMCTRL) != 27) def24 = false;
if (ImageList_GetImageCount(WIN32_imglst24) != 32) def24 = false;
}
DestroyWindow(hWnd);
}
if (WIN32_imglst16 && !def16) {
// Load your custom 16x16 fallback icons in the list "WIN32_imglst16" here
// Don't forget to set "def16 = true" on success
}
if (WIN32_imglst24 && !def24) {
// Load your custom 24x24 fallback icons in the list "WIN32_imglst24" here
// Don't forget to set "def24 = true" on success
}
if (!def16) {
// Trigger your error management here because 16x16 icons cannot be loaded
// Maybe, call "ImageList_Destroy(WIN32_imglst16)" and set "WIN32_imglst16 = NULL"
}
if (!def24) {
// Trigger your error management here because 24x24 icons cannot be loaded
// Maybe, call "ImageList_Destroy(WIN32_imglst24)" and set "WIN32_imglst24 = NULL"
}
return (def16 && def24);
}
注意:在简单 C 中,使用
<stdbool.h>
来定义 bool
值。