c++ - Windows/C++ -- 将图标渲染为具有透明度的位图
问题描述
我不是任何 GDI 方面的专家。但是几年前我收到了一些代码,这对我很有帮助。但是,它变老了……而且有了新的 windows10 深色主题,它显示出它的缺陷。
我正在渲染一个菜单(在资源管理器菜单插件中)。这是用于生成位图的代码片段。
我的目标是将此代码转换为生成保留图标透明度的位图。
(结果 HBITMAP 最终出现在 pItem->m_hBitmap )
HICON hIcon;
if ( (iIndex >= 0) && (ExtractIconEx(iconDLLPath, iIndex, NULL, &hIcon, 1) != 0) )
{
HDC hdc = CreateIC(L"DISPLAY", NULL, NULL, NULL);
HDC hdcMem = CreateCompatibleDC(hdc);
// XP demands 12x12, otherwise use 16x16
int cx = GetSystemMetrics((m_bUseSmallerIcons) ? SM_CXMENUCHECK : SM_CXSMICON);
int cy = GetSystemMetrics((m_bUseSmallerIcons) ? SM_CYMENUCHECK : SM_CYSMICON);
pItem->m_hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
HBITMAP hBmOld = (HBITMAP) SelectObject(hdcMem, pItem->m_hBitmap);
// DC: paint entire mem dc COLOR_MENU so icon looks transparent
// when painted into context menu having this background color
HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = cx;
rect.bottom = cy;
FillRect(hdcMem, &rect, hBrush);
DeleteObject(hBrush);
// Draw icon transparently, on top of the background color. Transparent
// areas will be the background color.
DrawIconEx(hdcMem, 0, 0, hIcon, cx, cy, 0, 0, DI_NORMAL);
// Cleanup
SelectObject(hdcMem, hBmOld);
DeleteDC(hdc);
DeleteDC(hdcMem);
DestroyIcon(hIcon);
}
我应该删除绘制白色背景的,但是如何放下透明背景?我尝试过的一切都会产生黑色背景。
* 只需移除白色“填充” * SetBkMode(TRANSPARENT) * 使用主题代码获取菜单颜色...
如何制作具有透明度的正确位图?
解决方案
最终,答案是我没有做错任何事。此菜单呈现为使用 IContextMenu 在 shell 插件中构建的菜单的一部分。
答案 - 实现 IContextMenu2。在这样做的过程中,做一个所有者绘制菜单项。
推荐阅读
- python - 如何在更新触发器之前使用 postgresql?这不执行只正确编译
- sql - 将列转换为单行并选择唯一条目
- python - list_directories_and_files 上缺少 Azure FileProperties 内容
- django - 如何在 Windows 机器上用 django 测试 celery
- spring - 何时使用基于 Spring Security 的场景
- angular - 使用 Typescript + Angular 填充日期输入
- c++ - C++终端句柄按键在屏幕上运行
- tensorflow - 如何使用张量流将 [1,2,3,4,5,6] 重塑为 [[1,3,5],[2,4,6]]?
- dart - Flutter:实现 peek & pop 效果
- json - 将结构编组和解组到 json 会丢失信息