我试图完成的目标非常简单:将图像添加到菜单项中。我正在使用win32 API编程C语言。图像/位图显示出来,但背景是白色的。我想要的是将白色背景变成透明的。
我已经阅读了所有可以找到的信息,包括stackoverflow,但信息似乎不一致。有人说位图不能具有任何形式的透明度,而另一些人则说可以。例如,可以查看以下问题: 在CMenu中以正确的透明度显示位图旁边的简单方法
我已经阅读了所有可以找到的信息,包括stackoverflow,但信息似乎不一致。有人说位图不能具有任何形式的透明度,而另一些人则说可以。例如,可以查看以下问题: 在CMenu中以正确的透明度显示位图旁边的简单方法
无论是SetMenuItemBitmaps()
还是SetMenuItemInfo()
都会给出白色背景。上面的链接说,如果位图是32bpp带有预乘alpha,则应该正确显示。所以要么这种方式根本不可能,要么我使用的bmp格式不正确。有人能给出这个问题的明确答案吗?如果使用SetMenuItemInfo()
无法解决,那么最简单的解决方法是什么?我尝试避免所有者绘制解决方案,因为我觉得这有点过度杀伤力。此外,据我所知,所有者绘制解决方案很难尊重Windows主题。
menubitmap.rc:
#include "menubitmap.h"
ID_ICON ICON DISCARDABLE "menu1.ico"
ID_BITMAP_EXIT BITMAP DISCARDABLE "Exit-icn.bmp"
ID_MENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
END
menubitmap.c:
#include <windows.h>
#include "menubitmap.h"
const char g_szClassName[] = "myWindowClass";
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_CREATE:
{
HBITMAP btmp;
MENUITEMINFOA miinfo;
HMENU menu;
btmp=LoadBitmap((HINSTANCE) GetModuleHandle (NULL), MAKEINTRESOURCE(ID_BITMAP_EXIT));
menu=GetMenu(hwnd);
miinfo.cbSize=sizeof(MENUITEMINFO);
if(!GetMenuItemInfo(menu,ID_FILE_EXIT,FALSE,&miinfo)){
printf("getmenuiteminfo failed\r\n");
}else{
miinfo.fMask |= MIIM_BITMAP;
miinfo.hbmpItem=btmp;
if(SetMenuItemInfo(menu,ID_FILE_EXIT,FALSE,&miinfo)){
printf("setmenuiteminfo");
}
}
}
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = MAKEINTRESOURCE(ID_MENU);
wc.lpszClassName = g_szClassName;
wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON), IMAGE_ICON, 16, 16, 0);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"A Menu",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
在这里你可以找到位图。
以下是以base64格式编码的位图:
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
AA==
ID_BITMAP_EXIT BITMAP DISCARDABLE "Exit-icn.bmp"
,并使用btmp=LoadBitmap((HINSTANCE) GetModuleHandle (NULL), MAKEINTRESOURCE(ID_BITMAP_EXIT));
进行加载。因此,资源中的透明度丢失了吗? - robLoadBitmap
可在需求部分指定的操作系统中使用。 它可能会在以后的版本中被更改或不可用。 相反,请使用LoadImage
和DrawFrameControl
。您可以上传您的32bpp位图进行测试。如果您能够提供“最小可复现示例”,我将不胜感激。 - Strive SunLoadImage()
没有任何区别。我尝试了不同的程序来制作bmp。结果要么是白色背景,要么是黑色背景。使用资源编辑器检查可执行文件时,位图是透明的。根据前两个评论,它应该正确显示。我如何向您发送MRE? - rob