[AHK]OFFICEアプリをマウスで横スクロール出来るようにする。

MicrosoftのWORD、EXCEL、PowerPointで横スクロールする時、スクロールバークリックするのめんどいと思ったんで、右クリック+ホイールで水平スクロールするようにしてみました。

AutoHotKeyでやったのはこんな感じ。

;office.ahk
#IfWinActive,ahk_exe WORD.EXE
	RButton & WheelUp::	; Scroll left.
		if(GetKeyState("Ctrl","P")){
			Send,{WheelLeft}
		}
		else{
			Send,{WheelLeft 10}
		}
	Return
	RButton & WheelDown::	; Scroll right.
		if(GetKeyState("Ctrl","P")){
			Send,{WheelRight}
		}
		else{
			Send,{WheelRight 10}
		}
	return
	RButton::Send,{RButton}
#IfWinActive

#IfWinActive,ahk_exe EXCEL.EXE
	RButton & WheelUp::	; Scroll left.
		SetScrollLockState, On
		if(GetKeyState("Ctrl","P")){
			Send {Left}
		}
		else{
			Send {Left 3}
		}
		SetScrollLockState, Off
	Return
	RButton & WheelDown::	; Scroll right.
		SetScrollLockState, On
		if(GetKeyState("Ctrl","P")){
			Send {Right}
		}
		else{
			Send {Right 3}
		}
		SetScrollLockState, Off
	return
	RButton::Send,{RButton}
#IfWinActive

#IfWinActive,ahk_exe POWERPNT.EXE
	;AutoHotKeyを管理者で実行してる場合、ログインユーザーとして実行する必要があるので、ShellRunを使う。
	RButton & WheelUp::	; Scroll left.
		if(GetKeyState("Ctrl","P")){
			ShellRun("ScrollH.js",-20)
		}
		else{
			ShellRun("ScrollH.js",-40)
		}
	Return
	RButton & WheelDown::	; Scroll right.
		if(GetKeyState("Ctrl","P")){
			ShellRun("ScrollH.js",20)
		}
		else{
			ShellRun("ScrollH.js",40)
		}
	return
	RButton::Send,{RButton}
#IfWinActive

; SHELLRUN
; ログインユーザーとして実行
;If the script is not elevated, relaunch as administrator and kill current instance
;if not A_IsAdmin
;{
;   Run *RunAs "%A_ScriptFullPath%"
;   ExitApp
;}
;Parameters for ShellRun
;1 application to launch
;2 command line parameters
;3 working directory for the new process
;4 "Verb" (For example, pass "RunAs" to run as administrator)
;5 Suggestion to the application about how to show its window - see the msdn link for possible values
ShellRun(prms*)
{
    shellWindows := ComObjCreate("{9BA05972-F6A8-11CF-A442-00A0C90A8F39}")
    desktop := shellWindows.Item(ComObj(19, 8)) ; VT_UI4, SCW_DESKTOP                

    ; Retrieve top-level browser object.
    if ptlb := ComObjQuery(desktop
        , "{4C96BE40-915C-11CF-99D3-00AA004AE837}"  ; SID_STopLevelBrowser
        , "{000214E2-0000-0000-C000-000000000046}") ; IID_IShellBrowser
    {
        ; IShellBrowser.QueryActiveShellView -> IShellView
        if DllCall(NumGet(NumGet(ptlb+0)+15*A_PtrSize), "ptr", ptlb, "ptr*", psv:=0) = 0
        {
            ; Define IID_IDispatch.
            VarSetCapacity(IID_IDispatch, 16)
            NumPut(0x46000000000000C0, NumPut(0x20400, IID_IDispatch, "int64"), "int64")

            ; IShellView.GetItemObject -> IDispatch (object which implements IShellFolderViewDual)
            DllCall(NumGet(NumGet(psv+0)+15*A_PtrSize), "ptr", psv
                , "uint", 0, "ptr", &IID_IDispatch, "ptr*", pdisp:=0)

            ; Get Shell object.
            shell := ComObj(9,pdisp,1).Application

            ; IShellDispatch2.ShellExecute
            shell.ShellExecute(prms*)

            ObjRelease(psv)
        }
        ObjRelease(ptlb)
    }
}
//ScrollH.js
var Lmove=0
var Rmove=WScript.Arguments(0)
if(Rmove<0){
	Lmove=-Rmove
	Rmove=0
}
var obj = WScript.CreateObject("PowerPoint.Application");
obj.ActiveWindow.SmallScroll(0,0,Rmove,Lmove);

PowerPointの横スクロールは、ScrollH.jsという、左右の移動量を渡すと動くスクリプトを、ShellRunで呼び出す形で実装しました。

最初は、直接COMオブジェクトをAHK上で作って動かそうとしてみたんですが、AHKを管理者として実行してるからか、AHK上でOFFICEのCOMオブジェクトが上手く作れませんでした。

(もしかしたら、64bit版のAHKを使ってるせいもあるかも。32bitのCOMを64bitで使うときはDLLサロゲートの設定とかいうものがいるらしいと聞くんで。まあ、wscriptをShellRunで叩くようにするとこの辺のめんどい話も全部なくなってそう。)

 

後、縦スクロールは、Alt+スクロールでPageUpとPageDownするように設定してるで、水平スクロールは、Ctrl有り無しでスクロール量が切り替わるようにもしてみました。

使い勝手としては非常に便利になりました。

PowerPointとかページの横に絵を大きく作っておいて、画像としてコピーしてサイズ調整とかよくやるんですけど、その時に左右にスクロールするのが地味にめんどくさかったんで。

 

2021/08/02, 追記

AHK64bit版を使ってたんで、COMオブジェクトを簡単に引っ張れなかったけど、64bitでなければいけない用途も特になかったんで、AHKを32bit版にして、COMオブジェクトをAHKから直接呼ぶようにしてみることにした。コードは下記のようにしてみた。

;AHKでCOMオブジェクトを直接生成
RButton & WheelDown::	; Scroll right.
	ppobj:= ComObjCreate("PowerPoint.Application")
	ppobj.ActiveWindow.SmallScroll(0,0,40,0)
return

これで、簡単に呼べるかと思ったんだけど、PowerPointとAHKの管理者権限と非管理者の組み合わせで動作が異なっていた。

以下が試してみた内容。

AutoHotkeyU32_UIA.exeは、非管理者として実行しても、管理者権限で実行されてるアプリを操作できるようになるexe。AHKを管理者権限で実行しなくていいので、管理者権限のアプリを操作したいなら、こっち使った方がセキュリティ的に良さげ。

インストール時に、オプションの”Add ‘Run with UI Access’ to context menus”をオンにしてインストールすると、AutoHotkeyU32_UIA.exeというのがインストールされている。.ahkファイルを右クリックすると、Run with UI Accessというコンテキストメニューが出来ているので、こちらから実行することもできる。チェック入れずにインストールしてたら、インストールディレクトリに入ってる、Installer.ahkを実行すると、インストール設定の変更が出来る。

結論から言うと、AHKを管理者で起動しても、PowerPointが非管理者として起動されていた場合、AHKで直接COMオブジェクトを生成することが出来なかった。また、AHKを非管理者で起動して、ShellRun(非管理者として実行)とRun *RunAs(管理者として実行)を試してみると、PowerPointが管理者ならCOMオブジェクトを生成しようとする実行ファイルも管理者、PowerPointが非管理者として実行されていたら、COMオブジェクトを生成しようとする実行ファイルも非管理者となっていないとうまく実行出来ないようだった。

PowerPointの実行状態による切り分けが必要になりそう。。。

実行ファイルの権限の状態はどうやって取得したらいいんだろ。。。

 

関連記事

[AHK]Outlookの送信済みアイテムフォルダーに移動するショートカットキーを作る。

 

 

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です