ドロップダウンリストの内容が規定の幅を超えたら内容が全く見えねえじゃねえか問題。
リストに入りうる文字列長が予めわかっていればどうとでもなるが、そうでないなら文字列から長さを計算する必要がある。
計算する上での問題
1.ドロップダウンリストの内容は単一の文字列である
画像の例でいえば、ドロップダウンリストを追加するコマンドは以下のようになっている。
gui, add, DropDownList, , 黄昏よりも昏きもの 血の流れより紅きもの 時の流れに埋もれし 偉大なる汝の名において 我ここに 闇に誓わん 我等が前に立ち塞がりし すべての愚かなるものに 我と汝が力もて 等しく滅びを与えんことを!||闇よりもなお昏きもの 夜よりもなお深きもの 混沌の海にたゆたいし 金色なりし闇の王 我ここに汝に願う 我ここに汝に誓う 我が前に立ち塞がりし すべての愚かなるものに 我と汝が力もて等しく滅びを与えんことを!
全ての要素を合わせて(デリミタを挟んだ)ひとつの文字列になってしまう。よって、まず各要素の文字列長からして素直に取れない。
2. 文字列長は実際の幅ではない
当たり前だが、文字列長は文字数であって物理的?な長さではない。等幅フォントならフォントサイズから計算できるかも知れないが、全角半角が混じるとめんどいというレベルじゃないし、プロポーショナルフォントならどうしようもない。
問題の解決
1. 各要素を配列にも格納する
やり方はまあどこから要素を持ってくるかによるが、まずは各要素をバラバラに扱うために配列に格納するのがはじまりだろう。
別にドロップダウンリストの文字列をStringSplitするんでもいいっちゃいいが、初期選択項目を決めるためにデリミタがひとつだけ二重になってたりしてめんどい。疑似配列の扱いもちょっとめんどいし。
; 呪文を配列に格納
Spells := Object(1,"黄昏よりも昏きもの 血の流れより紅きもの 時の流れに埋もれし 偉大なる汝の名において 我ここに 闇に誓わん 我等が前に立ち塞がりし すべての愚かなるものに 我と汝が力もて 等しく滅びを与えんことを!",2,"闇よりもなお昏きもの 夜よりもなお深きもの 混沌の海にたゆたいし 金色なりし闇の王 我ここに汝に願う 我ここに汝に誓う 我が前に立ち塞がりし すべての愚かなるものに 我と汝が力もて等しく滅びを与えんことを!")
for, index, Spell in Spells
{
If (A_Index = 1)
{
SpellsV .= Spell "|" ; 1つ目の呪文を初期選択項目とする
LongSpell := Spell
}
Else
{
SpellsV .= "|" Spell
If (StrLen(Spell) > StrLen(LongSpell)) ; 現在のLongSpellより長ければLongSpellに代入
LongSpell := Spell
}
}
gui, add, DropDownList, , %SpellsV%
このように、一度配列に格納すれば、各要素のうちもっとも文字列長の長い要素を得ることができる。
2. Text
コントロールを使い、文字列から実際の長さを得る
文字列から実際の長さを得るには、なにかに文字列を入れて測ってみればよい。
ここで、物差しに使うのは、文字列に合わせて拡縮してくれるものでなければいけない。
Wn | 省略時は、一部のコントロールはText引数の内容が収まるように自動設定され、それ以外の場合はフォントサイズの15倍に設定される。
これはまあ、普通にTextコントロールでやるのがよかろう。
コントロールの幅は、GuiControlGetで得ることができる。
スクリプト上で長さを得るのに、実際にGuiを表示する必要はない。
Hidden
オプションで非表示のコントロールとしてもよいし、Show
する前にDestoroy
して、それからドロップダウンリスト等を改めてAdd
してもよい。
; 最長呪文の表示に必要な幅を取得
Gui, Add, Text, vSizer, %LongSpell%
GuiControlGet, LongSpellLen, Pos, Sizer
Gui, Destroy
実装
両方合わせたのが以下のコード。
ドラグスレイブとギガスレイブから選択して詠唱できます。
; 呪文を配列に格納
Spells := Object(1,"黄昏よりも昏きもの 血の流れより紅きもの 時の流れに埋もれし 偉大なる汝の名において 我ここに 闇に誓わん 我等が前に立ち塞がりし すべての愚かなるものに 我と汝が力もて 等しく滅びを与えんことを!",2,"闇よりもなお昏きもの 夜よりもなお深きもの 混沌の海にたゆたいし 金色なりし闇の王 我ここに汝に願う 我ここに汝に誓う 我が前に立ち塞がりし すべての愚かなるものに 我と汝が力もて等しく滅びを与えんことを!")
for, index, Spell in Spells
{
If (A_Index = 1)
{
SpellsV .= Spell "|" ; 1つ目の呪文を初期選択項目とする
LongSpell := Spell
}
Else
{
SpellsV .= "|" Spell
If (StrLen(Spell) > StrLen(LongSpell)) ; 現在のLongSpellより長ければLongSpellに代入
LongSpell := Spell
}
}
; 最長呪文の表示に必要な幅を取得
Gui, Add, Text, vSizer, %LongSpell%
GuiControlGet, LongSpellLen, Pos, Sizer
Gui, Destroy
LongSpellLenW += 25 ; プルダウンボタンの分拡大
gui, add, text, HwndSpellScroll, 詠唱する呪文を選択
gui, add, DropDownList, w%LongSpellLenW% vSpelltoCast, %SpellsV%
gui, add, Button, Default y+30, 詠唱する
gui, Show
WinWaitClose, ahk_id %SpellScroll%
Button詠唱する:
gui, Submit
gui, Destroy
MsgBox, , %A_scriptname%, %SpelltoCast%
Exitapp
GuiClose:
GuiEscape:
gui, Destroy
Exitapp
これで、スレイヤーズだろうがバスタードだろうがネギまだろうがUBWだろうがDies Iraeだろうが、ディスプレイの許す限り適切に表示できます。