[AHK]マルチディスプレイだとMouseMoveで正しく移動できないことがあるので対策

AutoHotkey標準のMouseMoveは、直線的に移動できる座標にしか正しく移動できない。

マルチディスプレイで、複雑なスクリーン構成になってると、うまく動かないことが多かったので、対策関数を作成。

ついでに、”center,top”の様な感じで、modeを指定すると、アクティブウィンドウの相対座標の基準を変えて座標指示出来るようにもしてみた。

因みに、sampleは、Ctrl+Shift+aでアクティブウィンドウのタイトルバーの位置にカーソルが行くようになってる。

  

^+a::MouseMove2(0,10,"center,top")

;マルチディスプレイで、マウスの軌跡が直線で移動できない座標には、MouseMoveだと移動できないことがある。
;無理やり移動できるようにした関数を作成。
;ついでに、Window座標の相対指示等にも対応
;mode: マウスが移動する座標の指定方法
;	"": 何も代入しないとモニター全体からの絶対座標
;	"R": 現在のマウス座標からの相対座標となる。
;	windowモード: アクティブウィンドウに対する座標を相対位置で指定可能にする。
;		x_type: "left", "center", "right"
;		y_type: "top", "center", "bottom"
;		という風に指定可能
;	ex)	
;		mode:="center,top": ウィンドウの中央の上を基準にした座標として認識
;		mode:="right,bottom": ウィンドウの右下を基準にした座標として認識
;	また、windowモードの時は、PosX, PosYに1未満の値を設定すると、ウィンドウの比率で座標が指示される。
;	ex) PosX:=0.2なら、PosXはウィンドウの幅の0.2倍の長さとして認識
;n_try: カーソルの移動を試す最大試行回数(defaultは5)
MouseMove2(PosX, PosY, mode:="",speed:=0,n_try:=5){
	if((""==mode) || ("R"==mode)){
		tgtXa:=PosX
		tgtYa:=PosY
		err:=0
		send_mode:=mode
	}
	else{
		StringSplit, modeXYArr, mode, `,
		if(2!=modeXYArr0){
			msgbox, MouseMove2の引数、mode=%mode%は、未定義のモードです。
			return 16
		}
		x_type:=modeXYArr1
		y_type:=modeXYArr2
		err:=GetTgtAPosfromRPos(tgtXa,tgtYa,PosX,PosY,x_type, y_type)
		send_mode:=""
	}
	if(0==err){
		Loop,%n_try%
		{
			MouseMove, tgtXa, tgtYa, speed, %send_mode%
			MouseGetPos,Mx,My
			if(tgtXa==Mx && tgtYa==My){
				break
			}
		}
	}
	return err
}
;x_Rel, y_Relは絶対値が1未満の場合、それぞれ幅と高さの比率に対応する座標を返す。
GetTgtAPosfromRPos(ByRef tgtXa, ByRef tgtYa, x_Rel, y_Rel , x_type:="left", y_type:="top"){
	axRel:=abs(x_Rel)
	ayRel:=abs(y_Rel)
	err:=GetBasePosOfAWin(x_base, y_base,x_type, y_type)
	if(0==err){
		WinGetActiveStats, Title, Width, Height, WinX, WinY
		if(axRel<1){
			x_Rel*=Width
		}
		if(ayRel<1){
			y_Rel*=Height
		}
		tgtXa:=x_base+x_Rel
		tgtYa:=y_base+y_Rel
	}
	return err
}

;アクティブウィンドウの基準座標を取得する。
;基準座標は、x_baseとy_baseに返す。
;返す座標系は、ウィンドウの座標系となる。
;x_type: "left", "center", "right"
;y_type: "top", "center", "bottom"
;x_typeに次のもの以外を代入すると、4
;	left, center
;y_typeに次のもの以外を代入すると、8
;	top, center
;見つからなかったら: 16
;を戻り値として返す。
GetBasePosOfAWin(ByRef x_base, ByRef y_base, x_type, y_type){
	WinGetActiveStats, Title, Width, Height, WinX, WinY
	if("left"==x_type){
		x_base:=0
	}
	else if("center"==x_type){
		x_base:=Width/2
	}
	else if("right"==x_type){
		x_base:=Width
	}
	else{
		msgbox, GetBasePosOfAWinの引数、x_type=%x_type%は、未定義のタイプです。
		return 4
	}
	if("top"==y_type){
		y_base:=0
	}
	else if("center"==y_type){
		y_base:=Height/2
	}
	else if("bottom"==y_type){
		y_base:=Height
	}
	else{
		msgbox, GetBasePosOfAWinの引数、y_type=%y_type%は、未定義のタイプです。
		return 8
	}
	return 0
}

コメントを残す

メールアドレスが公開されることはありません。