Nikolas92 Posted October 15, 2016 Share Posted October 15, 2016 Hi, explorer context menu sometimes gets stuck and I would like to kill it, but I dont know how to check is context menu under mouse? Can someone show me some example? expandcollapse popup#NoTrayIcon #include <Misc.au3> #include <WinAPISys.au3> Opt("WinWaitDelay", 0) Opt("MouseClickDelay", 0) Opt("MouseClickDownDelay", 0) Opt("MouseClickDragDelay", 0) Opt("SendKeyDelay", 0) Opt("SendKeyDownDelay", 0) Global $hNTDll = DllOpen("ntdll.dll") Local $left, $right, $top, $bottom, $MouseX, $MouseY While 1 $hWnd = WinWait('[CLASS:#32768]') $aPos = WinGetPos($hWnd) Do _HighPrecisionSleep(0.1) until _WinAPI_GetAsyncKeyState(0x01) = False and _WinAPI_GetAsyncKeyState(0x02) = False If IsArray($aPos) Then While 1 _HighPrecisionSleep(0.1) If _IsPressed(01) Or _IsPressed(02) Then Do _HighPrecisionSleep(0.1) until _WinAPI_GetAsyncKeyState(0x01) = False and _WinAPI_GetAsyncKeyState(0x02) = False $MousePos = MouseGetPos() If $aPos[0] < $MousePos[0] And $MousePos[0] < $aPos[0] + $aPos[2] And $aPos[1] < $MousePos[1] And $MousePos[1] < $aPos[1] + $aPos[3] Then ; Mouse cursor is still inside window. If not WinExists($hWnd) Then ExitLoop Else WinKill($hWnd) ExitLoop EndIf EndIf WEnd EndIf WEnd Func _HighPrecisionSleep($iMicroSeconds) Local $hStruct = DllStructCreate("int64 time;") DllStructSetData($hStruct, "time", -1 * ($iMicroSeconds * 10)) DllCall($hNTDll, "dword", "NtDelayExecution", "int", 0, "ptr", DllStructGetPtr($hStruct)) EndFunc ;==>_HighPrecisionSleep Link to comment Share on other sites More sharing options...
Nikolas92 Posted October 15, 2016 Author Share Posted October 15, 2016 Dont know why I cant edit previous post, but code I posted above doesnt work correctly in case of submenus and usually kills menu when clicking on submenu item. Link to comment Share on other sites More sharing options...
ThioFoX Posted October 16, 2016 Share Posted October 16, 2016 expandcollapse popupMouseClick("menu") Send("{DOWN}") $Last = "" While Sleep(500) $HighlightedMenu = GetTextFromMenuContext() If $HighlightedMenu <> $Last Then ConsoleWrite($HighlightedMenu & @CRLF) $Last = $HighlightedMenu EndIf WEnd Func GetTextFromMenuContext() Local $hWnd, $hMenu, $isMenu, $hMenuCount, $hMenuText $hWnd = WinGetHandle("[CLASS:#32768]") $hMenu = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", 0x01E1, "wparam", 0, "lparam", 0) $isMenu = DllCall("user32.dll", "bool", "IsMenu", "handle", $hMenu[0]) If $isMenu[0] Then $hMenuCount = DllCall("user32.dll", "int", "GetMenuItemCount", "handle", $hMenu[0]) For $iItem = 0 To $hMenuCount[0] Step +1 $hMenuText = DllCall("user32.dll", "int", "GetMenuStringW", "handle", $hMenu[0], "uint", $iItem, "wstr", "", "int", 4096, "uint", 0x400) $bMenuHighlight = InfoMenu($hMenu[0], $iItem) If $bMenuHighlight = True Then Return $hMenuText[3] Next EndIf EndFunc ;==>GetTextFromMenuContext Func InfoMenu($hMenu, $iItem) Local Const $MFS_HILITE = 0x00000080 Local $tInfo = DllStructCreate("uint Size;uint Mask;uint Type;uint State;uint ID;handle SubMenu;" & _ "handle BmpChecked;handle BmpUnchecked;ulong_ptr ItemData;ptr TypeData;uint CCH;handle BmpItem") DllStructSetData($tInfo, "Size", DllStructGetSize($tInfo)) DllStructSetData($tInfo, "Mask", 0x3F) DllCall("user32.dll", "bool", "GetMenuItemInfo", "handle", $hMenu, "uint", $iItem, "bool", True, "struct*", $tInfo) $aResult = BitAND(DllStructGetData($tInfo, "State"), $MFS_HILITE) <> 0 Return $aResult EndFunc ;==>InfoMenu Or better: _GUICtrlMenu_GetItemHighlighted Link to comment Share on other sites More sharing options...
Nikolas92 Posted October 16, 2016 Author Share Posted October 16, 2016 Hi ThioFoX, thanks for answering, but it looks that there is no need to check for what context menu item is under mouse since this seems to work: expandcollapse popup; www.autoitscript.com/forum/topic/114628-capture-the-windows-events/ ; www.autoitscript.com/forum/topic/56536-easy-shell-hooking-example/?page=2 #NoTrayIcon #include<WinAPISys.au3> #include <Misc.au3> Opt("WinWaitDelay", 0) Opt("MouseClickDelay", 0) Opt("MouseClickDownDelay", 0) Opt("MouseClickDragDelay", 0) Opt("SendKeyDelay", 0) Opt("SendKeyDownDelay", 0) Opt("WinTitleMatchMode", 3) Global $ContextMenu = '' Global $hGUI = GUICreate('') GUIRegisterMsg(_WinAPI_RegisterWindowMessage('SHELLHOOK'), 'WM_SHELLHOOK') _WinAPI_RegisterShellHookWindow($hGUI) $hHookFunc = DllCallbackRegister('_WinEventProc', 'none', 'ptr;uint;hwnd;int;int;uint;uint') $hWinHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_MENUPOPUPSTART, $EVENT_SYSTEM_DIALOGSTART, DllCallbackGetPtr($hHookFunc)) While 1 Sleep(1000) WEnd Func WM_SHELLHOOK($hWnd, $iMsg, $wParam, $lParam) If $wParam = $HSHELL_WINDOWACTIVATED Or $wParam = $HSHELL_RUDEAPPACTIVATED Then $WindowHandle = $lParam $WindowClass = _WinAPI_GetClassName($WindowHandle) If $WindowClass = '#32768' Then $ContextMenu = $WindowHandle ElseIf $WindowClass <> '#32768' And $ContextMenu <> '' And (_IsPressed(01) Or _IsPressed(02)) Then WinKill($ContextMenu) EndIf EndIf EndFunc Func _WinEventProc($hHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iEventThread, $imsEventTime) $WindowHandle = $hWnd $WindowClass = _WinAPI_GetClassName($WindowHandle) If $WindowClass = '#32768' Then $ContextMenu = $WindowHandle ElseIf $WindowClass <> '#32768' And $ContextMenu <> '' And (_IsPressed(01) Or _IsPressed(02)) Then WinKill($ContextMenu) EndIf EndFunc Link to comment Share on other sites More sharing options...
Nikolas92 Posted October 16, 2016 Author Share Posted October 16, 2016 expandcollapse popup; www.autoitscript.com/forum/topic/114628-capture-the-windows-events/ ; www.autoitscript.com/forum/topic/56536-easy-shell-hooking-example/?page=2 ; www.autoitscript.com/forum/topic/185055-how-to-check-is-context-menu-under-mouse/ #NoTrayIcon #include<WinAPISys.au3> #include <Misc.au3> #Include <SendMessage.au3> #include <GuiMenu.au3> #include <WindowsConstants.au3> Opt("WinWaitDelay", 0) Opt("MouseClickDelay", 0) Opt("MouseClickDownDelay", 0) Opt("MouseClickDragDelay", 0) Opt("SendKeyDelay", 0) Opt("SendKeyDownDelay", 0) Opt("WinTitleMatchMode", 3) If WinExists('[CLASS:#32768]') Then Global $ContextMenu = WinGetHandle('[CLASS:#32768]') Else Global $ContextMenu = '' EndIf $hHookFunc = DllCallbackRegister('_WinEventProc', 'none', 'ptr;uint;hwnd;int;int;uint;uint') $hWinHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_FOREGROUND, $EVENT_SYSTEM_CAPTURESTART, DllCallbackGetPtr($hHookFunc)) While 1 Sleep(1000) WEnd Func _WinEventProc($hHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iEventThread, $imsEventTime) If $iEvent = $EVENT_SYSTEM_FOREGROUND or $iEvent = $EVENT_SYSTEM_MENUPOPUPSTART or $iEvent = $EVENT_SYSTEM_CAPTURESTART Then $Submenu = 'No' $WindowHandle = $hWnd $WindowClass = _WinAPI_GetClassName($WindowHandle) If $WindowClass = '#32768' Then $hMenu = _SendMessage($ContextMenu, $MN_GETHMENU, 0, 0) $MenuCount = _GUICtrlMenu_GetItemCount($hMenu) For $i = $MenuCount to 0 Step -1 $tInfo = _GUICtrlMenu_GetItemInfo($hMenu, $i) If BitAND(DllStructGetData($tInfo, "State"), $MFS_HILITE) <> 0 Then $Submenu = 'yes' ExitLoop EndIf Next If $ContextMenu <> '' and $ContextMenu <> $WindowHandle and $Submenu = 'No' Then WinKill($ContextMenu) $ContextMenu = $WindowHandle ElseIf $ContextMenu <> '' And (_IsPressed(01) Or _IsPressed(02)) Then WinKill($ContextMenu) EndIf EndIf EndFunc Link to comment Share on other sites More sharing options...
kosamja Posted October 17, 2016 Share Posted October 17, 2016 (edited) You are just making it complicated with event hook, you should have just added in your loop what thiofox told you: expandcollapse popup; www.unknowncheats.me/forum/1265891-post1.html ; www.autoitscript.com/forum/topic/183986-how-to-hide-focus-rectangle-for-any-control/ ; www.autoitscript.com/forum/topic/185055-how-to-check-is-context-menu-under-mouse/ #NoTrayIcon #include <Misc.au3> #include <WinAPISys.au3> #Include <SendMessage.au3> #include <GuiMenu.au3> #include <WindowsConstants.au3> Opt("WinWaitDelay", 0) Opt("MouseClickDelay", 0) Opt("MouseClickDownDelay", 0) Opt("MouseClickDragDelay", 0) Opt("SendKeyDelay", 0) Opt("SendKeyDownDelay", 0) Opt("WinTitleMatchMode", 3) Global $hNTDll = DllOpen("ntdll.dll") Global $MenuItemHighlighted, $left, $right, $top, $bottom, $MouseX, $MouseY While 1 $MenuItemHighlighted = 'No' $hWnd = WinWait('[CLASS:#32768]') $hMenu = _SendMessage($hWnd, $MN_GETHMENU, 0, 0) $MenuCount = _GUICtrlMenu_GetItemCount($hMenu) Do _HighPrecisionSleep(0.1) until _WinAPI_GetAsyncKeyState(0x01) = False and _WinAPI_GetAsyncKeyState(0x02) = False $aPos = WinGetPos($hWnd) If IsArray($aPos) Then While 1 _HighPrecisionSleep(0.1) If _IsPressed(01) Or _IsPressed(02) Then $MousePos = MouseGetPos() For $i = 0 to $MenuCount - 1 $tInfo = _GUICtrlMenu_GetItemInfo($hMenu, $i) If BitAND(DllStructGetData($tInfo, "State"), $MFS_HILITE) <> 0 Then $MenuItemHighlighted = 'yes' ExitLoop EndIf Next If $MenuItemHighlighted = 'yes' or ($aPos[0] < $MousePos[0] And $MousePos[0] < $aPos[0] + $aPos[2] And $aPos[1] < $MousePos[1] And $MousePos[1] < $aPos[1] + $aPos[3]) Then ; Mouse cursor is still inside window. If not WinExists($hWnd) Then ExitLoop Else WinKill($hWnd) ExitLoop EndIf EndIf WEnd EndIf WEnd Func _HighPrecisionSleep($iMicroSeconds) Local $hStruct = DllStructCreate("int64 time;") DllStructSetData($hStruct, "time", -1 * ($iMicroSeconds * 10)) DllCall($hNTDll, "dword", "NtDelayExecution", "int", 0, "ptr", DllStructGetPtr($hStruct)) EndFunc ;==>_HighPrecisionSleep Edited October 17, 2016 by kosamja Link to comment Share on other sites More sharing options...
Nikolas92 Posted October 17, 2016 Author Share Posted October 17, 2016 Hi kosamja, I tried that already, but it still doesnt work correctly on submenus. I currently trying this code, so it would be nice if you or anyone else could look in this code and help me find if there are any error in it expandcollapse popup; www.autoitscript.com/forum/topic/114628-capture-the-windows-events/ ; www.autoitscript.com/forum/topic/56536-easy-shell-hooking-example/?page=2 ; www.autoitscript.com/forum/topic/185055-how-to-check-is-context-menu-under-mouse/ #NoTrayIcon #include<WinAPISys.au3> #include <Misc.au3> #Include <SendMessage.au3> #include <GuiMenu.au3> #include <WindowsConstants.au3> Opt("WinWaitDelay", 0) Opt("MouseClickDelay", 0) Opt("MouseClickDownDelay", 0) Opt("MouseClickDragDelay", 0) Opt("SendKeyDelay", 0) Opt("SendKeyDownDelay", 0) Opt("WinTitleMatchMode", 3) $MenuNumber = WinList('[CLASS:#32768]') If $MenuNumber[0][0] = 0 Then Global $ContextMenu = '' Global $SubMenu = '' Else If $MenuNumber[0][0] = 1 Then Global $ContextMenu = $MenuNumber[1][1] Global $SubMenu = '' Else $match = '' For $j = 1 to 2 $WindowHandle = $MenuNumber[$j][1] $hMenu = _SendMessage($WindowHandle, $MN_GETHMENU, 0, 0) $MenuCount = _GUICtrlMenu_GetItemCount($hMenu) For $i = 0 to $MenuCount - 1 $tInfo = _GUICtrlMenu_GetItemInfo($hMenu, $i) $SubMenuHandle = _GUICtrlMenu_GetItemSubMenu($hMenu, $i) If BitAND(DllStructGetData($tInfo, "State"), $MFS_HILITE) <> 0 And $SubMenuHandle <> 0 Then Global $ContextMenu = $WindowHandle If $j = 1 Then Global $SubMenu = $MenuNumber[2][1] Else Global $SubMenu = $MenuNumber[1][1] EndIf $match = 'found' ExitLoop EndIf Next If $match <> '' Then ExitLoop Next If $match = '' Then Global $ContextMenu = $MenuNumber[1][1] Global $SubMenu = '' EndIf For $i = 1 to $MenuNumber[0][0] If $ContextMenu <> $MenuNumber[$i][1] And $SubMenu <> $MenuNumber[$i][1] Then WinKill($MenuNumber[$i][1]) Next EndIf EndIf $hHookFunc = DllCallbackRegister('_WinEventProc', 'none', 'ptr;uint;hwnd;int;int;uint;uint') $hWinHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_FOREGROUND, $EVENT_SYSTEM_CAPTURESTART, DllCallbackGetPtr($hHookFunc)) While 1 Sleep(1000) WEnd Func _WinEventProc($hHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iEventThread, $imsEventTime) If $iEvent = $EVENT_SYSTEM_FOREGROUND or $iEvent = $EVENT_SYSTEM_MENUPOPUPSTART or $iEvent = $EVENT_SYSTEM_CAPTURESTART Then $WindowHandle = $hWnd $WindowClass = _WinAPI_GetClassName($WindowHandle) If $WindowClass = '#32768' Then $hMenu = _SendMessage($ContextMenu, $MN_GETHMENU, 0, 0) $MenuCount = _GUICtrlMenu_GetItemCount($hMenu) For $i = 0 to $MenuCount - 1 $tInfo = _GUICtrlMenu_GetItemInfo($hMenu, $i) If BitAND(DllStructGetData($tInfo, "State"), $MFS_HILITE) <> 0 Then If $SubMenu = '' or not WinExists($SubMenu) Then $SubMenu = $WindowHandle ExitLoop EndIf Next If $ContextMenu <> '' and $ContextMenu <> $WindowHandle and $SubMenu <> $WindowHandle and WinExists($WindowHandle) Then If $SubMenu <> '' Then WinKill($SubMenu) $SubMenu = '' EndIf WinKill($ContextMenu) $ContextMenu = $WindowHandle EndIf ElseIf $ContextMenu <> '' And (_IsPressed(01) Or _IsPressed(02)) Then If $SubMenu <> '' Then WinKill($SubMenu) $SubMenu = '' EndIf WinKill($ContextMenu) EndIf EndIf EndFunc Link to comment Share on other sites More sharing options...
ThioFoX Posted October 17, 2016 Share Posted October 17, 2016 ;Kill any Context Menu if the window active isn't the PID of the context menu While Sleep(500) $hWnd = WinGetHandle("[CLASS:#32768]") $ContextMenuPID = WinGetProcess($hWnd) $WinActivePID = WinGetProcess(WinActive("")) ConsoleWrite("Context Menu PID: " & $ContextMenuPID & @TAB & "Active Window PID: " & $WinActivePID & @CRLF) If $WinActivePID <> $ContextMenuPID And $ContextMenuPID <> -1 Then ConsoleWrite("Context Menu " & $hWnd & " was killed!" & @CRLF) WinKill($hWnd) ;ExitLoop ; If you want! EndIf WEnd Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now