<<
 
>>
 
 
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?
3 Comments:

Posted by Tale on Fri 01 Nov 2024 at 03:11 from 77.170.68.x

I also forgot exactly where, but a few years back I found a bug with i386 exp() in MSVC, and I did manage to report it (for fun). It was (finally) fixed recently. So reporting it is probably doable, if you really, really want...

Posted by Gio on Fri 01 Nov 2024 at 05:47 from 94.70.25.x

I can confirm this bug as well. Tried to report this via MSVS ``Report a bug'' and landed to bing: what's trending... I gave up at that point, lol.

Thanks for the post and the possible workaround.

Posted by Justin on Fri 01 Nov 2024 at 09:42 from 71.125.233.x

not sure I care, we'll have to keep the workaround in our code anyway...

Add comment:

Name:
Human?: (no or yes, patented anti crap stuff here)
Comment:
search : rss : recent comments : Copyright © 2024 Justin Frankel