Make Entire Borderless Form Draggable from Certain Object - winforms

I have a borderless winform (WPF is not an option) that I am trying to make draggable from an object that is serving as a custom sidebar. I have searched around and found some things that allow me to drag the sidebar within the form, but I need to be able to move $Form with the sidebar. Any thoughts? It seems like I will need to use Add-Type with some C# here.

Ok, since we don't have the code to your form, here's a demo for you. It is just a not-pretty borderless form that uses a label to demonstrate the various events needed to drag the entire form around. (in your case this would be the sidebar)
Add-Type -AssemblyName System.Windows.Forms
# set up some globals for dragging
$global:dragging = $false
$global:mouseDragX = 0
$global:mouseDragY = 0
#Form
$form = New-Object System.Windows.Forms.Form
$form.FormBorderStyle = "None"
$form.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 9.0, [System.Drawing.FontStyle]::Regular, [System.Drawing.GraphicsUnit]::Point)
$form.MinimumSize = New-Object System.Drawing.Size(456, 547)
$form.AutoScaleDimensions = New-Object System.Drawing.SizeF(7.0, 15.0)
$form.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Font
$form.ClientSize = New-Object System.Drawing.Size(440, 509)
$form.ShowIcon = $false
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
#lblDrag (this is the object used for dragging the form)
$lblDrag = New-Object System.Windows.Forms.Label
$lblDrag.Name = "lblDrag"
$lblDrag.BackColor = [System.Drawing.Color]::LightYellow
$lblDrag.Location = New-Object System.Drawing.Point(172, 226)
$lblDrag.Size = New-Object System.Drawing.Size(117, 27)
$lblDrag.Anchor = "Top","Right"
$lblDrag.BorderStyle = "FixedSingle"
$lblDrag.Text = "Drag form.."
$lblDrag.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
# set the 'dragging' flag and capture the current mouse position
$lblDrag.Add_MouseDown( { $global:dragging = $true
$global:mouseDragX = [System.Windows.Forms.Cursor]::Position.X - $form.Left
$global:mouseDragY = [System.Windows.Forms.Cursor]::Position.Y -$form.Top
})
# move the form while the mouse is depressed (i.e. $global:dragging -eq $true)
$lblDrag.Add_MouseMove( { if($global:dragging) {
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea
$currentX = [System.Windows.Forms.Cursor]::Position.X
$currentY = [System.Windows.Forms.Cursor]::Position.Y
[int]$newX = [Math]::Min($currentX - $global:mouseDragX, $screen.Right - $form.Width)
[int]$newY = [Math]::Min($currentY - $global:mouseDragY, $screen.Bottom - $form.Height)
$form.Location = New-Object System.Drawing.Point($newX, $newY)
}})
# stop dragging the form
$lblDrag.Add_MouseUp( { $global:dragging = $false })
# add a button so you will be able to close the form
$btnClose = New-Object System.Windows.Forms.Button
$btnClose.Name = "btnClose"
$btnClose.Anchor = "Top","Right"
$btnClose.Location = New-Object System.Drawing.Point(172, 454)
$btnClose.Size = New-Object System.Drawing.Size(117, 27)
$btnClose.Text = "&Close"
$btnClose.UseVisualStyleBackColor = $true
$btnClose.UseMnemonic = $true
$btnClose.DialogResult = [System.Windows.Forms.DialogResult]::OK
# add controls to the form
$form.Controls.Add($btnClose)
$form.Controls.Add($lblDrag)
$form.AcceptButton = $btnClose
# show the form and play around with the dragging label
$form.ShowDialog()
# when done, dispose of the form
$form.Dispose()

Related

Powershell, WinForms and modal popup with faded background

I'm trying to implement a PowerShell form whereby there is a faded overlay over the background desktop.
The only way I could think implementing this was to use two forms - one to show a full screen overlay (background form), and the other being the actual (main) form. However, when i click off (or deactivate) the main form, I want everything to close. However it no longer closes and I can't figure it why? I get the feeling that when I click off the main form, the click event is trying to click the background form (and can't due to the main form having focus) and the 'deactivate' event no longer works?
Any help appreciated:
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles()
$windowsGreyTrans = [System.Drawing.Color]::FromArgb(20,43,43,43)
$windowsGreyOff = [System.Drawing.Color]::FromArgb(43,43,43)
$windowsGreyOn = [System.Drawing.Color]::FromArgb(60,60,60)
$bgform = New-Object System.Windows.Forms.Form
$bgform.WindowState = 'Maximized'
$bgform.ShowInTaskbar = $false
$bgform.MaximizeBox = $false
$bgform.Opacity = 0.5
$bgform.ControlBox = $false
$bgform.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::none
[void]$bgform.show()
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(200, 40)
$Form.StartPosition = "CenterScreen"
$form.ShowInTaskbar = $false
$form.Name ="Power"
$form.MaximizeBox = $false
$form.ControlBox = $false
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::none
$shutdownBtn = New-Object System.Windows.Forms.Button
$shutdownBtn.Location = New-Object System.Drawing.Point(0, 0)
$shutdownBtn.Size = New-Object System.Drawing.Size(200, 40)
$shutdownBtn.Text = "Shut down"
$shutdownBtn.FlatStyle = "Flat"
$shutdownBtn.UseVisualStyleBackColor = $True
$shutdownBtn.BackColor = $windowsGreyOff
$shutdownBtn.FlatAppearance.BorderSize = 0
$shutdownBtn.ForeColor = "White"
$shutdownBtn.Font = "Segoe UI,10pt"
#$shutdownBtn.Cursor = [System.Windows.Forms.Cursors]::Hand
$shutdownBtn.Add_Click({
try {
}
catch{
}
})
$shutdownBtn.Add_MouseEnter({
$this.BackColor = $windowsGreyOn
})
$shutdownBtn.Add_MouseLeave({
$this.BackColor = $windowsGreyOff
})
$form.Controls.Add($shutdownBtn)
$form.Add_Deactivate({
$this.Close()
$bgform.close()
})
$form.Add_Shown({
$this.Activate()
})
[void]$form.showdialog()
I propose you a better solution, use a tablelayoutpanel for center your button and intercept click event.
Try this :
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles()
$windowsGreyTrans = [System.Drawing.Color]::FromArgb(20,43,43,43)
$windowsGreyOff = [System.Drawing.Color]::FromArgb(43,43,43)
$windowsGreyOn = [System.Drawing.Color]::FromArgb(60,60,60)
#create form
$form = New-Object System.Windows.Forms.Form
$form.SuspendLayout()
$form.WindowState = [System.Windows.Forms.FormWindowState]::Maximized
$form.ShowInTaskbar = $false
$form.MaximizeBox = $false
$form.Opacity = 0.5
$form.ControlBox = $false
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::none
#create Tablelayout panel on this form
$TableLayoutPanel = New-Object System.Windows.Forms.TableLayoutPanel
$TableLayoutPanel.SuspendLayout()
$TableLayoutPanel.ColumnCount=1
$TableLayoutPanel.RowCount=1
$TableLayoutPanel.Dock=[System.Windows.Forms.DockStyle]::Fill
$form.Controls.Add($TableLayoutPanel)
#create button on this tablelayoutpanel
$shutdownBtn = New-Object System.Windows.Forms.Button
$shutdownBtn.Size = New-Object System.Drawing.Size(200, 40)
$shutdownBtn.Text = "Shut down"
$shutdownBtn.FlatStyle = "Flat"
$shutdownBtn.UseVisualStyleBackColor = $True
$shutdownBtn.BackColor = $windowsGreyOff
$shutdownBtn.FlatAppearance.BorderSize = 0
$shutdownBtn.ForeColor =[System.Drawing.Color]::White
$shutdownBtn.Font = "Segoe UI,10pt"
$shutdownBtn.Anchor=[System.Windows.Forms.AnchorStyles]::None
$TableLayoutPanel.Controls.Add($shutdownBtn)
#Layout
$TableLayoutPanel.ResumeLayout($false)
$form.ResumeLayout($false)
$shutdownBtn.Add_Click({
try {
}
catch{
}
})
#change color to tablelayot on first show
$form.Add_Shown({
$TableLayoutPanel.BackColor =$windowsGreyTrans
})
$TableLayoutPanel.Add_Click({
$form.close()
})
$shutdownBtn.Add_MouseEnter({
$this.BackColor = $windowsGreyOn
})
$shutdownBtn.Add_MouseLeave({
$this.BackColor = $windowsGreyOff
})
[void]$form.ShowDialog()
$form.Dispose()

How can i lock a form in position on the desktop?

I'm trying to make a form in PowerShell that gets locked to a fixed position on the desktop.
Because whenever I press the "Show Desktop" button on the bottom right corner on Win 8.1, the form disappears until I open a different window and close it.
I just want it there like it's a widget, here's a part of the code i'm using:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -Assembly System.Drawing
$Image = [System.Drawing.Image]::Fromfile("Panel.png")
$Form = New-Object system.Windows.Forms.Form
$Form.BackgroundImage = $Image
$Form.BackgroundImageLayout = "None"
$Form.Text = "Reboot Server"
$Form.Width = 517
$Form.Height = 134
$Form.ControlBox = $False
$Form.StartPosition = 'Manual'
$Form.Location = "1390, 300"
$Form.FormBorderStyle = 'None'
$Form.BackColor = "#000000"
$Form.MaximizeBox = $False
$Form.MinimizeBox = $False
$Form.Icon = "icon.ico"
$Form.Image = [System.Drawing.Image]::Fromfile("Panel.png")
$Form.ShowInTaskbar = $False
$Font = New-Object System.Drawing.Font("Tahoma",10, [System.Drawing.FontStyle]::Bold)
$Form.Font = $Font
$Label = New-Object System.Windows.Forms.Label
$Label.Text = ""
$Label.AutoSize = $True
$Form.Controls.Add($Label)
' Button 1 - Reboot Server'
$Button1 = new-object System.Windows.Forms.Button
$Button1.Location = new-object System.Drawing.Size(234,51)
$Button1.Size = new-object System.Drawing.Size(77,55)
$Button1.AutoSize = $True
$Button1.Add_Click({start-process "Reboot.lnk"})
$Button1.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$Button1.FlatAppearance.BorderSize=0
$Button1.BackColor = "Transparent"
$Button1.ForeColor = "Transparent"
$Button1.FlatAppearance.MouseDownBackColor = "Transparent"
$Button1.FlatAppearance.MouseOverBackColor = "Transparent"
$Button1.FlatAppearance.BorderColor = "#252525"
$Form.Controls.Add($Button1)
'----------------------------------------
$Form.ShowDialog() | Out-Null
Exit 0
For gadget style positions try to use a little snippet that I have made:
$Poistion = 'RightBottom'
$Coordinates = switch ($Poistion)
{
'LeftTop' { 0, 0 }
'LeftBottom' { 0, $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Bottom - $Form.Height) }
'RightTop' { $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Width - $Form.Width), 0 }
'RightBottom' { $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Width - $Form.Width), $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Bottom - $Form.Height) }
}
$Form.Location = New-Object System.Drawing.Point($Coordinates)
To keep your form up at the time when you activate "Show Desktop" set TopMost property to $True and MinimizeBox property to $False. Like so:
$Form.TopMost = $True
$Form.MinimizeBox = $False
When you click on Show Desktop or use its hotkey (Win+D) windows tries to send Minimize All command to running applications. After minimizing all the windows that can be minimized, it then takes the desktop and "raises" it to the top of the window stack so that no other windows cover it.
You could also try to use sizing events. Like so:
$Form_Resize={
$Form.WindowState = 'Normal'
}
$Form.add_Resize($Form_Resize)

powershell combobox items to variable

I am trying to create a powershell Script with a Gui that gives the user a drop list of available drives and then when the user selects the drive and clicks ok the script maps that drive as M:\
But I cant work out how to get the selected item in the combo box to be passed into the variable $MapDrive
#List of Drives To Map
$DriveList = #("0. DGL_Data","1. P1","2. DGLFSG3","3. p3 (TPC)","4. p4","6. p6","7. p7","8. p8","9. p9","10. p10","11. p11","12. p12")
#Displays With Drive to Map
$MapDrive = convert.ToString($Dropdown.SelectedItem)
Function MapDrive {
If ($MapDrive -eq $DriveList[0]){
Write-Output Sucess > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"}
ElseIf ($MapDrive -eq $DriveList[1]){
Write-Output BooYah > "C:\Users\andy.burton\Desktop\Practice Selector\Yes.txt"
}
Else {
Write-Output Failure > "C:\Users\andy.burton\Desktop\Practice Selector\Failed.txt"}
}
#test Function
Function test {
Write-Output $MapDrive > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"
}
#Function to Create Form
Function GenerateForm {
#Define Drive Selector Main Form
Add-Type -AssemblyName System.Windows.Forms
$DGL = New-Object system.Windows.Forms.Form
$DGL.Text = "DGL Practice Manager"
$DGL.TopMost = $true
$DGL.BackgroundImage = [system.drawing.image]::FromFile("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical.jpg")
$DGL.Icon = New-Object system.drawing.icon("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical2.ico")
$DGL.Width = 600
$DGL.Height = 265
$DGL.MinimizeBox = $False
$DGL.MaximizeBox = $False
#Label to Display Instuctions
$label2 = New-Object system.windows.Forms.Label
$label2.Text = "Select which drive"
$label2.BackColor = "#e4f3fa"
$label2.AutoSize = $true
$label2.Width = 25
$label2.Height = 10
$label2.location = new-object system.drawing.point(20,28)
$label2.Font = "Microsoft Sans Serif,10"
$DGL.controls.Add($label2)
#Dropdown Box For Selecting Practice
$Dropdown = New-Object system.windows.Forms.ComboBox
$Dropdown.BackColor = "#e4f3fa"
$DropDown.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$Dropdown.Width = 243
$Dropdown.Height = 20
$Dropdown.location = new-object system.drawing.point(21,73)
$Dropdown.Font = "Microsoft Sans Serif,10"
$DropDown.items.addrange($DriveList)
$DGL.controls.Add($Dropdown)
#Cancel Button to Cancel drive Selection
$Cancelbutton = New-Object system.windows.Forms.Button
$Cancelbutton.Text = "Cancel"
$Cancelbutton.Width = 60
$Cancelbutton.Height = 30
$Cancelbutton.location = new-object system.drawing.point(210,120)
$Cancelbutton.Font = "Microsoft Sans Serif,10"
$DGL.CancelButton = $Cancelbutton
$CancelButton.Add_Click({ $DGL.close();[System.Windows.Forms.Application]::Exit($null)})
$DGL.controls.Add($Cancelbutton)
#OK Button to Select Drive
$OKbutton = New-Object system.windows.Forms.Button
$OKbutton.Text = "OK"
$OKbutton.Width = 60
$OKbutton.Height = 30
$OKbutton.location = new-object system.drawing.point(140,120)
$OKbutton.Font = "Microsoft Sans Serif,10"
$DGL.AcceptButton = $OKbutton
$MapDrive = convert.ToString($Dropdown.SelectedItem)
#On click call PracticeSelectedCallBack to launch the application
$OKbutton.Add_Click({test ; $DGL.close()})
$DGL.controls.Add($OKbutton)
#Display the Form
$DGL.Add_Shown({$DGL.Activate()})
$DGL.ShowDialog()
}
GenerateForm
I also want to hide the powershell window but not the gui I have tried -window hidden but that hid everything
The ComboBox has several events that you can tie into that will do various things. One of the events is a SelectedIndexChanged. You can add that event to your ComboBox object and update $MapDrive
This code $MapDrive = convert.ToString($Dropdown.SelectedItem) will only fire once during the initial compile. You have to use events to trigger code changes after compile during runtime.
Also, in Powershell you can use the following command [System.Windows.Forms.ComboBox] | gm to get a list of the methods, and properties of the object. You can use [System.Windows.Forms.checkedlistbox].GetEvents() to get a list of events of an object.

.Bottom is read-only

I'm working on a PowerShell script that uses forms and panels that are docked. I was able to create the form and panels just fine, but I'm having issues getting a listbox to resize during runtime using $inputbox.Bottom = $form.Height - 215 to control the size, but I recieve the error
'Bottom' is a read-only property.
Simply using Fill in the panel will not work because I have buttons above and below the listbox. Here is a sample of my code:
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”)
$form.ResizeEnd
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(1040,459)
$form.KeyPreview = $true
$form.StartPosition = ‘centerscreen’
$form.BackColor = 'MidnightBlue'
$form.Add_KeyDown({if($_.KeyCode -eq "Escape"){$form.Close()}})
$form.Text = "Dialog Box 2.0"
$form.Icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell_ise.exe")
$buttonPanel3 = New-Object Windows.Forms.Panel
$buttonPanel3.Size = New-Object Drawing.Size #(290,70)
$buttonPanel3.Dock = "left"
$buttonPanel3.BackColor = 'Blue'
$inputbox = New-Object System.Windows.Forms.ListBox
$inputbox.BorderStyle = 'NONE'
$inputbox.Font = New-Object System.Drawing.Font(“segoe UI”,9)
$inputbox.SelectionMode = "MultiExtended"
$inputbox.Left = 10
$inputbox.Top = 105
$inputbox.Width = 200
$inputbox.Bottom = $form.Height -215
$inputbox.Height = $form.Height -215
$buttonPanel3.Controls.Add($inputbox)
$form.Controls.Add($buttonPanel3)
$form.ShowDialog()
If someone could give some sample code of a listbox that resizes (mainly concerned with vertical expansion) when you resize the form that would be excellent.
I ended up completely rearranging my form and using the fill method, but I wanted to put in a tidbit about form resizing since that was the true issue here.
The resize handler for the form would be $form.Add_Resize({}). Inside the brackets I could modify the height and width properties as desired. In this case, I only wanted the height property, so the code would be like:
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”)
$form.ResizeEnd
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(1040,459)
$form.KeyPreview = $true
$form.StartPosition = ‘centerscreen’
$form.BackColor = 'MidnightBlue'
$form.Add_KeyDown({if($_.KeyCode -eq "Escape"){$form.Close()}})
$form.Text = "Dialog Box 2.0"
$form.Icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell_ise.exe")
$form.Add_Resize({
$inputbox.Height = $form.Height -215
})
$buttonPanel3 = New-Object Windows.Forms.Panel
$buttonPanel3.Size = New-Object Drawing.Size #(290,70)
$buttonPanel3.Dock = "left"
$buttonPanel3.BackColor = 'Blue'
$inputbox = New-Object System.Windows.Forms.ListBox
$inputbox.BorderStyle = 'NONE'
$inputbox.Font = New-Object System.Drawing.Font(“segoe UI”,9)
$inputbox.SelectionMode = "MultiExtended"
$inputbox.Left = 10
$inputbox.Top = 105
$inputbox.Width = 200
$inputbox.Height = $form.Height -215
$buttonPanel3.Controls.Add($inputbox)
$form.Controls.Add($buttonPanel3)
$form.ShowDialog()

.NET DateTimePicker calendar not appearing in PowerShell form

I am trying to show a DateTimePicker in a WinForms form in PowerShell. When the form appears, the date can be changed, but hitting the dropdown button doesn't show the calendar. It seems like something is happening, it's just not visible.
What stupid thing am I missing here?
$form = New-Object Windows.Forms.Form
$form.Size = New-Object Drawing.Size #(400, 400)
$form.StartPosition = "CenterScreen"
$form.Text = "When do you want the snapshot to be taken?"
$form.Font = New-Object Drawing.Font("Microsoft Sans Serif",12)
$form.FormBorderStyle = [Windows.Forms.FormBorderStyle]::Fixed3D
$panel = New-Object Windows.Forms.FlowLayoutPanel
$panel.Height = 400
$panel.Width = 400
$panel.AutoScroll = $true
$panel.FlowDirection = [Windows.Forms.FlowDirection]::TopDown
$panel.WrapContents = $false
$titleText = New-Object Windows.Forms.Label
$titleText.AutoSize = $true
$titleText.Text = "When do you want the snapshot to be taken?"
$panel.Controls.Add($titleText)
$datePicker = New-Object Windows.Forms.DateTimePicker
$datePicker.ShowUpDown = $false
$datePicker.MinDate = $now
$datePicker.MaxDate = $now.AddMonths(3); #arbitrary
$datePicker.MaxSelectionCount = 1
$datePicker.Width = 350
$datePicker.Enabled = $false
$panel.Controls.Add($datePicker)
$form.Controls.Add($panel)
$drc = $form.ShowDialog()
Your code seems to work fine on my computer. I copy-pasted your code and added Add-Type to top:
Add-Type -AssemblyName System.Windows.Forms
And changed the $datePicker.Enabled:
$datePicker.Enabled = $true
When run, I can change the date/time and also the dropdown is working as expected:

Resources