lixiaolong 发表于 2011-5-22 16:37:18

(已解决)获取桌面右键菜单中点击的项目名

本帖最后由 lixiaolong 于 2011-5-23 04:39 编辑

像http://www.autoitx.com/thread-20923-1-1.html
和http://www.autoitx.com/forum.php?mod=viewthread&tid=16944&highlight=%D3%D2%BC%FC
的菜单中点击项目时,我想获取点击的项目名。

比如有3个项目

1.查找目标(F)
2.打开记事本
3.打开IE浏览器

我想点击"查找目标(F) "的时候获取 "查找目标(F)" 的字符串.
我想点击"打开记事本"的时候获取 "打开记事本" 的字符串.
我想点击"打开IE浏览器"的时候获取 "打开IE浏览器" 的字符串.

请问如何获取这个字符串?

3mile 发表于 2011-5-22 17:28:35

#include <GuiMenu.au3>
Opt('WinSearchChildren', 1)

HotKeySet('{ESC}', '_EXIT')

Global Const $MN_GETHMENU = 0x01E1
Global Const $EVENT_SYSTEM_MENUPOPUPSTART = 0x0006
Global $hFunc, $pFunc
Global $hWinHook

$hFunc = DllCallbackRegister('_WinEventProc', 'none', 'ptr;uint;hwnd;int;int;uint;uint')
$pFunc = DllCallbackGetPtr($hFunc)
$hWinHook = _SetWinEventHook(0x00000001, 0x7FFFFFFF, 0, $pFunc, 0, 0,BitOR(0x0002, 0x0000))

While 1
        Sleep(20)
WEnd

Func _EXIT()
        Exit
EndFunc   ;==>_EXIT

Func OnAutoItExit()
        _UnhookWinEvent($hWinHook)
        DllCallbackFree($hFunc)
EndFunc   ;==>OnAutoItExit

Func _WinEventProc($hHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iEventThread, $imsEventTime)
        Local $hMenu
       
        If $iEvent = $EVENT_SYSTEM_MENUPOPUPSTART Then
                $hMenu = _SendMessage($hWnd, 0x01E1)
                If _GUICtrlMenu_IsMenu($hMenu) Then
                        For $i = 0 To _GUICtrlMenu_GetItemCount($hMenu) - 1
                                Local $sItemText = _GUICtrlMenu_GetItemText($hMenu, $i)
                                If $sItemText = '' Then ContinueLoop
                               
                                ConsoleWrite($sItemText & @CRLF); ' is ')
                        Next
                EndIf
                ConsoleWrite(@CRLF)
        EndIf
EndFunc   ;==>_WinEventProc

Func _SetWinEventHook($ieventMin, $ieventMax, $hMod, $pCallback, $iProcID, $iThreadID, $iFlags)
        Local $aRet
       
        $aRet = DllCall('user32.dll', 'ptr', 'SetWinEventHook', 'uint', $ieventMin, 'uint', $ieventMax, _
                        'hwnd', $hMod, 'ptr', $pCallback, 'dword', $iProcID, 'dword', $iThreadID, 'uint', $iFlags)
       
        If @error Or $aRet = 0 Then Return SetError(1, 0, 0)
        Return $aRet
EndFunc   ;==>_SetWinEventHook

Func _UnhookWinEvent($hWinEventHook)
        Local $aRet
       
        $aRet = DllCall('user32.dll', 'int', 'UnhookWinEvent', 'ptr', $hWinEventHook)
        If @error Or $aRet = 0 Then Return SetError(1, 0, 0)
        Return $aRet
EndFunc   ;==>_UnhookWinEvent

lixiaolong 发表于 2011-5-22 18:33:02

回复 2# 3mile

谢谢前辈,这个可以获取菜单.
我语文不好,可能是没说明白.

比如我作了一个程序,把这个程序添加到桌面右键菜单里.

我想获取的是我点击哪个项目名启动了这个程序.
可以实现吗?我想不出来。。。

lixiaolong 发表于 2011-5-22 19:05:14

回复 2# 3mile

我写例子了,请前辈看看能不能实现?#NoTrayIcon

If $CmdLine > 0 Then
        $get = 在这里获取点击哪个项目名启动了本程序

        If $get = 'ReNameFile' Then; 如果点击了'ReNameFile'
                Send("{F2}")
        ElseIf $get = 'DelFile' Then; 如果点击了'DelFile'
                MsgBox(0, "", "削除")
        EndIf
Else
        If RegRead('HKCU\Software\Classes\*\shell\ReNameFile', '') = 'ReNameFile' Then
                RegDelete('HKCU\Software\Classes\*\shell\ReNameFile')
                RegDelete('HKCU\Software\Classes\*\shell\DelFile')
                If Not @error Then MsgBox(64, 'Un Install ReNameFile', '“OK!')
        Else
                RegWrite('HKCU\Software\Classes\*\shell\ReNameFile', '', 'REG_SZ', 'ReNameFile')
                RegWrite('HKCU\Software\Classes\*\shell\ReNameFile\Command', '', 'REG_SZ', '"' & @ScriptFullPath & '" %1')
                RegWrite('HKCU\Software\Classes\*\shell\DelFile', '', 'REG_SZ', 'DelFile')
                RegWrite('HKCU\Software\Classes\*\shell\DelFile\Command', '', 'REG_SZ', '"' & @ScriptFullPath & '" %1')
                If Not @error Then MsgBox(64, 'Install ReNameFile', '“OK!')
        EndIf
EndIf

3mile 发表于 2011-5-22 22:12:51

本帖最后由 3mile 于 2011-5-22 22:33 编辑

回复 4# lixiaolong
用个笨办法试试:
#include <GuiMenu.au3>
Opt('WinSearchChildren', 1)

HotKeySet('{ESC}', '_EXIT')
OnAutoItExitRegister('OnAutoItExit')

Global Const $MN_GETHMENU = 0x01E1
Global Const $EVENT_SYSTEM_MENUPOPUPSTART = 0x0006
Global Const $EVENT_SYSTEM_MENUPOPUPEND = 0x0007
Global $tPOINT, $tRECT, $hEventHook, $Index, $hMenu = 0, $itemtext

Global $hFunc, $pFunc
Global $hWinHook

$hFunc = DllCallbackRegister('_WinEventProc', 'none', 'ptr;uint;hwnd;int;int;uint;uint')
$pFunc = DllCallbackGetPtr($hFunc)
$hWinHook = _SetWinEventHook(0x00000001, 0x7FFFFFFF, 0, $pFunc, 0, 0, BitOR(0x0002, 0x0000))

While 1
        Sleep(20)
WEnd

Func _EXIT()
        Exit
EndFunc   ;==>_EXIT

Func OnAutoItExit()
        _UnhookWinEvent($hWinHook)
        DllCallbackFree($hFunc)
EndFunc   ;==>OnAutoItExit

Func _WinEventProc($hHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iEventThread, $imsEventTime)
       
        Switch $iEvent
                Case $EVENT_SYSTEM_MENUPOPUPSTART
                        $hMenu = _SendMessage($hWnd, 0x01E1)
                        $Index = _GUICtrlMenu_GetItemCount($hMenu)
                        ReDim $tRECT[$Index]
                        ReDim $itemtext[$Index]
                        For $i = 0 To $Index - 1
                                $tRECT[$i] = _GUICtrlMenu_GetItemRectEx($hWnd, $hMenu, $i)
                                $itemtext[$i] = _GUICtrlMenu_GetItemText($hMenu, $i)
                        Next
                Case $EVENT_SYSTEM_MENUPOPUPEND
                        If $hMenu Then
                                $tPOINT = _WinAPI_GetMousePos()
                                For $i = 0 To UBound($tRECT) - 1
                                        If _WinAPI_PtInRect($tRECT[$i], $tPOINT) Then
                                                ToolTip($itemtext[$i], @DesktopWidth - 100, @DesktopHeight - 100, "点击的菜单项:", 1, 4)
                                        EndIf
                                Next
                                Global $tRECT
                                Global $itemtext
                                $hMenu = 0
                        EndIf
        EndSwitch
EndFunc   ;==>_WinEventProc

Func _SetWinEventHook($ieventMin, $ieventMax, $hMod, $pCallback, $iProcID, $iThreadID, $iFlags)
        Local $aRet
       
        $aRet = DllCall('user32.dll', 'ptr', 'SetWinEventHook', 'uint', $ieventMin, 'uint', $ieventMax, _
                        'hwnd', $hMod, 'ptr', $pCallback, 'dword', $iProcID, 'dword', $iThreadID, 'uint', $iFlags)
       
        If @error Or $aRet = 0 Then Return SetError(1, 0, 0)
        Return $aRet
EndFunc   ;==>_SetWinEventHook

Func _UnhookWinEvent($hWinEventHook)
        Local $aRet
       
        $aRet = DllCall('user32.dll', 'int', 'UnhookWinEvent', 'ptr', $hWinEventHook)
        If @error Or $aRet = 0 Then Return SetError(1, 0, 0)
        Return $aRet
EndFunc   ;==>_UnhookWinEvent

3mile 发表于 2011-5-22 22:33:41

原来WINAPI里面有HOOK,晕了.
#Include <GUIMenu.au3>
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword')
Global $tPOINT, $tRECT, $hEventHook, $Index, $hMenu = 0,$itemtext

OnAutoItExitRegister('OnAutoItExit')

$hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_MENUPOPUPSTART, $EVENT_SYSTEM_MENUPOPUPEND, DllCallbackGetPtr($hEventProc))

While 1
        Sleep(1000)
WEnd

Func OnAutoItExit()
        _WinAPI_UnhookWinEvent($hEventHook)
        DllCallbackFree($hEventProc)
EndFunc   ;==>OnAutoItExit

Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadID, $iEventTime)
        Switch $iEvent
                Case $EVENT_SYSTEM_MENUPOPUPSTART
                        $hMenu = _SendMessage($hWnd, $MN_GETHMENU)
                        If (_GUICtrlMenu_IsMenu($hMenu)) And   (StringInStr(_WinAPI_GetWindowFileName($hWnd), 'explorer.exe')) then ;And (StringInStr(_GUICtrlMenu_GetItemText($hMenu, 0), '查看')) Then
                                $Index = _GUICtrlMenu_GetItemCount($hMenu)
                                ReDim $tRECT[$Index+1]
                                ReDim $itemtext[$Index+1]
                                for $i=0 to $Index
                                        $tRECT[$i] = _GUICtrlMenu_GetItemRectEx($hWnd, $hMenu, $i)
                                        $itemtext[$i]=_GUICtrlMenu_GetItemText($hMenu, $i)
                                Next
                        Else
                                $hMenu = 0
                        EndIf
                Case $EVENT_SYSTEM_MENUPOPUPEND
                        If $hMenu Then
                                $tPOINT = _WinAPI_GetMousePos()
                                for $i=0 to UBound($tRECT)-1
                                If _WinAPI_PtInRect($tRECT[$i], $tPOINT) Then
                                        ToolTip($itemtext[$i],@DesktopWidth-100,@DesktopHeight-100,"点击的菜单项:",1,4)
                                EndIf
                                Next
                                Global $tRECT
                                Global $itemtext
                                $hMenu = 0
                        EndIf
        EndSwitch
EndFunc   ;==>_EventProc

lixiaolong 发表于 2011-5-23 00:50:47

回复 6# 3mile

多谢前辈!用前辈的代码成功了!

richardhc 发表于 2012-3-30 08:34:36

在远程连接的时候,程序貌似有问题。。。

fybhwsx 发表于 2018-3-27 07:57:20

本帖最后由 fybhwsx 于 2018-3-27 08:02 编辑

原来WINAPI里面有HOOK,晕了.
3mile 发表于 2011-5-22 22:33 http://www.autoit3.cn/images/common/back.gif


    看不懂,谁能给个使用的例子!谢谢!
页: [1]
查看完整版本: (已解决)获取桌面右键菜单中点击的项目名