Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In PowerShell Form.Show() does not work right, but Form.ShowDialog() does

I am trying to display an image via powershell. I made a script based on this forum post.

If I use ShowDialog() it works fine, except the powershell execution stops while the dialog is up. However, that is by design for a modal dialog. If I call Form.Show() in PowershellISE the form shows up, but freezes and cannot be moved or dismissed. Behavior is similar if I copy and past the code to a powershell console.

How do I make the dialog non-modal, and not freeze.

like image 936
Justin Dearing Avatar asked May 13 '11 02:05

Justin Dearing


People also ask

What is the difference between form show () and form ShowDialog ()?

Show() method shows a windows form in a non-modal state. ShowDialog() method shows a window in a modal state and stops execution of the calling context until a result is returned from the windows form open by the method.

What happens after a form that has been displayed with the ShowDialog method is closed by the user?

When a form is displayed as a modal dialog box, clicking the Close button (the button with an X at the upper-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.

How do I close a ShowDialog form?

To close a form, you just need to set the form's DialogResult property (to any value by DialogResult. None ) in some event handler. When your code exits from the event handler the WinForm engine will hide the form and the code that follows the initial ShowDialog method call will continue execution.


2 Answers

First Answer Why it appends.

In a Windows graphic program the thread which create a Window must loop in a message pump in order to redistribute (translate) messages coming from the user action to events in his Windows.

In a modal window, the modal code that handles the window display runs its own message pump loop and doesn't return until the window is closed. That's why the code after ShowDialog() won't execute until the window is closed.

Show(), just ask to show the Window, but if there is no pump loop to manage the messages coming from user action, it just freezes.

Second a simple way to have two threads

The CmdLet start-job use another thread from the pool allocated by Powershell so it makes the dialog non-modal, and it does not freeze.

function goForm
{
  [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")

  $file = (get-item 'C:\temp\jpb.png')
  #$file = (get-item "c:\image.jpg")

  $img = [System.Drawing.Image]::Fromfile($file);

  # This tip from http://stackoverflow.com/questions/3358372/windows-forms-look-different-in-powershell-and-powershell-ise-why/3359274#3359274
  [System.Windows.Forms.Application]::EnableVisualStyles();
  $form = new-object Windows.Forms.Form
  $form.Text = "Image Viewer"
  $form.Width = $img.Size.Width;
  $form.Height =  $img.Size.Height;
  $pictureBox = new-object Windows.Forms.PictureBox
  $pictureBox.Width =  $img.Size.Width;
  $pictureBox.Height =  $img.Size.Height;

  $pictureBox.Image = $img;
  $form.controls.add($pictureBox)
  $form.Add_Shown( { $form.Activate() } )
  $form.ShowDialog()
}

Clear-Host

start-job $function:goForm

$name = Read-Host "What is you name"
Write-Host "your name is $name"
like image 63
JPBlanc Avatar answered Sep 22 '22 23:09

JPBlanc


There are ways to make this work, but nothing is worth spending five hours explaining on an open forum. There are other free, shrink-wrapped ways to do this on powershell. Most notably with the free WPF powershell toolkit: Show-UI at http://showui.codeplex.com/ (previously known as WPK and/or PowerBoots - they are merged now.)

like image 26
x0n Avatar answered Sep 23 '22 23:09

x0n