6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

(PowerShell) 5分待て。俺がGUIのモックを書いてやる、ビルドフォーーーム!!

Last updated at Posted at 2020-06-03

脳内では水木兄ぃの歌声が聞こえてきそうです。
それはさておき、PowerShellでGUIのモックアップが簡単にできるツールを作りました。

Formをグリッドに見立ててDSLなCSVでコントロールを配置します。
動くスクリプトをすばやく手軽に生成可能です。
慣れたら5分でコントロールを10個くらい配置できる(!)と思います。

サンプル

こんなCSVを書くと
buildForm_CSV.png

生成される画面はこんな感じです。
buildForm_Sample.png
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

スクリプト本体

buildForm.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を追加しました。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?