脳内では水木兄ぃの歌声が聞こえてきそうです。
それはさておき、PowerShellでGUIのモックアップが簡単にできるツールを作りました。
Formをグリッドに見立ててDSLなCSVでコントロールを配置します。
動くスクリプトをすばやく手軽に生成可能です。
慣れたら5分でコントロールを10個くらい配置できる(!)と思います。
サンプル
生成される画面はこんな感じです。
6行のCSVから92行(空行込み)のスクリプトが生成されました。
記法
-
コントロール_名前
スクリプト上で$buttonOKとするなら、button_OKとします。 -
コントロール_名前_キャプション
コントロール上に名前とは違う文字を表示したい場合、アンダースコアに続けてキャプションを記載します。button_Cancel_取消 等。
ListViewに限りキャプションを|で区切って項目を列挙できます。 -
コントロール:横倍率/縦倍率_名前
コントロールのサイズは一律ですが、整数倍でサイズ指定も可能です。横方向にだけ伸ばしたい場合、textBox:2/1_Name 等。さらに右にコントロールを配置するなら空項目(カンマのみ)の挿入を忘れずに! -
省略型
よく使うコントロールには省略型も用意しました。B_OKでも大丈夫。(サンプルはこればっかり。)
省略型 | コントロール |
---|---|
B | button |
L | label |
M | comboBox |
R | radioButton |
T | textBox |
V | listView |
X | checkBox |
使い方
- CSVを前述の記法で作成します。(BOM付UTF-8 括り文字なし)
- PowerShellやVS Codeのコンソール等で生成します。
>./buildForm.ps1 form.csv | out-file -encoding:utf8 form.ps1
- 生成したスクリプトを実行
>./form.ps1
スクリプト本体
# コントロールサイズ
$cWidth = 70
$cHeight = 25
# コントロール間のマージン
$xMar = 5
$yMar = 5
# 画面サイズ
$formWidth = 0
$formHeight = 0
# 画面のマージン
$formMarx = 15
$formMary = 15
# コントロール配置座標
$xPos = $xMar + $formMarx
$yPos = $yMar + $formMary
$tmpArr = $Args[0].split(".")
$winTitle = $tmpArr[0]
#windowsフォーム
Write-Output ("Add-Type -AssemblyName System.Windows.Forms")
Write-Output ("Add-Type -AssemblyName System.Drawing")
Write-Output ("")
#フォームの作成"
Write-Output ("`$form = New-Object System.Windows.Forms.Form")
Write-Output ("`$form.Text = `"$winTitle`"")
Write-Output ("")
$row = 0
foreach($line in (Get-Content $Args[0])){
# CSVをカンマで分割
$ctrls = $line.split(",")
$xPos = $xMar + $formMarx
foreach($ctrl in $ctrls){
if ($ctrl -ne ""){
# 項目をアンダースコアで分割
$ctrlInfo = $ctrl.Split("_")
# コントロールサイズ指定の反映
$setWidth = $cWidth
$setHeight = $cHeight
# ex) T:2/1 テキストボックスのサイズをX方向に2倍、Y方向に1倍
$tmpArr = $ctrlInfo[0].Split(":")
$ctrlCode = $tmpArr[0]
if ($tmpArr.Length -eq 1){
} else {
# コントロールサイズ倍率の反映
if ($tmpArr[1].contains("/")){
$sizeArr = $tmpArr[1].Split("/")
$setWidth = [int]$sizeArr[0] * ($cWidth + $xMar) - $xMar
$setHeight = [int]$sizeArr[1] * ($cHeight + $yMar) - $yMar
}
}
# コントロールタイプの設定
# 一致しなければ指定されたタイプをそのまま使用
switch ($ctrlCode) {
"L"{$ctrlType="label"}
"T"{$ctrlType="textBox"}
"B"{$ctrlType="button"}
"R"{$ctrlType="radioButton"}
"X"{$ctrlType="checkBox"}
"M"{$ctrlType="comboBox"}
"V"{$ctrlType="listView"}
Default {$ctrlType=$ctrlCode}
}
# コントロール名の設定
$ctrlName=$ctrlInfo[1]
# コントロールのキャプション(Textプロパティ)の設定
# 指定がなければコントロール名をコピー
# ex) L_OK_了解 :了解
# L_OK :OK
if ($ctrlInfo.Length -eq 2){
$ctrlCaption = $ctrlName
}else{
$ctrlCaption = $ctrlInfo[2]
}
$ctrlID = $ctrlType + $ctrlName
# コントロール生成
Write-Output ("`${0} = New-Object System.Windows.Forms.{1}" -f $ctrlID,$ctrlType)
Write-Output ("`${0}.Location = New-Object System.Drawing.Point({1},{2})" -f $ctrlID, $xPos, $yPos)
Write-Output ("`${0}.Size = New-Object System.Drawing.Size({1},{2})" -f $ctrlID, $setWidth, $setHeight)
# コントロール個別の処理
switch -Regex ($ctrlType){
"label|button|radioButton|checkBox"{
Write-Output ("`${0}.Text = `"{1}`"" -f $ctrlID, $ctrlCaption)
if ($ctrlType -eq "label"){
Write-Output ("`${0}.TextAlign = `"MiddleLeft`"" -f $ctrlID)
}
}
"listView"{
Write-Output ("`${0}.View = `"Details`"" -f $ctrlID)
# キャプションを|で区切り、列名として追加
foreach($li in ($ctrlCaption.split("|"))){
Write-Output ("`${0}.Columns.Add(`"{1}`",{2})" -f $ctrlID, $li,$cWidth)
}
}
"textBox"{
if ($setHeight -gt $cHeight){
Write-Output ("`${0}.Multiline = `$True" -f $ctrlID)
}
}
}
# コントロールを画面に追加
Write-Output ("`$Form.controls.Add(`${0})" -f $ctrlID)
Write-Output ("")
}
# コントロールX座標移動
$xPos = $xPos + $setWidth + $xMar
}
#フォーム幅設定
$xPos = $xPos + $xMar + $formMarx
if ($xPos -gt $formWidth){
$formWidth = $xPos
}
# コントロールY座標移動
$yPos = $yPos + $setHeight + $yMar
$row = $row + 1
}
#フォーム高さ設定
$yPos = $yPos + $cHeight + $yMar + $formMary
$formHeight = $yPos
Write-Output ("`$form.Size = New-Object System.Drawing.Size({0},{1})" -f $formWidth,$formHeight)
Write-Output ("`$result = `$form.ShowDialog()")
これでEXCELのない環境でもGUIのツールが使える、みたいな。
2020/6/8 textBoxの高さ変更についてMultiline=$Trueを追加しました。