找回密码
 加入
搜索
查看: 11263|回复: 22

[系统综合] 如何在系统菜单里添加菜单项和相应事件?

 火.. [复制链接]
发表于 2012-2-21 21:53:14 | 显示全部楼层 |阅读模式
帮助中_GUICtrlMenu_GetSystemMenu()的例子可以在记事本的系统菜单中添加一个菜单项,

那如果响应它的点击事件?求例子

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2012-2-21 22:55:10 | 显示全部楼层
GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND")
这里面响应系统菜单事件
发表于 2012-2-21 22:56:34 | 显示全部楼层
发表于 2012-2-21 23:38:04 | 显示全部楼层
回复 2# 298311657

兄弟,你确定这样子就能响应非au3程序的自定义菜单项?
发表于 2012-2-21 23:42:34 | 显示全部楼层
需要 Hook
发表于 2012-2-22 00:59:19 | 显示全部楼层
WM_SYSCOMMAND 消息即可,网页快捕源码里有例子(置顶功能)
发表于 2012-2-22 01:44:32 | 显示全部楼层
本帖最后由 pusofalse 于 2012-2-22 01:51 编辑

#include <GUIMenu.au3>
#include <Thread.au3>

Const $tagREMOTE_SYSCOMMAND = "ptr SetWindowLongW;ptr CallWindowProcW;ptr GetSystemMenu;ptr GetMenuStringW;ptr MessageBoxW;ptr wsprintfW;ptr WndProc;dword Breakpoint;wchar wzTitle[16];wchar wzText[32];ubyte ShellX[256]"


$hWnd = WinGetHandle("[class:Notepad]")
If $hWnd = 0 Then
        Run(@WindowsDir & "\notepad.exe")
        $hWnd = WinWait("[class:Notepad]")
EndIf

$hMenu = _GUICtrlMenu_GetSystemMenu($hWnd)
If $hMenu = 0 Then Exit

_GUICtrlMenu_InsertMenuItem($hMenu, -1, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, -1, "Hello", 0xF201)

$iProcessID = WinGetProcess($hWnd)
$hProcess = _RTOpenProcess($iProcessID)

$pBaseAddress = _RTVirtualAllocEx($hProcess, 4096)

$tBuffer = DllStructCreate($tagREMOTE_SYSCOMMAND)
$pBuffer = DllStructGetPtr($tBuffer)

DllStructSetData($tBuffer, "SetWindowLongW", _RTGetProcAddress("User32.dll", "SetWindowLongW"))
DllStructSetData($tBuffer, "CallWindowProcW", _RTGetProcAddress("User32.dll", "CallWindowProcW"))
DllStructSetData($tBuffer, "GetSystemMenu", _RTGetProcAddress("User32.dll", "GetSystemMenu"))
DllStructSetData($tBuffer, "GetMenuStringW", _RTGetProcAddress("User32.dll", "GetMenuStringW"))
DllStructSetData($tBuffer, "MessageBoxW", _RTGetProcAddress("User32.dll", "MessageBoxW"))
DllStructSetData($tBuffer, "wsprintfW", _RTGetProcAddress("User32.dll", "wsprintfW"))
DllStructSetData($tBuffer, "Breakpoint", 0xCCCCCCCC)
DllStructSetData($tBuffer, "wzTitle", "Hello")
DllStructSetData($tBuffer, "wzText", "You clicked ID 0x%08X.")
DllStructSetData($tBuffer, "ShellX", _GetShellX())

_RTWriteProcessMemory($hProcess, $pBaseAddress, $pBuffer, DllStructGetSize($tBuffer))
$hThread = _RTCreateRemoteThread($hProcess, $pBaseAddress + 0x80, $hWnd)

_RTWaitForObject($hThread)
_RTCloseHandle($hThread)
_RTCloseHandle($hProcess)

Func _GetShellX()
        Local $bBinary = "0x558BEC53E8000000005B81EB890000008D83A8000000506AFCFF7508FF138943185B5DC20400CCCC558BEC53E8000000005B81EBB1000000817D0C12010000753AF7451000020000743181EC00040000568D742404FF75108D43405056FF531483C40C6A308D43205056FF7508FF531033C05E81C400040000EB12FF7514FF7510FF750CFF7508FF7318FF53045B5DC21000CCCC"

        Return Binary($bBinary)
EndFunc        ;==>_GetShellX


为了区分系统定义的命令ID,_GUICtrlMenu_InsertMenuItem函数中指定的ID的第9位必须为1,即合法的命令ID为 0x.....2..,0x.....3..,0x.....7..,0x.....E..等等,以下是汇编代码。
00AD0080     55                    push    ebp                              ; 设置窗口过程
00AD0081     8BEC                  mov     ebp, esp
00AD0083     53                    push    ebx
00AD0084     E8 00000000           call    00AD0089                         ; 代码自定位
00AD0089     5B                    pop     ebx
00AD008A     81EB 89000000         sub     ebx, 89
00AD0090     8D83 A8000000         lea     eax, dword ptr [ebx+A8]
00AD0096     50                    push    eax
00AD0097     6A FC                 push    -4
00AD0099     FF75 08               push    dword ptr [ebp+8]
00AD009C     FF13                  call    dword ptr [ebx]                  ; SetWindowLongW
00AD009E     8943 18               mov     dword ptr [ebx+18], eax
00AD00A1     5B                    pop     ebx
00AD00A2     5D                    pop     ebp
00AD00A3     C2 0400               retn    4
00AD00A6     CC                    int3
00AD00A7     CC                    int3
00AD00A8     55                    push    ebp                              ; 窗口过程
00AD00A9     8BEC                  mov     ebp, esp
00AD00AB     53                    push    ebx
00AD00AC     E8 00000000           call    00AD00B1
00AD00B1     5B                    pop     ebx
00AD00B2     81EB B1000000         sub     ebx, 0B1
00AD00B8     817D 0C 12010000      cmp     dword ptr [ebp+C], 112           ; if MsgID = WM_SYSCOMAMND ...
00AD00BF     75 3A                 jnz     short 00AD00FB
00AD00C1     F745 10 00020000      test    dword ptr [ebp+10], 200          ; 测试标志位
00AD00C8     74 31                 je      short 00AD00FB
00AD00CA     81EC 00040000         sub     esp, 400
00AD00D0     56                    push    esi
00AD00D1     8D7424 04             lea     esi, dword ptr [esp+4]
00AD00D5     FF75 10               push    dword ptr [ebp+10]
00AD00D8     8D43 40               lea     eax, dword ptr [ebx+40]
00AD00DB     50                    push    eax
00AD00DC     56                    push    esi
00AD00DD     FF53 14               call    dword ptr [ebx+14]               ; wsprintfW
00AD00E0     83C4 0C               add     esp, 0C
00AD00E3     6A 30                 push    30
00AD00E5     8D43 20               lea     eax, dword ptr [ebx+20]
00AD00E8     50                    push    eax
00AD00E9     56                    push    esi
00AD00EA     FF75 08               push    dword ptr [ebp+8]
00AD00ED     FF53 10               call    dword ptr [ebx+10]               ; MessageBoxW
00AD00F0     33C0                  xor     eax, eax
00AD00F2     5E                    pop     esi
00AD00F3     81C4 00040000         add     esp, 400
00AD00F9     EB 12                 jmp     short 00AD010D
00AD00FB     FF75 14               push    dword ptr [ebp+14]
00AD00FE     FF75 10               push    dword ptr [ebp+10]
00AD0101     FF75 0C               push    dword ptr [ebp+C]
00AD0104     FF75 08               push    dword ptr [ebp+8]
00AD0107     FF73 18               push    dword ptr [ebx+18]
00AD010A     FF53 04               call    dword ptr [ebx+4]                ; CallWindowProcW
00AD010D     5B                    pop     ebx
00AD010E     5D                    pop     ebp
00AD010F     C2 1000               retn    10
00AD0112     CC                    int3
00AD0113     CC                    int3
发表于 2012-2-22 08:08:40 | 显示全部楼层
p版 太厉害  学习学习。。。
 楼主| 发表于 2012-2-22 10:36:04 | 显示全部楼层
回复 7# pusofalse


    P大,你的例子好像是把事件写到内存中?
我想让此项目执行的事件为脚本中的一个自定义函数,该如何写?
 楼主| 发表于 2012-2-22 10:37:12 | 显示全部楼层
回复 2# 298311657


    我说的不是脚本自身的窗口哦.也可以?求例子.
发表于 2012-2-22 12:02:42 | 显示全部楼层
试试,学习了
发表于 2012-2-22 18:17:09 | 显示全部楼层
#include <MsgSpy.au3>

Const $WM_SYSCOMAMND = 0x112

$hWnd = WinGetHandle("[class:Notepad]")
If $hWnd = 0 Then
        Run(@WindowsDir & "\notepad.exe")
        $hWnd = WinWait("[class:Notepad]")
EndIf

$hMenu = _GUICtrlMenu_GetSystemMenu($hWnd)
If $hMenu = 0 Then Exit

_GUICtrlMenu_InsertMenuItem($hMenu, -1, "", 0)
_GUICtrlMenu_InsertMenuItem($hMenu, -1, "Hello", 0xF201)
_GUICtrlMenu_InsertMenuItem($hMenu, -1, "Test", 0xF202)


_SPY_InitLibrary()
_SPY_ListenPort($SPY_OBJECT_WINDOW)

$hCallBack = DllCallBackRegister("_SpyMsgHandler", "none", "ptr;long;ptr;hwnd;long;wparam;lparam;lresult")
$pCallBack = DllCallBackGetPtr($hCallBack)

Local $aMsg[1] = [$WM_SYSCOMAMND]

$pMsgFilter = _SPY_CreateMsgFilter($aMsg, $SPY_MSG_OK)
$pObject = _SPY_CreateObject($hWnd, $pCallBack, $pMsgFilter, 0)

_SPY_CreateChannel($pObject)
_SPY_SignalObject($pObject)

HotKeySet("!{esc}", "_OnExitFreeObject")

While 1
        Sleep(1000)
WEnd

Func _SpyMsgHandler($pObject, $iObjectType, $pContext, $hWnd, $iMsg, $iwParam, $ilParam, $iResult)
        If $iMsg = $WM_SYSCOMAMND Then
                Switch $iwParam
                Case 0xF201 To 0xF202
                        MsgBox(48, "Hello", StringFormat("You clicked ID 0x%08X.", $iwParam), 0, $hWnd)
                EndSwitch
        EndIf
EndFunc        ;==>_SpyMsgHandler

Func _OnExitFreeObject()
        _SPY_UnsignalObject($pObject)
        _SPY_CloseChannel($pObject)
        _SPY_CloseObject($pObject)

        DllCallBackFree($hCallBack)
        Exit
EndFunc        ;==>_OnExitFreeObject

评分

参与人数 1贡献 +5 收起 理由
lixiaolong + 5 厉害!!

查看全部评分

发表于 2012-2-22 19:55:57 | 显示全部楼层
可惜无MsgSpy.au3文件。努力
 楼主| 发表于 2012-2-22 19:58:07 | 显示全部楼层
回复 12# pusofalse


    P侠V5.
困扰了半年的问题终于解决....内牛满面.....
发表于 2012-2-22 20:36:50 | 显示全部楼层
本帖最后由 pusofalse 于 2012-2-22 20:39 编辑

将 _SpyMsgHandler函数中的Switch $iwParam ... 改成 If BitAND($iwParam, 0x200) Then ...,判断wParam参数的标志位。系统定义的命令ID都是 0xF0XX或0xF1XX,第9位都是0,BitAND($iwParam, 0x200) 如果第9位(以第0位为基始)不为0,则说明是Au3进程添加的菜单项。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-26 11:48 , Processed in 0.303695 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表