rcmdnk's blog
Last update

20171107_ahkguiinput0_200_200

AutoHotkeyのスクリプトで、 GUIウィンドウを使って色々と表示させたり 設定を変えたりする方法について。

Sponsored Links

GUI

AutoHotkeyではスクリプトの中でGUIを呼び出して 色々表示したり値を入力したり色々操作できます。

GUI

簡単なメッセージだけであればMsgboxを使えば簡単に表示できますが、 GUIを使うとかなり色々なことが出来ます。

今回は簡単な表示と特にGUIを使ってスクリプト中で使っている変数を変更する方法について まとめてみます。

簡単なメッセージ表示

simple

gui_simple.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
; Add menus to Tray
Menu, Tray, Add
Menu, Tray, Add, GuiTest

Return

; Gui with simple message
GuiTest:
  Gui, Add, Text, , Simple message!
  Gui, Show
Return

; Destroy Gui instance at close
GuiClose:
  Gui, Destroy
Return

; Assign a as Gui launcher
a::
  Goto, GuiTest
Return

単にテキストを表示するだけのGui。

Guiの表示をラベルの中で指定して メニューから呼び出したり Aで呼び出したり出来るようにしています。

Guiの作成呼び出しはGuiTestのラベルのところですが、

Text を使って Gui, Add, Text, [Option], [Text][Text]を追加できます。 Show で実際に作ったGuiを表示させます。

これだけなら実際には

1
2
3
GuiTest:
  Msgbox, Simple message!
Return

msgbox

だけで十分です。

まあともかくこれと同じ様な事が出来ます。

Showしてウィンドウを閉じるボタンで閉じても Guiのインスタンスは残っているので 色々問題が起こります。

テキスト部分に変数などを使う場合、 最初に作られた状態で固定され、 再び同じAddとかを行っても変化しません。

一方で、下に書く v-label などを設定すると 2回目にGuiを開こうとする時に

Error: The same variable cannot be used for more than one control.

みたいなエラーが出ます。

Addの行を重複して読み込まない様にしてる様に見えて v-labelでは重ねて入れようとしてるみたいで、 ちょっと中身は複雑みたいです。

いずれにしろこの様な混乱を避けるため、閉じた時の動作として GUICloseDestroy ということでインスタンスを削除しています。

これで毎回作って消して、を行っています。

もし永続的に使い続けるウィンドウでメモリとかも気にしないのであれば、 Auto-execute Section (最初のReturn前)で Addなどをして作成し、ラベルでの動作をShowだけにして Destroyもしなければ同じ表示をし続けることは出来ます。

ハイパーリンクの埋め込み

link

gui_hyperlink.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a::
  Gui, Add, Text, , Link!
  Gui, Font, Underline
  Gui, Add, Text, cBlue gMyLink, My GitHub
  Gui, Font, Norm
  Gui, Show
Return

MyLink:
  Run "https://github.com/rcmdnk"
Return

GuiClose:
  Gui, Destroy
Return

Font でアンダーラインを設定し、 My GitHubという表示の青いリンクを作っています。

青はオプションのcBlueで設定しています。

オプションの所のgMyLinkg-label と呼ばれ、 MyLinkというgを取った形のラベル でこの部分を押した時の動作を決める事が出来ます。

MyLinkでは Run を使っていますが、URLを与えるとブラウザで開いてくれます。

ここではここで終わっているので特に意味はありませんが、 一応最後にFontでノーマル(Norm)に戻してあります。

配置間隔や横並びにする方法

place

gui_place.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a::
  Gui, Add, Text, , Text1
  Gui, Add, Text, CRed, Text2
  Gui, Add, Text, Y+0, Text3
  Gui, Add, Text, X+10, Text4
  Gui, Add, Text, , Text5
  Gui, Add, Text, xm W100 Border, Text6
  Gui, Add, Text, X+0, Text7
  Gui, Add, Text, xm W100 Center Border, Text8
  Gui, Show
Return

GuiClose:
  Gui, Destroy
Return

オプションの所にXnX+nなどと書くことで 表示位置を設定したり、HnWnなどで 高さや幅を設定できます。

Positioning and Sizing of Controls

XnYnはウィンドウの左端、上端からのnピクセルの距離に置く設定。 この際マージンは考慮されず、X0とかすると 通常の表示より左側に表示されます。

マージンを考慮した位置設定にはxm+nとするとマージンを考慮した位置に出来ます。 (xm+0で通常の表示と同じ。)

X+nY+nは前の項目の右端、下端からの距離になります。

上の例では Y+0で前の項目の真下にくっつけています。

通常、Addしていくと縦に追加されていきますが、 X+nを指定すると前の項目の右側に追加されます。

この時、次の項目をそのまま足すと この最後の項目のxのスタート位置を基準にして配置されるので 全体的に右に寄ってしまいます。

それを直すために次の項目ではxm(xm+0と同様)を使って 通常マージン状態の左端に寄せています。

また、Text7ではオプションでCenterを使って文字列を中寄せしています。 (Leftがデフォルトで左寄せ、右寄せにしたかったらRight。)

これらはText以外にもButtonなどでも基本的に同じようにAddのオプションとして使います。

ウィンドウの表示設定

window

gui_window.ahk
1
2
3
4
5
6
7
8
9
a::
  Gui, -MinimizeBox +Resize
  Gui, Add, Text, , Window view settings!
  Gui, Show, W500, Gui Window View
Return

GuiClose:
  Gui, Destroy
Return

最初の引数に+/-を付けてオプションを書くことで 表示のあれこれを決められます。 ここでは最小化ボタンの無効化とリサイズの有効化(最大化ボタンの有効化含む) を行っています。 (それぞれ初期値では最小化ボタンは有効、リサイズは無効。)

ちなみに最小化とリサイズの両方を無効化すると両方共のボタンが消えます。 (どちらか一方が有効だと無効な方は単にグレーアウトして押せなくなるだけ。)

Showでは次の引数でウィンドウの大きさ等を決められ、 その次にタイトルを入れられます。(タイトル無しならスクリプトの名前がタイトルになります。)

タイトルバーの左端にアイコンが表示されますが、これは トレイアイコンと同じなのでGuiコマンドではなく

1
Menu, Tray, Icon, % A_LineFile . "\..\myTray.ico"

と言った感じでトレイアイコンを変更するとそのアイコンがGuiウィンドウにも表示されます。

ボタンの設置

button

gui_button.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
a::
  Gui, Add, Text, , Buttons!
  Gui, Add, Button, gMyOK W100 X25 Default ,OK
  Gui, Add, Button, W100 X+0, Cancel
  Gui, Show, W250, Button test
Return

MyOK:
  Msgbox, OK!
  Gui, Destroy
Return

ButtonCancel:
  Msgbox, Cancel!
  Gui, Destroy
Return

GuiClose:
  Gui, Destroy
Return

AddButton を与えるとボタンを設置できます。

ここではOKCancelボタンを設置しています。

4つ目の最後の引数がボタンに表示されるテキストです。

3つ目の引数のオプションののところでは W100 X25等は幅位置設定。 Cannelの方のX+0で横並びに。

オプションの所のgMyOKg-labelMyOKというラベルを張っています。

もしg-labelが設定されない場合は 最後のテキストを用いてButtonCancelというラベルが 自動で付きます。

Defaultオプションは表示した時にそのボタンを選択した状態にするためのオプションです。 (何もせずにReturnとか押すとそのボタンが押されることになる。)

値の入力、変更

input0

gui_input.ahk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
MyText := "My Text"
MyRadio1 := 1
MyRadio2 := 0
MyRadio3 := 0
MyCheckBox := 1
MyCount := 0
MyDropDown := ""
MyComboBox := ""
MyListBox := ""
MyHotkey := ""
MyMonthCal := 20151031103040
MyDateTime := 20151031103040
Return

a::
  Gui, Add, Text, , Settings

  Gui, Add, Edit, W200 vMyText, %MyText%

  ;if(MyRadio1 == 1){
  ;  Gui, Add, Radio, Group vMyRadio1 Checked, Radio1
  ;  Gui, Add, Radio, x+0 vMyRadio2, Radio2
  ;  Gui, Add, Radio, x+0 vMyRadio3, Radio3
  ;}else if(MyRadio2 == 1){
  ;  Gui, Add, Radio, Group vMyRadio1, Radio1
  ;  Gui, Add, Radio, x+0 vMyRadio2 Checked, Radio2
  ;  Gui, Add, Radio, x+0 vMyRadio3, Radio3
  ;}else{
  ;  Gui, Add, Radio, vMyRadio1 Group, Radio1
  ;  Gui, Add, Radio, x+0 vMyRadio2, Radio2
  ;  Gui, Add, Radio, x+0 vMyRadio3 Checked, Radio3
  ;}
  Gui, Add, Radio, Group vMyRadio1, Radio1
  Gui, Add, Radio, x+0 vMyRadio2, Radio2
  Gui, Add, Radio, x+0 vMyRadio3, Radio3
  if(MyRadio1 == 1){
    GuiControl, , MyRadio1, 1
  }else if(MyRadio2 == 1){
    GuiControl, , MyRadio2, 1
  }else{
    GuiControl, , MyRadio3, 1
  }

  ;if(MyCheckBox == 1){
  ;  Gui, Add, Checkbox, xm vMyCheckBox Checked, My CheckBox
  ;}else{
  ;  Gui, Add, Checkbox, xm vMyCheckBox, My CheckBox
  ;}
  Gui, Add, Checkbox, xm vMyCheckBox, My CheckBox
  if(MyCheckBox == 1){
    GuiControl, , MyCheckBox, 1
  }

  Gui, Add, Text, , My Count
  Gui, Add, Edit
  Gui, Add, UpDown, vMyCount Range0-10, %MyCount%

  Gui, Add, Text, , My DropDownList
  ;ddn := 0
  ;if(MyDropDown == "Item1"){
  ;  ddn := 1
  ;}else if(MyDropDown == "Item2"){
  ;  ddn := 2
  ;}else if(MyDropDown == "Item3"){
  ;  ddn := 3
  ;}
  ;Gui, Add, DropDownList, vMyDropDown Choose%ddn%, Item1|Item2|Item3
  Gui, Add, DropDownList, vMyDropDown, Item1|Item2|Item3
  GuiControl, ChooseString, MyDropDown, %MyDropDown%

  Gui, Add, Text, , My ComboBox
  ;Gui, Add, ComboBox, vMyComboBox, %MyComboBox%||Item1|Item2|Item3
  Gui, Add, ComboBox, vMyComboBox, Item1|Item2|Item3
  GuiControl, Text, MyComboBox, %MyComboBox%

  Gui, Add, Text, , My ListBox
  ;lbn := 0
  ;if(MyListBox == "Item1"){
  ;  lbn := 1
  ;}else if(MyListBox == "Item2"){
  ;  lbn := 2
  ;}else if(MyListBox == "Item3"){
  ;  lbn := 3
  ;}
  ;Gui, Add, ListBox, vMyListBox Choose%lbn%, Item1|Item2|Item3
  Gui, Add, ListBox, vMyListBox, Item1|Item2|Item3
  GuiControl, ChooseString, MyListBox, %MyListBox%

  Gui, Add, Text, , My Hotkey
  Gui, Add, Hotkey, vMyHotkey, %MyHotkey%

  Gui, Add, Text, , My DateTime
  Gui, Add, DateTime, vMyDateTime Choose%MyDateTime%, yyyy/MM/dd HH:mm:ss

  Gui, Add, Text, , My MonthCal
  Gui, Add, MonthCal, vMyMonthCal, %MyMonthCal%

  Gui, Add, Button, W100 X25 Default , OK
  Gui, Add, Button, W100 X+0, Cancel
  Gui, Show, , Input Test
Return

ButtonOK:
  Gui, Submit
ButtonCancel:
GuiClose:
  Gui, Destroy
Return

AddText以外に入力アイテムを作って入力した値をスクリプト内に 反映させることが出来ます。

色々なアイテムがありますが、共通の項目としては

1
Gui, Add, Edit, vMyText, %MyText%

このvMyTextというのが v-label と呼ばれる書き方で、 この3番目のオプションを入力する引数のところにv-label を入れるとこのvを取った変数(ここではMyText) に入力された値が入り、以後その値をスクリプト中で使えるようになります。

もともと何か定義している値がある場合、それにvを付けてここに入れれば 値の変更が出来ます。

ただし、入力された直後は反映されず、 Gui, Submitをして初めて値に反映されます。

なので上の例ではOKを押した場合に値を反映、 Cancelした場合やそのまま閉じた場合には値を反映させないようにしています。

補足ですが、AutoHotkeyではラベルに対する動作やキーに対する動作設定をする場合に、 Returnが来る前に他のラベルとかを追加しても、それ以降の命令も前の ラベルへの命令として追加されるので、 ここでは共通のDestroyを最後に持ってきて最初にOKに対してだけ Submitを与える様にしています。

上の例ではv-labelにそのまま初期値として入れてる変数を与えているので、 次に立ち上げた時はその変更が反映された形でちゃんと立ち上がることが確認できます。

input1

追記: 2017/11/12

GuiControlによる後からGuiのパーツを変更する方法を使ってなかったので それを使った方法に書き換えました。 コメントアウトされてるのは以前の方法。

GuiControl

1
GuiControl, Sub-command, ControlID [, Param3]

という使い方で、ControlIDにはv-labelか指定がなければClassNN(Button1の様にGuiの種類+番号(作られた順))、もしくはテキストを指定します。

Sub-commandを空欄にした場合、3番目で指定したGuiControlの内容を Param3で指定します。

Sub-Commandはいくつかありますが、ListBoxなどに対してChoose使うと Param3で指定の番号を選んだ状態にできます。 ChooseStringだとその文字列に前方一致するアイテムを選んだ状態になります。

追記ここまで

以下、上で使っている各アイテムについて。

GUI Control Types

Edit

テキストを入力できる枠を作ります。

4番目の引数を与えると初期値として枠内に最初に値が書かれてる状態になります。

Radio

ラジオボタンを作ります。

4番目の引数はラジオボタンの横に表示されるラベルになります。

複数のアイテムが一固まりのラジオボタン郡になってどれかが選択されてる様な状態になりますが、 このグループはGroupというオプションを与えることで区切ることが出来ます。

1
2
3
4
5
6
Gui, Add, Radio, , Radio1
Gui, Add, Radio, , Radio2
Gui, Add, Radio, , Radio3
Gui, Add, Radio, Group, Radio4
Gui, Add, Radio, , Radio5
Gui, Add, Radio, , Radio6

とすれば、Radio1-3とRadio4-6で別グループになってそれぞれで一つ選べる様な状態になります。

オプションにCheckedを入れるとそれが選択された状態になります。 (後から別なのをCheckedで追加するとそちらが選ばれた状態に変更される。)

v-labelはそれぞれのアイテムにありますが、選択されていれば1、されてなければ0です。 何番目が選択されてる、とかそういう値はありません。

上の例では最初にどれにチェック入れておくか、という所でちょっと無駄な繰り返しな書き方になっていますが、Addしたあとで変更する方法が分からなかったので取り敢えず無理やりやってる感じです。

追記: 2017/11/12

GuiControlを使って後からチェックをいれています。

追記ここまで

CheckBox

チェックボックスを作ります。

4番目の引数はチェックボタンの横に表示されるラベルになります。

オプションにCheckedを入れればチェックが付いた状態、なければ付いてない状態で表示されます。

これもv-labelにはチェックが付いてれば1、なければ0が入ります。

UpDown

数値を上下できる様なカウンターを作ります。

このアイテムはちょっと特殊で、これだけでAddすると 背景が他と同じ状態で数値が表示され、 右側に上下のボタンが付くような状態になってちょっと見づらいです。

UpDownを追加する直前にAdd, Editをすると 数値が入力欄になりキーボード入力でも変更できるようになります。 また背景色が変わるので見やすい。

なのでEditと合わせて使うほうがおすすめです。

4番目の引数を入れると初期値になります。 ない場合には0が最初に表示されます。

オプションにRangeN-Mと書くと上下できる幅がNからMまでになります。 もし、Mの方が小さい数値の場合、上下ボタンの上ボタンで数字が減る様になります。

数値は整数で、負の数字も使えます。

v-labelには表示されている数字が入ります。

ドロップダウン型の選択アイテムを作ります。

4番目の引数は選択項目を|で区切って書きます。

ChooseNでN番目のアイテムを選んだ状態で表示します。(0なら何も選択されてない状態。)

v-labelには選択されたアイテムが入ります。

追記: 2017/11/12

ChooseNの代わりに後からGuiControl, Chooseで該当する文字列のものを初期値として選ぶようにしました。

追記ここまで

ComboBox

DropDownと同じようなアイテムですが、 選択欄がキーボード入力できる様になって リストにない値も入れる事が出来るアイテムです。

4番目の引数はラジオボタンの横に表示されるラベルになります。 4番目の引数は選択項目を|で区切って書きますが、 後ろに||と2つ入れるとそのアイテムが最初に選択された状態になります。 (最後のアイテムを選択状態にする場合にもa|b|c||の様に2つ書く。)

上の例では初期値を一番上に出すような設定にしていますが、 この場合、すでにItem1とかを選んでいたらItem1が2つリストに現れることになりますが、 まあ一番上が現在の値、ということでそれはそれでOKでしょう。

DropDownの方でも同様に毎回最初に一つ現在の値を加えれば (%MyDropDown%|Item1|Item2|Item3の様に)、 常にChoose1にすれば良いのでコードは簡潔を完結にすることが出来ます。

v-labelには選択したり書き込んだ値が入ります。

追記: 2017/11/12

ComboBoxChooseString等が使えますが、それだと該当するアイテムがない場合には 何も選ばれない状態になります。

ComboBoxではアイテムにないものも書き込めるので、そういった場合に Textを使うとどんな文字でも初期値として設定できます。 また、値が選択アイテムの中にあればそれを選んでる様な状態になります。

追記ここまで

ListBox

DropDownと違って常に全てが表示されてる様な所から選ぶ 選択リストアイテムを作ります。

4番目の引数は選択項目を|で区切って書きます。

ChooseNでN番目のアイテムを選んだ状態で表示します。(0なら何も選択されてない状態。)

v-labelには選択されたアイテムが入ります。

これもComboBoxのとこに書いたDropDownの例の様に一番上に現在値を入れることで 初期値の選択を簡潔に書くことも可能です。

追記: 2017/11/12

これもGuiControl, Chooseを使った方法に変更しました。

追記ここまで

Hotkey

Hotkeyを入力できるアイテムを作ります。

アイテム欄をフォーカスして何かキーを押すとそのキーが入力される様なアイテムです。

ShiftCtrlAltなどと同時押しは Shift+Ctrl+Aなどとなります。

Windowsキーは入力できませんでした。 また、EscやTabもだめ。 Deleteキーは入力内容の削除になります。 Enterキーはボタンを押す動作になってしまうので、Defaultボタンがあるとこの欄にフォーカスがあってもボタンを押してしまいます。

4番目の引数は初期値になります。ない場合はなしと(日本語なら)表示されます。

v-labelはなし以外にキーが入力されてればその値、なしの場合は空文字になります。

DateTime

年月日時刻を入力するアイテムを作ります。

右側のドロップダウンボタンを押すとカレンダーが表示されカレンダーから日付を選ぶことも可能です。

4番目の引数には表示フォーマットを書きます。 上の例の様にyyyyとかを使って自分で直接設定する他、 省略するとWindowsの日付と時刻で設定してる日付(短い形式)LongDateと書くと日付(長い形式)Timeと書くと時刻(長い形式)の表示になります。

オプションにChoose20151031103040と書くと2015年10月31日 10:30:40が初期値として表示されます。 Choose201510だけだと2015年10月1日 00:00:00になります。15月とか無い数字にすると1月に直されます。 Choose10とか使えない数字を入れると今の時間が入ります。

Chooseを省略した場合も現在の年月日時刻が入ります。

RangeMin-Maxで入力できる最初と最後の年月日時刻を指定できます。

オプションに1を書くとカレンダー表示のドロップダウンボタンがアップダウンボタンになります。

オプションに2を書くとチェックボタンが左側に表示され、 このチェックボタンが選択されてない場合、日付が書かれていても返り値が空文字になります。

このチェックボタンは初期値は選択された状態ですが、 ChooseNoneをオプションに加えるとチェックが外れた状態になります。

v-labelには年月日時刻の数字を続けて書いたものが帰ります。 2オプションを入れてチェックが外れてる場合には空文字になります。

MonthCal

日付を選択できるカレンダーを作ります。

DateTimeと違い、4番目の引数が初期値で20151031の様な年月日を入れます。 ない場合は今日の日付が初期値になります。

RangeMin-Maxで入力できる最初と最後の年月日時刻を指定できます。

Multiというオプションを入れると複数の日付が選べる様になります。

v-labelには選択した日付が入ります。 Multiオプションが有効な場合で複数の日付を選んだ場合には 20151031-20151105の様にハイフン区切りなものが返ります。

複数のGuiの作成

multi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
a::
  Gui, MyGui1:+Resize
  Gui, MyGui1:Add, Text , , MyGui1
  Gui, MyGui1:Show
Return

MyGui1GuiClose:
  MsgBox, Close MyGui1
  Gui, MyGui1:Destroy
Return

b::
  Gui, MyGui2:+LabelMyWindow +Resize
  Gui, MyGui2:Add, Text , , Gui %NW2%
  Gui, MyGui2:Add, Button, gMyOK, OK
  Gui, MyGui2:Show
Return

MyOK:
  MsgBox, OK @ myok
  Gui, MyGui2:Destroy
Return

MyWindowClose:
  MsgBox, Close Gui MyWindow
  Gui, MyGui2:Destroy
Return

これまでの例では Gui, Addとかやってましたが、 これをする限りずっと同じウィンドウにアイテムが追加されていきます。

この何も付いてないGuiは名無しのGuiになりますが、 複数のGuiを作りたい時は名前を付けて作ってあげれば別のウィンドウを作ったり出来ます。

名前は最初に与えるサブコマンドの前にName:の様に付けることで そのコマンドがその名前のGuiに対するものになります。

名前は文字でも数字でも、また%GuiName%:Addの様に変数で渡す事も出来ます。

また、GuiCloseの様に自動的に作られるラベルがありますが、 名前付きのGuiでは直接名前を付けてNameGuiCloseとするとそのGuiに対するCloseラベルになります。

同様に、Buttonを作った時にラベルを付けないと自動的にButtonOKの様な 表示名にButtonの付いたラベルが割り振られますが、 これも名前付きのGuiではNameButtonOKとなります。

さらに、名前とは別に

1
Gui, 10:+LabelMyWindow

とすると10番目のGuiにMyWindowというラベルを付ける事が出来ます。 +Labelは上のウィンドウの表示設定でも出てきたオプション の1つです。

このラベルを設定すると、GuiCloseMyWindowClose の様に ラベルが前に付いた形になります。

名前付きのGuiでもラベルを設定したらラベルを使ったものが優先されます。

ちょっと注意が必要なのは名前の時はそのまま前に付けてましたが、 ラベルの場合はGuiを消してからラベルを付ける、という点。

名前を変数を使って与えている時にGuiCloseの設定をしようとする場合は %NW1%GuiClose:...の様なラベルの動作指定に変数を使うことは出来ないので Guiのラベルを指定してGuiCloseをラベル付きの名前にして設定する必要があります。

一方、Button等に関してはラベルを設定しても GuiName+Button+ButtonNameのままです。

こちらを変更したい場合は直接

1
Gui, %NW1%:Add, Button , gMyButton, MyButton

の様にボタンにg-labelを使ってラベルを付けます。

SmartGui Creator

GuiをGui上でパーツを貼り付ける様に作れるツールが公開されています。

:: SmartGUI Creator :: - Scripts and Functions - AutoHotkey Community

Sponsored Links
Sponsored Links

« AutoHotkeyでのメニューの追加 AutoHotkeyで設定ファイルの読み書きをする »