過去記事で何度か書いてますが、会社でも自宅でも複数台のPCを運用しているので、MouseWithoutBorders が必須です。さらにキータイプを楽にするために、AutoHotKey も必須。
ところがこの2つは、両方ともキーボードやマウス操作をフックするプログラムなので、あまり相性がよくありません。
MouseWithoutBorders で別の PC(キーボードがつながっていないPC)を操作しているときに、マウスホイールが効かなかったり、こっちの PC を操作していると思ったら、別の PC の操作になっていて、間違えて ALT+F4 で関係ないアプリを閉じちゃったり。
なんとか回避できないものかと考えていたら、MouseWithoutBorders でアクティブではない PC で、AutoHotKey を一時停止させれば…と思い立ちました。
■AutoHotKey を Susupend して、メッセージを表示する
結構困ったので、いろいろ調べているうちに思いついたのが、
・操作対象じゃない PC には目立つようにメッセージを表示させる
・操作対象じゃない PC では AutoHotKey を suspend させる
と結構うまくいくことがわかりました。
それがこちらのコード。
。。。おっとぉ!!。
そのままコピペしても動きませんよ。
使い方は、下のメモを読んで
■コード
★――――――――――――――――――――――――――
SetTimer, MouseWithoutBordersTest, 200
;
MouseWithoutBordersTest:
MouseWithoutBordersTest()
MouseWithoutBordersTest() {
static susm := 0 ; 今 Suspend しているかどうか
static susk := 0 ;
CoordMode,Mouse,Screen ; スクリーン座標にしないと場所がわからない
MouseGetPos, MX, MY
if (TestRange(MX, 640, MY, 400) || TestRange(MX, 384, MY, 683) || TestRange(MX, 960, MY, 640)) {
; この上の行は MouseWithoutBorders が切り替わったときにマウスカーソルの位置
; を固定するのを利用しているので、ユーザの環境依存です
if (susm == 1 && A_PriorKey != susk) {
; マウスが所定位置にあっても、状態が変化していたら Suspend 解除
; ・Suspend したときの最後のキー(ALT のはずだけど)
MouseMove, MX+5, MY+5 ; もう引っかからないようにする
Suspend, Off ; Suspend 解除
susm := 0 ; 状態フラグ
susk := 0
Tooltip
} else {
Tooltip, Now Suspending %MX% + %MY% + %susk% : %A_PriorKey%
susm := 1
susk := A_PriorKey ; AutoHotKey が最後に検出したキー
Suspend, On
}
return
} else if (susm == 1) {
; マウス移動で MouseWithoutBorder を切り替えたときにはここに来る
Suspend, Off
Tooltip
susm := 0
susk := 0
}
return
}
TestRange(mx, rx, my, ry) {
if ((Abs(mx - rx) <= 2) and ((Abs(my - ry) <= 2)))
return true
return false
}
――――――――――――――――――――――――――★
■これを使いたい方向けの改造方法
このコードは私の環境に特化しているので、そのままでは多分うときません。
まず、現在の環境を調査する必要があります。
●MouseWithoutBordersの固定位置の取得
Windows SPY (AutoHotKeyに同梱されているアプリ)を立ち上げて、MouseWithoutBorders で PC の切り替えをしてください。
そうすると、"Mouse Position" という項目の "Absolute" という行にマウスの位置が表示されていて、当然ながら、MouseWithoutBorders で他のPCにマウスの移動制御が送られてしまっているので、マウスを動かしても、その値は変わらないはずです。
この位置が、MouseWithoutBorders が操作対象PCを切り替えているときに、マウスを固定している位置です。
それぞれの PC でこれを調査してメモってください。
私の場合は、
PC1: x=640 y=400
PC2: x=384 y=683
PC3: x=960 y=640
でした。
で、これを
if (TestRange(MX, 640, MY, 400) || TestRange(MX, 384, MY, 683) || TestRange(MX, 960, MY, 640)) {
; この上の行は MouseWithoutBorders が切り替わったときにマウスカーソルの位置
; を固定するのを利用しているので、ユーザの環境依存です
の行の数字に置き換えます。
多分、モニタの解像度や接続台数に依存していると思われますので、環境ごとに確認してください。
2台しかPCがなければ3つ目の "|| TestRange(MX, 960, MY, 640)" 部分は不要です。逆に4台以上あるときには、"||" でどんどんつないでいってください。
なお、これは状況によって 1〜2 ピクセルずれることがありますので、判定関数 TestRange にてその範囲内ならOKにしてあります。もし、もっと大きく動くようなら、TestRange 関数内の
if ((Abs(mx - rx) <= 2) and ((Abs(my - ry) <= 2)))
の "2" を大きくしてみてください。判定が甘くなります。
●スクリプトへの組み込み
なるべくキーの定義をしたスクリプトの最初の方に、上で編集したプログラムを貼り付けます。
これで、リロードしてやれば、現在アクティブじゃないPCには、画面のほぼ真ん中あたりに
Suspending ......
とポップアップで表示されるはずです。このときは AutoHotKey は Suspend していますので、AutoHotKey のアイコンは "S" になっているはず。
●反応が鈍い
検出周期を 200ms にしていますので、ちと反応が鈍いな…、という方には、
SetTimer, MouseWithoutBordersTest, 200
の最後の 200 を適当に小さくしてください。反応が早くなります。ただし、それだけ繰り返し処理をすることになるので、CPUリソースは若干多めになるかもしれません。まあ、適当なところで。
■現時点わかっていて放置している不具合
●リモート側のマウスを勝手に動かしてしまう時がある
再現性がないのですが、リモート側にMouseWithoutBordersを切り替えているときに、キーがつながったPCでキー押下をAutoHotKeyが検出してしまうことがあります。
今プログラムでは、なにかキーの辺があると、自分のところに制御が戻ってきたかと思って、マウスを動かしてみるのですが、それがリモート側のPCに伝わっちゃう(制御が戻ってきてない)みたいです。
これは、MouseWithoutBorders の設定を弄っていると治ることが多いです。
Move mouse relatively
Use Key Mappings
あたり。
●戻ってきても自動的にSuspendを解除しないときがある
これも原因がよくわからない。
とりあえずマウスを動かしてやるか、何かのキーを適当に押してやると復旧します。
●ときどき妙…?
ほかにも若干、妙な動きをする時があるのですが、「ん?」と思ってもう一度やると再現しないので放置してあります。
■完璧じゃない
制限事項として、このスクリプトは、MouseWithoutBorders の状態を直接見ているわけではないので、期待通りに動かない場合や、何かの拍子に、Suspend 解除されてしまうことがあります。
逆に、制御を戻しても、Suspend が解除されなかったり、モニタのつけ外しをすると勝手に起動する場合もあります。そのときには、ポップアップの最後の方に書いてあるキー以外のキーを押せば(たとえば、"Alt" って表示されていたら、SHIFT や CTRL)を一度だけタップしてやるか、マウスを動かせば解除されます。
また、今後の MouseWithoutBorders の仕様変更によっては動かなくなることがあります。
まぁ、「使える場面では使える」程度に思っててください。
より完璧な方法をご存知の方は教えてくださいませ。
最後にお約束。
☆――――――――――――――――――――――――――
このプログラムやそれに類する方法によって、あなたの環境や大切なファイルにダメージを与えたとしても、当方は一切責任は負えません。自己責任でお願いします。
――――――――――――――――――――――――――☆