Feren6、私はあなたを圧倒しないことを願っていますが、私は一度このテキストを切り取ったことがあり、まだ使用していません。それがあなた、特にHSHELL_ENDTASKに役立つことを願っています。
wParamの文書化された値は次のとおりです。
1. HSHELL_WINDOWCREATED
2. HSHELL_WINDOWDESTROYED
3. HSHELL_ACTIVATESHELLWINDOW
4. HSHELL_WINDOWACTIVATED
5. HSHELL_GETMINRECT
6. HSHELL_REDRAW
7. HSHELL_TASKMAN
8. HSHELL_LANGUAGE
9. HSHELL_SYSMENU
10. HSHELL_ENDTASK
11. HSHELL_ACCESSIBILITYSTATE
12. HSHELL_APPCOMMAND
13. HSHELL_WINDOWREPLACED
14. HSHELL_WINDOWREPLACING
15. HSHELL_HIGHBIT
16. HSHELL_FLASH
17. HSHELL_RUDEAPPACTIVATED
lParamは、受け取ったwParamの値に応じてタイプが異なります。ほとんどのwParam値の場合、lParamは、AHKのWindowコマンドでahk_id%lParam%として使用できるウィンドウへのハンドルです。
いくつかのアイデア:ウィンドウが最小化/最大化されるたびに、シェルはHSHELL_GETMINRECT(シェルフック構造を使用)を受け取ります。スクリプトがそれを監視して、トレイへのウィンドウを最小化する場合があります。ウィンドウが再描画されているときに、シェルはHSHELL_REDRAWを受け取ります。スクリプトは、内容が変更されるたびにウィンドウをアクティブにするためにそれを監視する場合があります。
私は実験を試みました、そしてここにいくつかの例があります:
実験1:
Windows XPでは、CTRL + ALT+DELによってタスクマネージャーが表示されます。フォーラムでは、タスクマネージャーへのアクセスを拒否する方法を要求する投稿がいくつか見られました。次のスクリプトは、作成時にほぼ瞬時にWindowsタスクマネージャーを検出して閉じます。
コード:
持続的
SetBatchLines、-1プロセス、優先度、、高
Gui + LastFound hWnd:= WinExist()
DllCall( "RegisterShellHookWindow"、UInt、hWnd)MsgNum:= DllCall( "RegisterWindowMessage"、Str、 "SHELLHOOK")OnMessage(MsgNum、 "ShellMessage")Return
ShellMessage(wParam、lParam){If(wParam = 1); HSHELL_WINDOWCREATED:= 1 {WinGetTitle、Title、ahk_id%lParam%If(Title = "Windowsタスクマネージャー"){WinClose、ahk_id%lParam%; 実行、Calc.exe; 代わりは } } }
実験2:
シェルメッセージをフックすると、最後のアクティブウィンドウを追跡する確実な方法が提供されます。参照:最後のアクティブウィンドウを取得する方法は?by r0lZ次のスクリプトは、アクティブウィンドウのTopMost / TopLevelスタイル(Always on Top On / OFF)を切り替えます。
コード:
持続的
Menu、Tray、NoStandard Menu、Tray、Add、Toggle AOT、ToggleAOT Menu、Tray、Add、Menu、Tray、Add、Reload、ExitScript Menu、Tray、Add、Exit、ExitScript Menu、Tray、Tip、Toggle AOT Menu、Tray 、デフォルト、AOTの切り替え
Gui + LastFound DllCall( "RegisterShellHookWindow"、UInt、WinExist())MsgNum:= DllCall( "RegisterWindowMessage"、Str、 "SHELLHOOK")OnMessage(MsgNum、 "ShellMessage")LastActiveWindowID:= WinActive( "A")
戻る ; //自動実行セクションの終了//
ShellMessage(wParam、lParam){グローバルLastActiveWindowID If(wParam = 4 And WinExist( "ahk_id" lParam)){; HSHELL_WINDOWACTIVATED = 4 LastActiveWindowID:=lParam}}
ToggleAOT:WinSet、AlwaysOnTop、Toggle、ahk_id%LastActiveWindowID%戻り値
ExitScript:DllCall( "DeregisterShellHookWindow"、UInt、hWnd); 冗長だと思います!IfEqual、A_ThisMenuItem、Reload、Reload ExitApp Return
スクリプトを実行します。ターゲットウィンドウをクリックしてフォーカスします。スクリプトトレイアイコンをダブルクリックします。ターゲットウィンドウは、TopMostスタイルとTopLevelスタイルの間で切り替えられます。
実験3:
Logitechマルチメディアキーボードを持っていますが、付属のソフトウェアをインストールしていません。私は、VOLUME_UP / DN/MUTEキーをホットキーとして使用してSoundGet/SoundSetコマンドで調整をトリガーする独自のOSDスクリプトを使用していました。
マルチメディアキーを押すたびにシェルに通知(HSHELL_APPCOMMAND)されることがわかりました。lParamのHiWordには、押されたMMキーの値が含まれています。そのため、ボリューム変更OSDスクリプトを変更して、HotKeysまたはSoundSetコマンドなしで機能するようにしました。
コード:Gui、Color、FFFFFF Gui、-Caption + Border + AlwaysOnTop + ToolWindow + LastFound
hWnd:= WinExist()、DllCall( "RegisterShellHookWindow"、UInt、hWnd)MsgNum:= DllCall( "RegisterWindowMessage"、Str、 "SHELLHOOK")OnMessage(MsgNum、 "ShellMessage")
Gui、Add、Picture、x5 y5 w32 h32 Icon4 vIcon1、SndVol32.exe Gui、Add、Picture、x5 y5 w32 h32 Icon5 vIcon2、SndVol32.exe Loop、25 Gui、Add、Text、x + 3 w5 h32 Hidden Border vText% A_Index%0x4;
戻る ; //自動実行セクションの終了//
ShellMessage(wParam、lParam){If(wParam = 12 AND((lParam >> 16)> = 8 OR(lParam >> 16)<= 10)){Gui、Show SoundGet、Volume、MASTER、VOLUME SoundGet、Mute、 、 無音
Loop, 25
IfLessOrEqual, A_Index, % Round(Volume/4), GuiControl, Show, Text%A_Index%
Else GuiControl, Hide, Text%A_Index%
IfEqual, Mute, On, GuiControl, Hide, Icon2
Else GuiControl, Show, Icon2
SetTimer, GuiEscape, 1234
} }
GuiEscape:SetTimer、GuiEscape、OFF Gui、Hide
簡単に言うと、wParamが12(HSHELL_APPCOMMAND)の場合、lParamのHiWordには次の定数のいずれかが含まれます。
* APPCOMMAND_BROWSER_BACKWARD = 1
APPCOMMAND_BROWSER_FORWARD = 2 APPCOMMAND_BROWSER_REFRESH = 3 APPCOMMAND_BROWSER_STOP = 4 APPCOMMAND_BROWSER_SEARCH = 5 APPCOMMAND_BROWSER_FAVORITES = 6 APPCOMMAND_BROWSER_HOME = 7 APPCOMMAND_VOLUME_MUTE = 8 APPCOMMAND_VOLUME_DOWN = 9 APPCOMMAND_VOLUME_UP = 10 APPCOMMAND_MEDIA_NEXTTRACK = 11 APPCOMMAND_MEDIA_PREVIOUSTRACK = 12 APPCOMMAND_MEDIA_STOP = 13 APPCOMMAND_MEDIA_PLAY_PAUSE = 14 APPCOMMAND_LAUNCH_MAIL = 15 APPCOMMAND_LAUNCH_MEDIA_SELECT = 16 APPCOMMAND_LAUNCH_APP1 = 17 APPCOMMAND_LAUNCH_APP2 = 18 APPCOMMAND_BASS_DOWN = 19 APPCOMMAND_BASS_BOOST = 20 APPCOMMAND_BASS_UP = 21 APPCOMMAND_TREBLE_DOWN = 22 APPCOMMAND_TREBLE_UP = 23 APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24 APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25 APPCOMMAND_MICROPHONE_VOLUME_UP = 26 APPCOMMAND_HELP = 27 APPCOMMAND_FIND = 28 APPCOMMAND_NEW = 29 APPCOMMAND_OPEN = 30 APPCOMMAND_CLOSE =31 APPCOMMAND_SAVE = 32 APPCOMMAND_PRINT = 33 APPCOMMAND_UNDO = 34 APPCOMMAND_REDO = 35 APPCOMMAND_COPY = 36 APPCOMMAND_CUT = 37 APPCOMMAND_PASTE = 38 APPCOMMAND_REPLY_TO_MAIL = 39 APPCOMMAND_FORWARD_MAIL = 40 APPCOMMAND_SEND_MAIL = 41 APPCOMMAND_SPELL_CHECK = 42 APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43 APPCOMMAND_MIC_ON_OFF_TOGGLE = 44 APPCOMMAND_CORRECTION_LIST = 45
実験4:
メッセージを研究して理解しようとしている間、私はシェルによって受信されているメッセージを監視するためにこの粗雑なシェルスパイを書きました:
コード:
持続的
メニュー、トレイ、メニューの追加、トレイ、追加、&Show、GuiShowメニュー、トレイ、デフォルト、&Show Gui、フォント、s9、Courier New
Gui + ToolWindow + AlwaysOnTop + Resize + LastFound hWnd:= WinExist()DllCall( "RegisterShellHookWindow"、UInt、hWnd)MsgNum:= DllCall( "RegisterWindowMessage"、Str、 "SHELLHOOK")OnMessage(MsgNum、 "ShellMessages")
Gui、Add、Edit、w512 h512 vMsgs hwndEditC + ReadOnly Gui、Show、x10 y10、Shell Spy
MsgNames =(HSHELL_WINDOWCREATED HSHELL_WINDOWDESTROYED HSHELL_ACTIVATESHELLWINDOW HSHELL_WINDOWACTIVATED HSHELL_GETMINRECT HSHELL_REDRAW HSHELL_TASKMAN HSHELL_LANGUAGE HSHELL_SYSMENU HSHELL_ENDTASK HSHELL_ACCESSIBILITYSTATE HSHELL_APPCOMMAND HSHELL_WINDOWREPLACED HSHELL_WINDOWREPLACING HSHELL_HIGHBIT HSHELL_FLASH HSHELL_RUDEAPPACTIVATED)
AppCommands =(APPCOMMAND_BROWSER_BACKWARD = 1 APPCOMMAND_BROWSER_FORWARD = 2 APPCOMMAND_BROWSER_REFRESH = 3 APPCOMMAND_BROWSER_STOP = 4 APPCOMMAND_BROWSER_SEARCH = 5 APPCOMMAND_BROWSER_FAVORITES = 6 APPCOMMAND_BROWSER_HOME = 7 APPCOMMAND_VOLUME_MUTE = 8 APPCOMMAND_VOLUME_DOWN = 9 APPCOMMAND_VOLUME_UP = 10 APPCOMMAND_MEDIA_NEXTTRACK = 11 APPCOMMAND_MEDIA_PREVIOUSTRACK = 12 APPCOMMAND_MEDIA_STOP = 13 APPCOMMAND_MEDIA_PLAY_PAUSE = 14 APPCOMMAND_LAUNCH_MAIL = 15 APPCOMMAND_LAUNCH_MEDIA_SELECT = 16 APPCOMMAND_LAUNCH_APP1 = 17 APPCOMMAND_LAUNCH_APP2 = 18 APPCOMMAND_BASS_DOWN = 19 APPCOMMAND_BASS_BOOST = 20 APPCOMMAND_BASS_UP = 21 APPCOMMAND_TREBLE_DOWN = 22 APPCOMMAND_TREBLE_UP = 23 APPCOMMAND_MICROPHONE_VOLUME_MUTE = 24 APPCOMMAND_MICROPHONE_VOLUME_DOWN = 25 APPCOMMAND_MICROPHONE_VOLUME_UP = 26 APPCOMMAND_HELP = 27 APPCOMMAND_FIND = 28 APPCOMMAND_NEW= 29 APPCOMMAND_OPEN = 30 APPCOMMAND_CLOSE = 31 APPCOMMAND_SAVE = 32 APPCOMMAND_PRINT = 33 APPCOMMAND_UNDO = 34 APPCOMMAND_REDO = 35 APPCOMMAND_COPY = 36 APPCOMMAND_CUT = 37 APPCOMMAND_PASTE = 38 APPCOMMAND_REPLY_TO_MAIL = 39 APPCOMMAND_FORWARD_MAIL = 40 APPCOMMAND_SEND_MAIL = 41 APPCOMMAND_SPELL_CHECK = 42 APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE = 43 APPCOMMAND_MIC_ON_OFF_TOGGLE = 44 APPCOMMAND_CORRECTION_LIST = 45 ) 戻る45)戻る45)戻る
ShellMessages(wP、lP){Global EditC Global mVal:= lP GuiControlGet、Msgs Routine:= GetMessageName(wP)IfEqual、Routine ,, SetEnv、Routine、UNKNOWN GuiControl ,, Msgs、%Msgs " n
n" Routine "[" wP " ] "If IsLabel(Routine)GoSub、%Routine%ControlSend ,, ^ {End}、ahk_id%EditC%}
GetMessageName(FieldN = 0){グローバルMsgNamesループ、解析、MsgNames、 `n IfEqual、A_Index、%FieldN%、Return、A_LoopField}
GetAppCommand(FieldN = 0){グローバルAppCommandsループ、解析、AppCommands、 `n IfEqual、A_Index、%FieldN%、Return、A_LoopField}
不明:HSHELL_WINDOWCREATED:HSHELL_WINDOWACTIVATED:HSHELL_WINDOWDESTROYED:HSHELL_REDRAW:HSHELL_FLASH:HSHELL_ENDTASK:HSHELL_WINDOWREPLACING:HSHELL_WINDOWREPLACED:
HSHELL_RUDEAPPACTIVATED
WinGetTitle、Title、ahk_id%mVal%WinGetClass、Class、ahk_id%mVal%GuiControlGet、Msgs GuiControl 、、 Msgs、%Msgs " n
nhWnd t: " WinExist("ahk_id" mVal) "
nTitle t: " Title "
nClass`t:"クラス
戻る
HSHELL_GETMINRECT:戻る
HSHELL_APPCOMMAND:GuiControlGet、Msgs GuiControl 、、 Msgs、%Msgs "//" GetAppCommand(mVal >> 16)Return
GuiClose:Gui、Show、Hide Return
GuiShow:Gui、Show、Return
網羅的ではありませんが、機能を理解するのに役立ちます。
上記のコードを実行した状態で、電卓を実行し、標準モードから科学モードに変更します。電卓ウィンドウが破棄されて再度作成され、ハンドルが変更されていることがわかります。( 私はそれを知りませんでした )
興味深いことに、ウィンドウがタイトルバー/タスクバーボタンを点滅させているときはいつでも、文書化されていない(AFAIK)値0x8006(32774)がシェルによって受信されることがわかりました。次のコードは、点滅しているウィンドウをアクティブにします:(すべての人に機能するかどうかはわかりません):
コード:Gui + LastFound
hWnd:= WinExist()、DllCall( "RegisterShellHookWindow"、UInt、hWnd)MsgNum:= DllCall( "RegisterWindowMessage"、Str、 "SHELLHOOK")OnMessage(MsgNum、 "ShellMessage")
戻る ; //自動実行セクションの終了//
ShellMessage(wParam、lParam){If(wParam = 0x8006); スパイに示されているように、0x8006は32774です。{WinActivate、ahk_id%lParam%}}