AutoHotKeyでウィンドウのタイル配置

以前にもAutoHotKeyカスタマイズネタを書きましたが、私はウィンドウ移動系を多用しています。トリプルモニタの間を瞬時にジャンプさせたり、サイズをフィットさせたり。Windows7からWindowsボタン + ←でディスプレイの左半分にリサイズとかがあるので、幾分か被ってしまっているところもありますが、細かい部分では自分で調整したもののほうが、やはり使いやすいです。今回はその中から一つ、同一アプリケーションのウィンドウを水平に並べる関数を紹介します。水平に並べるって、昔懐かしMDIアプリにはありましたが、タブ全盛の昨今だと結構忘れ去られ……。

OSをWindows7に変更したところ、便利なQTTabBarが動かない。困ったねえ。ファイラー使えば?って話なのですが、エクスプローラーに統合されてる便利さは何にも代え難いものがある。と、いうわけで、なんかもうファイラーに戻る気しないしエクスプローラーのままでいいよぅ。でも、せめて多用するファイル移動をスムーズに行いたい→ウィンドウ複数毎開いたた時にズらすのが面倒くさい→こんなの全自動で並べるべき、人力で毎回やるなんてアホ→AutoHotKeyでスクリプト書きましょう。

;アクティブなアプリケーションと同一種類のウィンドウを水平垂直に並べる(最大4枚まで)
;アクティブウィンドウの左上座標が含まれるモニターに並べる
TileMove()
{
    WinGet, activeWindowID, ID, A
    WinGetPos, x, y, w, h, ahk_id %activeWindowID%
    SysGet, monitorCount, MonitorCount
    Loop, %monitorCount%
    {
        SysGet, m, MonitorWorkArea, %a_index%
        if (mLeft <= x && x <= mRight && mTop <= y && y <= mBottom)
        {
            WinGetClass, activeWindowClass, ahk_id %activeWindowID%
            WinGet, id, list, ahk_class %activeWindowClass%
            Loop, %id%
            {
                w := (mRight - mLeft) / 2
                h := (id > 2) ? (mBottom - mTop) / 2 : mBottom - mTop
                x := (Mod(a_index, 2) == 1) ? mLeft : mLeft + w
                y := (a_index <= 2) ? mTop : mTop + h
 
                StringTrimRight, this_id, id%a_index%, 0
                WinActivate, ahk_id %this_id%
                WinWaitActive, ahk_id %this_id%
                WinMove, ahk_id %this_id%,,%x%, %y%, %w%, %h%
            }
            break
        }
    }
}

AutoHotKeyは三項演算子ないのかよ、クソ!とか思ってたのですが実は普通にあったことが判明。知らんかった。今回ようやく気付いた。で、これは関数の形にしているので、設定ファイルの上のほうにでも張り付けてやって、割り当ては好きなキーを選んでください。私は無変換+Tabに振っています。その場合は「vk1Dsc07B & Tab::TileMove()」になります。

実行するとこんな風に整列します。二枚の場合は縦領域を全部使って平行並べになる。ワンタッチでサクッと出来て、かなり便利だと思います。あ、そういえば全然関係ないのですが、Win7からフォルダの新規作成にCtrl + Shift + nというショートカットキーが振られています。これは嬉しい。今まではQTTabBarのプラグインCreateNewItemButtonを使ってCtrl+Kを振っていたのですが、これでQTTabBarがなくてもやっていけるようになった、かどうかはまだまだ微妙だけど、何とか我慢できる。

つまるところ、Win7はかなりイイ。タスクバー回りも大きく変更が加えられていて、最初は慣れなくて以前の方式に戻そうかと思ったのですが、慣れてくると良く出来てるなーと感心しました。いやー、発売日には憧れの(?)秋葉で並ぶ、をやりたいぐらいに良いですねえ。ドライバも、インストール時に跳ねられるものもVista互換モードで動かすと大抵入るので発売日から入れようと、RCから入れようと、不安なところはない。

Comment (4)

GEN : (09/09 01:31)

こんにちは。このスクリプトとても便利ですね。自分でスクリプトが書けない人間なのでありがたく使わせてもらっています。
ただデュアルモニタと環境下でプライマリとセカンダリモニタ両方にウィンドウを展開できたらもっと便利かなと思いました。それとウィンドウ表示枚数を4枚以上に増やすことはできないでしょうか?

neuecc : (09/10 22:39)

使っていただきありがとうございます。

ウィンドウ枚数は決め打ちで2で割っているところを適当に増やせばいい気がします(かなり前に書いたものなので大分忘れてしまっていまして……)
複数枚での展開は結構大掛かりに変えないとダメそうですねえ。

GEN : (09/13 03:21)

お返事どうもです。google検索しながらなんとか見よう見まねでいじってみましたがどうでしょうか?
ここはおこうするべき、というところはありませんでしょうか?これでセカンダリモニタとプライマリモニタに渡って合計8枚展開できるようになりました。
ただ、プライマリのモニタにウィンドウがある状態でスクリプトを実行するとウィンドウが表示範囲外に配置されてしまいました。
プライマリモニタのX座標が0からはじまっていて、セカンダリモニタのx座標はマイナス値なので
WinGetPos, x, y, w, h, ahk_id %activeWindowID%
if(0<=X)
send #a
#aはウィンドウを移動させるアプリケーションのショートカットですが、
これを追加して、プライマリにウィンドウががある場合は、セカンダリにウィンドウを移動するようにしたんですが、外部アプリを使用してウィンドウを移動せずに、プライマリを起点にして
セカンダリまでウィンドウを展開させる方法は思いつきませんでした。。
というか複数枚に展開させる人なんて普通いないですよね笑 用途があまりにも特殊すぎますね。変なこと聞いてすいませんでした。

F2::
WinGetPos, x, y, w, h, ahk_id %activeWindowID%
if(0<=X)
send #a

SysGet, monitorCount, MonitorCount
Loop, %monitorCount%
{
SysGet,m,MonitorWorkArea
SysGet,m,Monitor, %a_index%
if (mLeft <= x && x <= mRight && mTop <= y && y 2) ? (mBottom - mTop) / 2 : mBottom - mTop
x := (Mod(a_index, 2) == 1) ? mLeft : mLeft + w
y := (a_index <=2) ? mTop : mTop + h
y2 := (a_index <=6 ) ? mTop : mTop + h
x2 := (Mod(a_index, 2) == 1) ? mLeft + w + w : mLeft + w + w + w

if(a_index <= 4)
{
StringTrimRight, this_id, id%a_index%, 0
WinActivate, ahk_id %this_id%
WinWaitActive, ahk_id %this_id%
WinMove, ahk_id %this_id%,,%x%, %y%, %w%, %h%
}
Else
{
StringTrimRight, this_id, id%a_index%, 0
WinActivate, ahk_id %this_id%
WinWaitActive, ahk_id %this_id%
WinMove, ahk_id %this_id%,,%x2%, %y2%, %w%, %h%
}
}
break
}
}
return

GEN : (09/13 03:27)

すいません。スクリプトを書き間違えました。

F2::
WinGetPos, x, y, w, h, ahk_id %activeWindowID%
if(0<=X)
send #a

WinGet, activeWindowID, ID, A
WinGetPos, x, y, w, h, ahk_id %activeWindowID%
SysGet, monitorCount, MonitorCount
Loop, %monitorCount%
{
SysGet,m,MonitorWorkArea
SysGet,m,Monitor, %a_index%
if (mLeft <= x && x <= mRight && mTop <= y && y 2) ? (mBottom - mTop) / 2 : mBottom - mTop
x := (Mod(a_index, 2) == 1) ? mLeft : mLeft + w
y := (a_index <=2) ? mTop : mTop + h
y2 := (a_index <=6 ) ? mTop : mTop + h
x2 := (Mod(a_index, 2) == 1) ? mLeft + w + w : mLeft + w + w + w

if(a_index <= 4)
{
StringTrimRight, this_id, id%a_index%, 0
WinActivate, ahk_id %this_id%
WinWaitActive, ahk_id %this_id%
WinMove, ahk_id %this_id%,,%x%, %y%, %w%, %h%
}
Else
{
StringTrimRight, this_id, id%a_index%, 0
WinActivate, ahk_id %this_id%
WinWaitActive, ahk_id %this_id%
WinMove, ahk_id %this_id%,,%x2%, %y2%, %w%, %h%
}
}
break
}
}
return

Name
WebSite(option)
Comment

Trackback(0) | http://neue.cc/2009/06/20_168.html/trackback

Search/Archive

Category

Profile


Yoshifumi Kawai
Microsoft MVP for Visual Studio and Development Technologies(C#)

April 2011
|
July 2018

Twitter:@neuecc
GitHub:neuecc
ils@neue.cc