2015-07-09

PowerShellでユーザーフォームを作る - 基礎編 -

PowerShellでは、ユーザーが独自にフォームを作成することができます。

以前の投稿で、インプットボックスやメッセージボックスをご紹介しましたが、それは非常にシンプルなものであり、使い勝手が良い反面、自由度が低いものでした。

過去の投稿はこちら↓↓
PowerShellでInputBoxを使用する
PowerShellでMessageBoxを使用する


よって今回より数回に分けて、独自のユーザーフォームを作る方法をご紹介していきます。


ユーザーフォーム 1回目は「PowerShellでユーザーフォームを作る - 基礎編 -」です。


<今回の完成品>


下記の例文を実行すると、上記のフォームが表示されます。

インプットボックスとあまり変わらない!といった声が聞こえてきそうですが、まぁ今回は基礎編ですので、どうかお付き合いください。


それでは例文を記述します。



---------ここから-------------------------------------------------------------------------------------
# ユーザーフォームを作る - 基礎編 -

# アセンブリの読み込み
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "入力"
$form.Size = New-Object System.Drawing.Size(260,180)

# OKボタンの設定
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(40,100)
$OKButton.Size = New-Object System.Drawing.Size(75,30)
$OKButton.Text = "OK"
$OKButton.DialogResult = "OK"

# キャンセルボタンの設定
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(130,100)
$CancelButton.Size = New-Object System.Drawing.Size(75,30)
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult = "Cancel"

# ラベルの設定
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,30)
$label.Size = New-Object System.Drawing.Size(250,20)
$label.Text = "好きな言葉を入力してください"

# 入力ボックスの設定
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,70)
$textBox.Size = New-Object System.Drawing.Size(225,50)

# キーとボタンの関係
$form.AcceptButton = $OKButton
$form.CancelButton = $CancelButton

# ボタン等をフォームに追加
$form.Controls.Add($OKButton)
$form.Controls.Add($CancelButton)
$form.Controls.Add($label)
$form.Controls.Add($textBox)

# フォームを表示させ、その結果を受け取る
$result = $form.ShowDialog()

# 結果による処理分岐
if ($result -eq "OK")
{
$x = $textBox.Text
$x
}
---------ここまで-------------------------------------------------------------------------------------

上記内容をコピーし、PowerShell ISEに貼り付けて、実行してみてください。
完成品と同じものが表示されましたか??

それでは少しずつ解説していきます。


**********************************解説*******************************************

# アセンブリの読み込み
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

PowerShellは.Net Frameworkライブラリを使用することを前提として設計されています。
したがって、いくつかのアセンブリは既にロードされているのですが、今回使用するアセンブリはロードされていないものであるため、まず最初にロードを行っています。


# フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "入力"
$form.Size = New-Object System.Drawing.Size(260,180)

ここではフォームのみについて記述しています。
この時点ではまだ空っぽの状態です。
ここにボタンなどを設置していくことになります。
勘のいい方はお気づきと思いますが、Sizeプロパティ($form.Sizeの部分)はフォームの大きさを設定しています。
したがって、(260,180)の部分を変更すれば、自分の好きな大きさに変えることができます。
260は横軸(幅)を、180は縦軸(高さ)を示しています。


# OKボタンの設定
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(40,100)
$OKButton.Size = New-Object System.Drawing.Size(75,30)
$OKButton.Text = "OK"
$OKButton.DialogResult = "OK"

ここではフォーム内に設置するOKボタンについて記述しています。
Locationプロパティ($OKButton.Locationの部分)はフォーム内のボタン左上角の設置位置を指定しています。
Sizeプロパティはボタンの大きさを、Textプロパティはボタンに表示する文字列を設定します。
DialogResultプロパティは、ボタンが押されたときに返す値を指定しています。
ここで指定できるものは決まっており、次のいずれかの列挙子名を指定することができます。

  列挙子名:None, OK, Cancel, Abort, Retry, Ignore, Yes, No

キャンセルボタンについてはOKボタン部分とほぼ同じですので、解説は省略します。


# ラベルの設定
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,30)
$label.Size = New-Object System.Drawing.Size(250,20)
$label.Text = "好きな言葉を入力してください"

ここではフォーム内に設置するラベルについて記述しています。
ラベルというのは要するに文字列です。


# 入力ボックスの設定
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(10,70)
$textBox.Size = New-Object System.Drawing.Size(225,50)

ここではフォーム内に設置する入力ボックス(テキストボックス)について記述しています。
この入力ボックスに入力した文字列が$textBoxに格納されます。


# キーとボタンの関係
$form.AcceptButton = $OKButton
$form.CancelButton = $CancelButton

ここでは、設置したOKボタンとキャンセルボタンをキーボードのEnterキーとEscキーに関連させています。
つまり、Enterキーを押すことはOKボタンを押すことと同じですよ、Escキーを押すことはキャンセルボタンを押すことと同じですよ、と設定しているわけです。


# ボタン等をフォームに追加
$form.Controls.Add($OKButton)
$form.Controls.Add($CancelButton)
$form.Controls.Add($label)
$form.Controls.Add($textBox)

ここでは、これまでに作成したボタンやラベルを、最初に作成した空っぽのフォームに追加しています。
この記述を忘れると、せっかく作ったボタン等が表示されないので注意しましょう。


# フォームを表示させ、その結果を受け取る
$result = $form.ShowDialog()

ここでいよいよフォームを表示させています。(ShowDialogプロパティ)
さらに、フォームの結果(=押されたボタン)を変数に格納しています。


# 結果による処理分岐
if ($result -eq "OK")
{
    $x = $textBox.Text
    $x
}

最後に、押されたボタンによる処理の分岐を行っています。
押されたボタンが「OK」ならば、入力ボックスの内容を変数xに入れ、変数xを出力しています。

***********************************************************************************

少し長くなりましたが、いかがだったでしょうか。


ユーザーフォームの利点はその自由度の高さにあります。

今回は大きさの変更(Sizeプロパティ)や設置位置の変更(Locationプロパティ)についてのみ書きましたが、その他にもフォームの色やボタンの色、ラベルの文字色やフォントサイズ、最大化・最小化ボタンの有無、さらにフォームの透明度などなど、変更できることは多くあります。
自分好みなフォームにしていくと、単調な作業も楽しくなってきますね。


=======================================================================
本投稿に関する疑問や質問には可能な限りお答えさせていただきます。
お気軽にコメントやメールをお送りください。
(リクエストも歓迎します)
メール:tkk-powershell@gmail.com
また、間違いのご指摘・アドバイス等も歓迎いたします。
=======================================================================
Google+、Twitterで更新情報をお届けしています!
ぜひフォローをお願い致します!           
=======================================================================
スポンサーリンク


7 件のコメント:

  1. # 結果による処理分岐 にて、
    テキストボックスが空白だった場合、表示していたフォームに
    戻るには、どうすればいいですか?

    返信削除
    返信
    1. コメントありがとうございます。

      未入力にてOKボタンが押された場合、フォームを再表示する処理は、do/while文を利用すれば可能となります。
      上記「ここから~ここまで」のスクリプトの場合、「#フォームを表示させ、その結果を受け取る」と「# 結果による処理分岐」の部分を次のように変更します。

      # フォームを表示させ、その結果を受け取る
      do
      {
      $result = $form.ShowDialog()

      # 結果による処理分岐
      if ($result -eq "OK")
      {
      $x = $textBox.Text
      }elseif($result -eq "Cancel"){
      break
      }
      }while ( $x -eq "" )

      do/while文はまずdo{}の部分を実行し、その結果をwhile文の条件に照らし合わせ、Falseになるまでdo部分を繰り返すというものです。

      今回の場合は、次のような流れになります。
      ①まずdoの部分を実行し、フォームを表示します
      ②押されたボタンがOKの場合、テキストボックス値を変数xに格納します
       (キャンセルが押された場合はループを抜けます)
      ③while部分で変数xの値が空白かどうか判定します
      ④変数xが空白の場合はTrueとなりますので、再度do部分を実行します

      この方法でいかがでしょうか。
      宜しくお願い致します。

      削除
  2. 返信遅くなりましたが、なるほど!なご回答、ありがとうございます。
    ”$form.ShowDialog()”がキモだったのですか。

    単純にGUIがやっぱり便利!と思い、コーディングに走りましたが。。。
    WinAPI? FORM?の基礎が抜けているのでくろうします。。

    ありがとうございました。

    追伸:

    ドラッグ&ドロップの記事、拝見しました。
    また、制作欲がわきまして。。。3連休なのに(笑

    返信削除
    返信
    1. ご返答いただき、ありがとうございます。

      返信させていただいた内容がお役に立ったようで、大変うれしく思います。

      また、ご不明点がございましたら、遠慮なくコメントorメールをお寄せください。

      今後もご愛顧のほど、よろしくお願い致します。

      削除
  3. 初心者です!
    ISEでデバッグした時とスクリプトで実行した時で
    フォームの見た目が変わります(スクリプト実行だとクラシックスタイル?になります)
    デバッグしてる時と同じフォームに変更するにはどうすればよいでしょうか?

    返信削除
    返信
    1. こんにちは!
      匿名ですが管理人です(別のPCからなので)

      ご質問の件ですが、私もわからなかったので調査したところ、stackoverflowに同じ質問をされているページを見つけました。
      その回答に、「フォームを表示する前に、スクリプトに次の行を追加します。」とあります。

      [System.Windows.Forms.Application]::EnableVisualStyles();

      参照ページ(英語):https://stackoverflow.com/questions/3358372/windows-forms-look-different-in-powershell-and-powershell-ise-why

      私自身が未確認で申し訳ないですが、上記一文を追加して一度お試しください。

      削除
    2. 返信ありがとうございます!
      [System.Windows.Forms.Application]::EnableVisualStyles();
      を追加して試したところ無事デバッグと同じフォームになりました!

      助かりましたありがとうございました!

      削除

疑問・質問・リクエスト お気軽にどうぞ (^O^)/