Jump to content

Recommended Posts

Posted

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?

#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

 

Posted

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.

Posted
MouseClick("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

Posted

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:

; 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

 

Posted
; 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

 

Posted (edited)

You are just making it complicated with event hook, you should have just added in your loop what thiofox told you:

; 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 by kosamja
Posted

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

 

; 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

 

Posted
;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

 

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...