Reputation: 3425
I wanted to get the dimensions of a drop-down menu from the menu-bar. According to Microsoft documentation if I pass in OBJID_CLIENT
to the idObject
parameter of
BOOL GetMenuBarInfo(
HWND hwnd,
LONG idObject,
LONG idItem,
PMENUBARINFO pmbi
);
I should be able to retrieve the MENUBARINFO
structure of
The popup menu associated with the window.
However I don't believe there is a pop-up menu associated with a window. Calling GetMenuBarInfo()
with OBJID_CLIENT
gives me zeros, calling SetMenu()
(on a sub-menu on the menu-bar) gives me an ERROR_INVALID_PARAMETER
error code. TrackPopupMenu()
is the only documented way to display pop-up menus but it blocks.
Is the documentation wrong?
Upvotes: 1
Views: 697
Reputation: 3425
case WM_MENUSELECT:
{
HWND myhWnd = FindWindowW(L"#32768", nullptr);
GetMenuBarInfo(myhWnd, OBJID_CLIENT, 0, &info);
printf_rect(info.rcBar);
}
works. But I wouldn't have known how to get the name of the system menu class without out Drake's answer:
hook the Winproc of system menu class
L"#32768"
.
Upvotes: 2
Reputation: 7170
In this case, hWnd
needs to specify the window handle of menu bar, and the pop menu is visible.
This is usually used in Windows Hook. sample:
HHOOK hhook;
LRESULT CALLBACK myHookProc(int code, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* lpcwps = (CWPSTRUCT*)lParam;
BOOL ret = 0;
if (code == HC_ACTION)
{
if (lpcwps->message == MN_GETHMENU)
{
MENUBARINFO minfo;
minfo.cbSize = sizeof(MENUBARINFO);
ret = GetMenuBarInfo(lpcwps->hwnd, OBJID_CLIENT, 0, &minfo);
printf_rect(minfo.rcBar);
}
}
return CallNextHookEx(hhook, code, wParam, lParam);
}
And
hhook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)myHookProc, hInstance, GetCurrentThreadId());
This will hook the Winproc of system menu class L"#32768"
, and get the menubar window when the after the pop-up menu has been visable.
Upvotes: 2
Reputation: 13679
TrackPopupMenu()
does not block your code from execution. It has message loop inside, this message loop processed popup menu messages and messages of your window.
For example, if your window is being repainted while showing menu caused by TrackPopupMenu()
, you are able to find that menu using GetMenuBarInfo
from your WM_PAINT
handler. Same way with WM_TIMER
or other messages, there's even dedicated WM_ENTERMENULOOP
message.
Upvotes: 2