<<
 
>>
 
 
justin = {main feed , music , code , askjf , pubkey };
 
win32 menu bug
October 31, 2024
Microsoft generally does a very good job in preserving compatibility of existing applications; software written 20 years ago generally works well in Windows 11, amazingly. We noticed something they broke relating to menus that use bitmaps via MF_BITMAP, though, somewhere after Windows 7 -- I don't have 8.x installed anywhere to test, but Windows 10 and 11 are affected. Trying to figure out where to report these bugs online is difficult, and I'm lazy, so instead I'll document it here.

When setting a bitmap image for a menu item via MF_BITMAP, on Windows 10+, if the item does not have MF_CHECKED set, the bitmap will be drawn twice, and if the width of the menu is sufficiently longer than the width of the bitmap, one of those draws will be stretched. Here's some code that reproduces:
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR cmd, int ns)
{
	const int w = 32, h = 16;
	int pixels[w*h];
	for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) pixels[x + y * w] = RGB(x * 256 / w, y * 256 / h, 0);  // oops BGR but whatever
        HBITMAP bitmap = CreateBitmap(w, h, 1, 32, &pixels);
	HWND wnd = CreateWindowEx(0, "Edit", "test", WS_VISIBLE, 0, 0, 10, 10, GetDesktopWindow(), NULL, hInst, 0);
	HMENU menu = CreatePopupMenu();
	InsertMenuA(menu, 0, MF_BYPOSITION|MF_STRING, 1, (char*)"this is a thing that will cause stretching to happen");
	InsertMenuA(menu, 1, MF_BYPOSITION|MF_BITMAP, 2, (char*)bitmap);
	TrackPopupMenu(menu, TPM_NONOTIFY|TPM_RETURNCMD, 0, 0, 0, wnd, NULL);
	DestroyMenu(menu);
	DeleteObject(bitmap);
	DestroyWindow(wnd);
	return 0;
}
Windows XP, Windows 7, and WINE all display something about like this, which is expected: Windows 10 and 11 display this: As a workaround, you can call SetMenuItemBitmaps() for the item with hBitmapUnchecked to a small image, and it will prevent the bug from occurring (or at least prevent it from being obvious heh). It was a waste of time writing this blog post and writing the test case, but the things we do for fun, right?
Add comment:
Name:
Human?: (no or yes, patented anti crap stuff here)
Comment:
search : rss : recent comments : Copyright © 2024 Justin Frankel