So I've worked on this some more but I'm still stuck =)
The +menu log shows a couple CreateMenu calls that I can immediately dismiss -- they're for the system menu (the one you get when you click the upper left box in the title bar). Using +win, there's a call to CreateWindowEx that passes a value for hMenu, but the name of this window is "listbox" and the app does have a listbox, and the listbox doesn't have it's own menu, so I'm assuming as per the MSDN docs this hMenu is actually a child window identifier (MSDN says that can be the case for certain window styles, and it looks like dlls/user/win.c does check for this, see here: http://tinyurl.com/qp1q).
Question: What's the "correct" behavior for CreateWindowEx to take if no hMenu is passed in english? I'm not sure what logic the code snippet below is following.
There's another call to CreateWindowEx that appears to be making the main window, that has no hMenu value passed to it. I planted a bunch of TRACE's in dlls/user/win.c and found that it's getting to the following section of CreateWindowEx:
(Around line 1046 or so, should be 10 or so lines off because of stuff I've added)
LPCSTR menuName = (LPCSTR)GetClassLongPtrA( hwnd, GCLP_MENUNAME ); if (menuName) { if (!cs->hInstance || HIWORD(cs->hInstance)) { TRACE("We get right here\n"); cs->hMenu = LoadMenuA(cs->hInstance,menuName); } else { cs->hMenu = HMENU_32(LoadMenu16(HINSTANCE_16(cs->hInstance),menuName)); }
if (cs->hMenu) { MENU_SetMenu( hwnd, cs->hMenu ); } }
In this section menuName is the same as the class name passed to CreateWindowEx. I don't know if that should cause problems. I haven't started looking at what GetClassLongPtrA does yet.
LoadMenuA must end up returning null, because it never ends up getting to the SetMenu call. Through judicious trace planting, I've deduced this string of calling:
LoadMenuA - > FindResourceA -> FindResourceExA -> findresourceA -> LdrFindResource_U -> find_entry -> RtlImageDirectoryEntryToData
And then a check this check returns true:
(Around line 2037 :P)
if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL;
At that point I stopped because I've now delved into the realm of deep black magic, and I suspect the bug must be somewhere earlier in the chain (probably in CreateWindowEx).
Thoughts? Ideas? :P