Reputation: 6051
How can I detect whether a specific app (where the app's window handle and process-ID are known) currently has any MENU opened (main menu or popup menu)?
I have researched this but did not find anything.
Upvotes: 1
Views: 545
Reputation: 54802
A possible implementation might involve enumerating top level windows of the thread that the target application window belongs, to search if any one of them is the menu window class. This is '#32768' as per the documentation.
Following example does the same for Windows 7 calculator in a timer event handler. The example outputs a debug string if the program's menu or context menu is open.
function EnumThreadWindowsCallback(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
const
MenuWndClass = '#32768';
var
ClassName: array[0..256] of Char;
begin
Result := True;
if (GetClassName(hwnd, ClassName, Length(ClassName)) = Length(MenuWndClass)) and
(ClassName = MenuWndClass) then begin
PBoolean(lparam)^ := True;
Result := False;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
Wnd: HWND;
ThrId: DWORD;
MenuWnd: Boolean;
begin
Wnd := FindWindow('CalcFrame', 'Calculator');
if Wnd <> 0 then begin
ThrId := GetWindowThreadProcessId(Wnd);
MenuWnd := False;
EnumThreadWindows(ThrId, @EnumThreadWindowsCallback, LPARAM(@MenuWnd));
if MenuWnd then
OutputDebugString('active menu');
end;
end;
Upvotes: 2