タグ別アーカイブ: IWin32Window

ShowDialog() をモーダルに

本当のモーダル

通常、PowerShell で System.Windows.Forms.Formを使ってモーダルダイアログ を表示するには、次のようにします。

PS> $form = New-Object Windows.Forms.Form
PS> $form.add_Shown({$form.Activate()})
PS> $button = New-Object Windows.Forms.Button
PS> $button.Text = '閉じる(&c)'
PS> $button.add_Click({$form.Close()})
PS> $form.Controls.Add($button)
PS> $form.ShowDialog()

しかし、これは本当のモーダルとは呼べません。

確かに、ダイアログボックスを表示している間は、コマンドレットの起動などを行うことはできませんが、PowerShell のコンソールウィンドウをアクティブにしたり、終了させたりすることは可能です。

コンソールをアクティブにできるということは、ダイアログが隠されてしまってユーザーの混乱を招く可能性があり、終了できるということは、中断の好ましくない場面で強制終了が簡単にできてしまうということになります。

意図があってこのような仕様にするならばともかく、Visual Studio .NET で作られたアプリケーションのような、本当にモーダルな動作が欲しい場合には困りますね。 そこで、次のようにします。

PS> $form = New-Object Windows.Forms.Form
PS> $form.add_Shown({$form.Activate()})
PS> $button = New-Object Windows.Forms.Button
PS> $button.Text = '閉じる(&c)'
PS> $button.add_Click({$form.Close()})
PS> $form.Controls.Add($button)
PS> $form.ShowDialog((Get-MainWindow))

強調された部分が変更点です。「(Get-MainWindow)」ではなく、「((Get-MainWindow))」のように括弧が二重になっていることにご注意ください。 おや?エラーがでますか?

PS> $form.ShowDialog((Get-MainWindow))
用語 ‘Get-MainWindow’ は、コマンドレット、関数、操作可能なプログラム、またはスクリプト ファイルとして認識されません。用語を確認し、再試行してください。発生場所 行:1 文字:26 + $form.ShowDialog((Get-MainWindow) <<<< )

それもそのはず。あなたはまだ必要なスクリプトをインストールしていません。次よりダウンロードし、PATH の通ったディレクトリに保存してください。。

ダウンロード

実装

Get-MainWindow.ps1 は、まず現在のプロセスのメインウィンドウのハンドルを取得します。これは、コンソールから起動した場合、コンソールウィンドウのハンドルになるはずです。

次に、取得したハンドルを使って、 System.Windows.Forms.NativeWindow を作ります。このクラスは、System.Windows.Forms.Control よりも軽量で、より低レベルなウィンドウ管理を行います。また、IWin32Window インターフェースを実装するので、ShowDialog() のオーナーとして使うことができます。