Add-Type -AssemblyName System.Drawing
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class NativeMethods {
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
}
"@
# 定数定義
$WM_NCLBUTTONDOWN = 0xA1
$HTCAPTION = 0x2
# メニュー設定ファイル
$csvPath = "$PSScriptRoot\menutable.csv"
#パネルグループ分け件数
$btnCount = 100
$flags = [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance
$script:menutable = @()
$fontzoom = 1.0 # サイズ倍率
$MinButtonWidth = [int](54 * $fontzoom)
$MinButtonHeight = [int](54 * $fontzoom)
$BrowserPath = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
# 格納フォーム寸法
$script:fold = [PSCustomObject]@{
x = 550
y = 100
w = 50
h = 50
}
# 展開フォーム寸法
$script:expand = [PSCustomObject]@{
x = 200
y = 100
w = 400
h = 300
}
# ボタンの種類に応じて文字色を設定
$colorMap = @{
"PowerShell" = "#09c"
"実行" = "#09d"
"実行2" = "#09d"
"フォルダ" = "#c90"
"開く" = "#ccc"
"URL" = "#0c9"
"" = "#333"
}
$FontLevel = @{
"L" = 26 * $fontzoom
"M" = 16 * $fontzoom
"S" = 14 * $fontzoom
"SS" = 12 * $fontzoom
}
$iconSize = 48 * $fontzoom
# リセット復元用
$script:currentGroupId = 1
# 編集モードフラグ
$script:isEditMode = $false
$script:isMenuPanel = $false
$script:editMenuBound = 0
# 展開フォームフラグ
$script:isExpand = $false
# 展開ボタン移動モード
$script:isMoveBtn = $false
# グループ化
$groupPanels = @{}
$groupRadios = @{}
# ツールチップオブジェクト
$tooltip = New-Object System.Windows.Forms.ToolTip
# 固定アイコン
$script:explorericon = [System.Drawing.Icon]::ExtractAssociatedIcon("$env:windir\explorer.exe")
$script:powershellicon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Command "powershell.exe").Source)
# エンコード指定
$psversion = $PSVersionTable.PSVersion.Major
if ( $psversion -ge 6 ) {
$csvencode = "Shift_JIS"
} else {
$csvencode = "Default"
}
# タイマー(共通)
$script:hoverTimer = New-Object Windows.Forms.Timer
$script:hoverTimer.Interval = 300
$script:currentRadio = $null
$script:hoverTimer.Add_Tick({
if ( $script:currentRadio -ne $null ) {
$script:currentRadio.Checked = $true
$script:hoverTimer.Stop()
}
})
##########
# 関数
# 関数:メッセージボックス
function MsgBox ($message, $title = "通知", $buttons = "OK", $icon = "None", $defaultButton = "Button1", $timeout = 0) {
return [System.Windows.Forms.MessageBox]::Show($message, $title, $buttons, $icon, $defaultButton, $timeout)
}
# 関数:ひとつ上のフォルダを開く
function Open-ParentFolder {
param($Path)
Show-FoldForm
try{
if ([System.IO.Path]::GetExtension($Path) -eq "") {
$folder = $Path
} else {
$folder = Split-Path $Path -Parent
}
& explorer.exe $folder
} catch {
Write-Host "一つ上のフォルダを開けなかった:$folder"
}
}
# 関数:グループ選択移動フォーム
function Show-GroupSelector {
param($groupPanels)
$groupSelectForm = New-Object System.Windows.Forms.Form
$groupSelectForm.Text = "グループ選択"
$groupSelectForm.Size = "275,$($groupPanels.Keys.Count * 50 + 150)"
$groupSelectForm.StartPosition = 'CenterParent'
$panel = New-Object System.Windows.Forms.FlowLayoutPanel
$panel.Dock = 'Fill'
$panel.AutoScroll = $true
$groupSelectForm.Controls.Add($panel)
foreach ($key in ($groupPanels.Keys | Sort-Object)) {
$btn = New-Object System.Windows.Forms.Button
$btn.Text = "$key"
$btn.Font = "Consolas,28"
$btn.Tag = $key
$btn.Width = 250
$btn.Height = 40
$btn.Add_Click({
param($s, $e)
Write-Host "選択されたグループ: $($s.Tag)"
$groupSelectForm.DialogResult = 'OK'
$groupSelectForm.Tag = $s.Tag # 選択結果を保持
$groupSelectForm.Close()
})
$panel.Controls.Add($btn)
}
# パネル追加ボタン
$btnAddPanel = New-Object System.Windows.Forms.Button
$btnAddPanel.Text = "追加"
$btnAddPanel.Font = "Consolas,20"
$btnAddPanel.Size = New-Object Drawing.Size(250,40)
$btnAddPanel.Add_Click({
$gid = Add-NewPanel
Write-Host "選択されたグループ: $($s.Tag)"
$groupSelectForm.DialogResult = 'OK'
$groupSelectForm.Tag = $gid # 選択結果を保持
$groupSelectForm.Close()
})
$panel.Controls.Add($btnAddPanel)
# キャンセルボタン
$cancel = New-Object System.Windows.Forms.Button
$cancel.Text = "キャンセル"
$cancel.Width = 250
$cancel.Height = 40
$cancel.Add_Click({ $groupSelectForm.DialogResult = 'Cancel'; $groupSelectForm.Close() })
$panel.Controls.Add($cancel)
$groupSelectForm.TopMost = $true
$result = $groupSelectForm.ShowDialog()
if ($result -eq 'OK') {
return $groupSelectForm.Tag # 選択されたキー
} else {
return $null
}
}
function Set-FormSizeSettings {
if ($script:isEditMode) {
$topBound = 30
$leftBound = 8
} else {
$topBound = 0
$leftBound = 0
}
if ($script:isExpand) {
$script:expand.x = $script:form.Location.X + $script:editMenuBound + $leftBound
$script:expand.y = $script:form.Location.Y + $topBound
$script:expand.w = $script:form.Size.Width - $script:editMenuBound - ($leftBound * 2)
$script:expand.h = $script:form.Size.Height - ($topBound + $leftBound)
$script:fold.x = $script:expand.x + $script:expand.w - $script:fold.w
$script:fold.y = $script:expand.y
} else {
$script:expand.x = $script:form.Left - $script:expand.w + $script:fold.w + $leftBound
$script:expand.y = $script:form.Top + $topBound
$script:fold.x = $script:form.Location.X + $leftBound
$script:fold.y = $script:form.Location.Y + $topBound
}
}
# 関数:フォームサイズ変更 展開サイズ
function Show-ExpandForm {
# if($script:timer) {
# $script:timer.Stop()
# $script:timer.Dispose()
# $script:timer = $null
# }
#
# $script:timer = New-Object Windows.Forms.Timer
# $script:timer.Interval = 10
# $script:step = 10
# $script:targetX = $script:expand.x - $script:editMenuBound
# $script:targetY = $script:expand.y
# $script:targetW = $script:expand.w + $script:editMenuBound
# $script:targetH = $script:expand.h
#
#
# $script:timer.Add_Tick({
#
# $currentX = $script:form.Left
# $currentY = $script:form.Top
# $currentW = $script:form.Width
# $currentH = $script:form.Height
#
# $nextX = if ($currentX -gt $script:targetX) { $currentX - $step } else { $script:targetX }
# $nextY = $script:targetY
# $nextW = if ($currentW -lt $script:targetW) { $currentW + $step } else { $script:targetW }
# #$nextH = if ($currentH -lt $script:targetH) { $currentH + ($step * ($currentH / $currentW)) } else { $script:targetH }
# $nextH = $script:targetH
#
# $script:form.SetBounds($nextX, $nextY, $nextW, $nextH)
# #Write-Host "$nextX, $nextY, $nextW, $nextH $script:targetX, $script:targetY, $script:targetW, $script:targetH"
# Write-Host "$($nextX - $script:targetX), $($nextY - $script:targetY), $($script:targetW - $nextW), $($script:targetH - $nextH)"
# if ($nextX -le $script:targetX -and $nextY -ge $script:targetY -and $nextW -ge $script:targetW -and $nextH -ge $script:targetH) {
# $script:form.SetBounds($script:targetX, $script:targetY, $script:targetW, $script:targetH)
# $script:timer.Stop()
# $script:timer.Dispose()
# $script:timer = $null
# }
#})
#$script:timer.Start()
$script:isExpand = $true
$targetX = $script:expand.x - $script:editMenuBound
$targetY = $script:expand.y
$targetW = $script:expand.w + $script:editMenuBound
$targetH = $script:expand.h
$script:form.SuspendLayout()
$expandFormBtn.Visible = $false
$expandFormBtn.SendToBack()
$script:form.SetBounds($targetX, $targetY, $targetW, $targetH)
$script:form.ResumeLayout()
$editBtnItem.Enabled = $true
$editMenuItem.Enabled = $true
}
# 関数:フォームサイズ変更 格納サイズ
function Show-FoldForm {
if ($script:isEditMode) { return }
$script:isExpand = $false
$script:form.SuspendLayout()
$expandFormBtn.Visible = $true
$expandFormBtn.BringToFront()
$script:form.SetBounds(
$script:fold.x,
$script:fold.y,
$script:fold.w,
$script:fold.h
)
$script:form.ResumeLayout($false)
$editBtnItem.Enabled = $false
$editMenuItem.Enabled = $false
}
# 関数:フォームサイズ変更 展開格納切り替え
function Toggle-FormSize {
Set-FormSizeSettings
$script:isExpand = -not $script:isExpand
if ($script:isExpand) {
Show-ExpandForm
} else {
Show-FoldForm
}
}
# 関数:メニューパネル表示切り替え
function Toggle-MenuPanelView {
$menuPanel.Visible = $script:isMenuPanel
if ($script:isMenuPanel) {
$script:editMenuBound = $menuPanel.Size.Width
} else {
$script:editMenuBound = 0
}
if ($script:isExpand) {
Show-ExpandForm
} else {
Show-FoldForm
}
}
function Toggle-MoveButton {
if ( $script:isMoveBtn ) {
$moveBtnItem.Text = "移動する"
$expandFormBtn.ForeColor = "LightGreen"
$foldFormBtn.ForeColor = "LightGreen"
Set-FormSizeSettings
Save-MenuTable
} else {
$moveBtnItem.Text = "移動しない"
$expandFormBtn.ForeColor = "Orange"
$foldFormBtn.ForeColor = "Orange"
}
$script:isMoveBtn = -not $script:isMoveBtn
}
function Toggle-EditMode {
$script:isEditMode = $editToggle.Checked
if ($script:isEditMode) {
$script:isMenuPanel = $true
Toggle-MenuPanelView
$editToggle.Text = "編集モード: ON"
$editToggle.BackColor = 'LightYellow'
#$editToggle.ForeColor = 'Black'
$addPanelBtn.Visible = $true
$resetBtn.Visible = $true
$statusText.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#fff")
$statusText.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#000")
$script:form.SuspendLayout()
$script:form.Top = $script:form.Top - 31
$script:form.Left = $script:form.Left - 8
$script:form.FormBorderStyle = 'Sizable'
$script:form.ResumeLayout()
$col = "#070"
if ( -not $script:isMoveBtn ) {
Toggle-MoveButton
}
$editMenuItem.Enabled = $false
$moveBtnItem.Enabled = $false
} else {
$editToggle.Text = "編集モード: OFF"
$editToggle.BackColor = 'LightGray'
#$s.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#3d3")
$addPanelBtn.Visible = $false
$resetBtn.Visible = $false
$statusText.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$statusText.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#ccc")
$col = "#ddf"
$script:form.SuspendLayout()
$script:form.Top = $script:form.Top + 31
$script:form.Left = $script:form.Left + 8
$script:form.FormBorderStyle = 'None'
$foldFormBtn.BringToFront()
$script:form.ResumeLayout()
if ( $script:isMoveBtn ) {
Toggle-MoveButton
}
$editMenuItem.Enabled = $true
$moveBtnItem.Enabled = $true
if ($groupPanels.Keys.Count -eq 1) {
$script:isMenuPanel = $false
Toggle-MenuPanelView
}
}
foreach ($key in $groupPanels.Keys) {
$groupPanels[$key].BackColor = [System.Drawing.ColorTranslator]::FromHtml($col)
}
}
function Set-ButtonGeometory {
param($item)
$entry = $script:menutable | Where-Object { $_.ボタン番号 -eq $item.Tag.Entry.ボタン番号 }
if ($entry) {
$entry.Left = $item.Location.X
$entry.Top = $item.Location.Y
$entry.Width = [Math]::Max($MinButtonWidth, $item.Size.Width)
$entry.Height = [Math]::Max($MinButtonHeight, $item.Size.Height)
}
}
function Get-NextButtonNumber{
$maxButtonNumber = $script:menutable | Measure-Object -Property ボタン番号 -Maximum
$result = $maxButtonNumber.Maximum + 1
return $result
}
function Get-MenuTable {
$script:menutable = @() # 事前に空の配列として初期化
$script:menutable = Import-Csv -Path $csvPath -Encoding $($csvencode) | ForEach-Object {
[PSCustomObject]@{
ボタン番号 = $_.ボタン番号
タイトル = $_.タイトル
アイコン = $_.アイコン
データ = $_.データ
TOP = [int]$_.Top
Left = [int]$_.Left
Height = [int]$_.Height
Width = [int]$_.Width
種類 = $_.種類
グループ = $_.グループ
}
}
$ZeroEntry = $script:menutable | Where-Object { $_.ボタン番号 -eq 0 }
if ($null -eq $ZeroEntry) {
$script:menutable += [PSCustomObject]@{ ボタン番号 = 0; タイトル = "ウィンドウ"; アイコン = ""; データ = ""; Top = "200"; Left = "100"; Height = "600"; Width = "800"; 種類 = ""; グループ = ""}
}
$entry = $script:menutable | Where-Object { $_.ボタン番号 -eq 0 }
$script:expand.x = [int]$entry.Left
$script:expand.y = [int]$entry.Top
$script:expand.w = [int]$entry.Width
$script:expand.h = [int]$entry.Height
$script:fold.x = $script:expand.x + $script:expand.w - $script:fold.w
$script:fold.y = $script:expand.y
}
function Save-MenuTable {
# 既存のカスタムオブジェクト配列をソート
$script:menutable = $script:menutable | Sort-Object `
@{ Expression = { [int]$_.グループ } }, `
@{ Expression = { [int]$_.ボタン番号 } }
# 新しいボタン番号を連番で振り直す
$counter = 0
$script:menutable | ForEach-Object { $_.ボタン番号 = $counter; $counter++ }
$windowentry = ($script:menutable | Where-Object { $_.ボタン番号 -eq 0 })
$windowentry.Height = $script:expand.h
$windowentry.Width = $script:expand.w
$windowentry.Top = $script:expand.y
$windowentry.Left = $script:expand.x
# foreach ($row in $script:menutable) {
# $row.PSObject.Properties.Remove("種類")
# }
$script:menutable | Export-Csv $csvPath -NoTypeInformation -Encoding $($csvencode)
}
function Add-MenuTable {
param(
$number,
$title,
$data,
$icon = "",
$top = 0,
$left = 0,
$height = ($MinButtonHeight),
$width = ($MinButtonWidth),
$groupId = 1
)
if ($script:menutable -isnot [System.Array]) {
$script:menutable = @($script:menutable) # 配列化
}
$script:menutable += [PSCustomObject]@{
ボタン番号 = $number
タイトル = $title
アイコン = $icon
データ = $data
TOP = [int]$top
Left = [int]$left
Height = [int]$height
Width = [int]$width
グループ = [int]$groupId
}
# Write-Host "NewButton $number $title $icon $data $top $left $height $width"
Save-MenuTable
Reset-Panels
}
function Remove-MenuTable {
param($number)
$existingEntry = $script:menutable | Where-Object { $_.ボタン番号 -eq $number }
$result = MsgBox "ボタン番号:$($existingEntry.ボタン番号)`nタイトル:$($existingEntry.タイトル)`n`nボタンを削除しますか?" "確認" "YesNo"
if ($result -eq [System.Windows.Forms.DialogResult]::No) {
Write-Host "削除キャンセル"
return
}
$script:menutable = $script:menutable | Where-Object { $_.ボタン番号 -ne $number }
if ($null -eq $script:menutable) {$script:menutable = @([PSCustomObject]@{ ボタン番号 = 1; タイトル = "メモ帳"; アイコン = ""; データ = "notepad.exe"; Top = "0"; Left = "0"; Height = "64"; Width = "350"})}
Save-MenuTable
Reset-Panels
}
function Get-WebTitle {
param ([string]$Url)
try {
$response = Invoke-WebRequest -Uri $Url -UseBasicParsing
Write-Host "URL: $Url"
# Write-Host "HTTP ステータスコード: $($response.StatusCode)"
# ステータスコードが200の場合はタイトルを取得
if ($response.StatusCode -eq 200) {
if ($response.Content -match "
(.*?)") {
$title = $matches[1]
} else {
$title = $Url
}
# Write-Host "取得したタイトル: $($title)"
return $title
} else {
throw
}
} catch {
Write-Host "タイトル取得失敗: $Url Error: $_"
return $Url # 取得できなかった場合はURLをそのまま返す
}
}
function Add-NewPanel {
param([int]$groupId)
$flg = ($null -eq $groupId -or $groupId -eq "")
if ($flg) {
for( $i = 1; $i -le $groupPanels.Keys.Count; $i++){
if ( -not $groupPanels.ContainsKey($i) ) {
$newGroupId = $i
}
}
if ($null -eq $newGroupId){
$newGroupId = [int](($groupPanels.Keys | Measure-Object -Maximum).Maximum + 1)
}
# Write-Host "$newGroupId 構築"
} else {
$newGroupId = [int]$groupId
if ($groupPanels.ContainsKey($groupId)) {
# Write-Host "$groupId 再構築の為削除"
$groupPanels[$newGroupId].Controls.Clear()
$rightPanel.Controls.Remove($groupPanels[$newGroupId])
$groupPanels.Remove($newGroupId)
} else {
$flg = $true
}
}
$newPanel = New-Object System.Windows.Forms.Panel
$newPanel.Dock = 'Fill'
$newPanel.Tag = $newGroupId
#$newPanel.GetType().GetProperty("DoubleBuffered", $flags).SetValue($newPanel, $true, $null)
$newPanel.AllowDrop = $true
$rightPanel.Controls.Add($newPanel)
$groupPanels[$newGroupId] = $newPanel
$newPanel.Add_DragEnter({
param($s, $e)
if ($e.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop) -or
$e.Data.GetDataPresent([Windows.Forms.DataFormats]::Text)) {
$e.Effect = [System.Windows.Forms.DragDropEffects]::Copy
} else {
$e.Effect = [System.Windows.Forms.DragDropEffects]::None
}
})
$newPanel.Add_DragDrop({
param($s, $e)
$pos = $s.PointToClient([System.Windows.Forms.Cursor]::Position)
$data = $e.Data
if ($data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop)) {
$files = $data.GetData([Windows.Forms.DataFormats]::FileDrop)
if($files.Count -eq 1) {
$file = $files[0]
Write-Host "ファイルドロップ: $file"
# ファイル処理
$title = [System.IO.Path]::GetFileNameWithoutExtension($file)
} else {
Write-Host "複数ファイルの位置ずらし方わからん"
}
} elseif ($data.GetDataPresent([Windows.Forms.DataFormats]::Text)) {
$text = $data.GetData([Windows.Forms.DataFormats]::Text)
if ($text -match '^https?://') {
Write-Host "URLドロップ: $text"
# URL処理
$file = $text
$title = Get-WebTitle -Url $file
} else {
Write-Host "テキストドロップ: $text"
# 通常テキスト処理
}
} else {
Write-Host "未知の形式がドロップされました"
}
# foreach ($key in $groupPanels.Keys) {
# Write-Host "$key → $($key.GetType().FullName)"
# }
Add-MenuTable -number $(Get-NextButtonNumber) -title $title -data $file -top $pos.Y -Left $pos.X -groupId $s.Tag
$editToggle.Checked = $true
})
# パネルにマウスダウンイベントを追加
$newPanel.Add_MouseDown({
if ( $script:isEditMode ) {
[NativeMethods]::ReleaseCapture() | Out-Null
[NativeMethods]::SendMessage($form.Handle, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
}
})
if ($flg){
$radio = New-Object System.Windows.Forms.RadioButton
$radio.Appearance = 'Button'
$radio.FlatStyle = 'Standard'
$radio.Margin = '0,0,0,0'
$radio.Size = New-Object System.Drawing.Size($groupPanel.Width, 100)
$radio.Tag = $newGroupId
$radio.Text = "グループ $newGroupId"
$index = $groupPanel.Controls.Count
$groupPanel.Controls.Add($radio)
$groupPanel.Controls.SetChildIndex($radio, $groupPanel.Controls.Count - 1)
$groupRadios[$newGroupId] = $radio
# マウスリーブでタイマー停止
$radio.Add_MouseLeave({
$script:hoverTimer.Stop()
$script:currentRadio = $null
})
# マウスエンターでタイマー開始
$radio.Add_MouseEnter({
param($s, $e)
$script:currentRadio = $s
# タイマーTickでクリック発火
$script:hoverTimer.Stop()
$script:hoverTimer.Start()
})
$radio.Add_CheckedChanged({
param($s, $e)
if ($s.Checked) {
$s.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#ddf")
$s.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#000")
$script:currentGroupId = $s.Tag
$groupPanels[$s.Tag].BringToFront()
if ($groupPanels[$s.Tag].Controls.Count -eq 0) {
$statusText.Text = "下のスペースにファイルなどをドロップすると登録されます"
}
} else {
$s.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$s.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#ccc")
$statusText.Text = (Get-Date).ToString("yyyy-MM-dd dddd")
}
})
$radio.Checked = $true
} else {
# $groupId
}
if ($script:isEditMode) {
$col = "#070"
} else {
$col = "#ddf"
}
$newPanel.BackColor = [System.Drawing.ColorTranslator]::FromHtml($col)
$groupRadios[$newGroupId].Checked = $true
return $newGroupId
}
# アイコン生成関数(Labelベース)
function Add-LauncherPanel($item, $targetPanel) {
$item.Width = [Math]::Max($MinButtonWidth, $item.Width)
$item.Height = [Math]::Max($MinButtonHeight, $item.Height)
$panel = New-Object System.Windows.Forms.Panel
$panel.Size = New-Object System.Drawing.Size($item.Width, $item.Height)
$panel.Location = New-Object System.Drawing.Point($item.Left, $item.Top)
$panel.Font = New-Object System.Drawing.Font("メイリオ",24)
$panel.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$panel.GetType().GetProperty("DoubleBuffered", $flags).SetValue($panel, $true, $null)
#$panel.BorderStyle = 'FixedSingle'
$panel.BorderStyle = 'None'
# アイコン設定
$iconpath = ""
if( $item.アイコン -ne "") {
$iconpath = "$($item.アイコン -replace "^\.\\", "$PSScriptRoot\")"
} elseif ($item.種類 -eq 'URL') {
$uri = [System.Uri]::new($item.データ)
$iconpath = "$PSScriptRoot\icon\$($uri.Host).png"
} elseif ($item.種類 -eq '開く') {
$iconpath = "$PSScriptRoot\icon\$([System.IO.Path]::GetExtension($item.データ)).png"
} else {
$iconpath = "$PSScriptRoot\icon\$([System.IO.Path]::GetFileNameWithoutExtension($($item.データ))).png"
}
if ($null -eq $iconpath -or $iconpath -eq "" -or $iconpath -eq ".png") {
$iconpath = ""
}
$existIconFile = Test-Path -Path $iconpath
# Write-Host $iconpath, $existIconFile, $item.種類.ToString()
if ($existIconFile) {
try {
$icon = [System.Drawing.Image]::FromFile($iconpath)
} catch {
Write-Host "画像読み込み失敗: $iconpath"
}
} else {
switch ($item.種類) {
'URL' {
$uri = [System.Uri]::new($item.データ)
$iconpath = "$PSScriptRoot\icon\$($uri.Host).png"
if (Test-Path $iconpath) {
$icon = [System.Drawing.Image]::FromFile($iconpath)
} else {
$faviconUrl = "$($uri.Scheme)://$($uri.Host)/favicon.ico"
try {
$response = Invoke-WebRequest -Uri $faviconUrl -Headers @{ "User-Agent" = "Mozilla/5.0" } -Method Get -ErrorAction Stop
$ms = New-Object System.IO.MemoryStream
$ms.Write($response.Content, 0, $response.Content.Length)
$ms.Position = 0
$icon = [System.Drawing.Image]::FromStream($ms)
} catch {
Write-Host "Favicon取得失敗: $faviconUrl"
$file = (Get-Command $BrowserPath).Source
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($file)
$icon = $icon.ToBitmap()
}
}
}
'フォルダ' {
$icon = $script:explorericon
$icon = $icon.ToBitmap()
$iconpath = ""
}
'PowerShell' {
$icon = $script:powershellicon
$icon = $icon.ToBitmap()
$iconpath = ""
}
'実行' {
try {
$file = (Get-Command $item.データ -ErrorAction Stop).Source
Write-Host $file
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($file)
$icon = $icon.ToBitmap()
} catch {
Write-Host "実行アイコン取得失敗: $($item.データ)"
}
}
default {
$ext = [System.IO.Path]::GetExtension($item.データ)
if ($ext -ne "") {
$dummyFile = "$env:TEMP\dummy$ext"
New-Item -Path $dummyFile -ItemType File -Force | Out-Null
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon($dummyFile)
$icon = $icon.ToBitmap()
Remove-Item $dummyFile -Force
$iconpath = "$PSScriptRoot\icon\$($ext).png"
}
}
}
}
if ($null -ne $icon -and $null -ne $iconpath -and $iconpath -ne "" ) {
if(-not (Test-Path -Path $iconpath)) {
try{
#Write-Host $iconpath, $item.種類.ToString(), $existIconFile
$icon.Save($iconpath, [System.Drawing.Imaging.ImageFormat]::Png)
} catch {
Write-Host "アイコンファイルの保存に失敗"
}
}
}
$titlelength = Get-HalfWidthLength -text $item.タイトル
$fontsize = if ($($titlelength) -le 10) {
$FontLevel["L"]
} elseif ($($titlelength) -le 16) {
$FontLevel["M"]
} elseif ($($titlelength) -le 20) {
$FontLevel["S"]
} else {
$FontLevel["SS"]
}
$btnFont = New-Object System.Drawing.Font("Meyrio",$fontsize,[System.Drawing.FontStyle]::Bold)
$btnColor = New-Object Drawing.SolidBrush ([Drawing.ColorTranslator]::FromHtml($colorMap[$item.種類]))
$panel.Tag = @{
Entry = $item
Icon = $icon
Font = $btnFont
Color = $btnColor
}
$panel.Add_Paint({
param($s, $e)
$entry = $s.Tag.Entry
$icon = $s.Tag.Icon
$btnFont = $s.Tag.Font
$btnColor = $s.Tag.Color
$g = $e.Graphics
$g.SmoothingMode = 'AntiAlias'
$r = $s.ClientRectangle
$radius = 12
$path = [System.Drawing.Drawing2D.GraphicsPath]::new()
$path.AddArc($r.X, $r.Y, $radius, $radius, 180, 90)
$path.AddArc($r.Right - $radius, $r.Y, $radius, $radius, 270, 90)
$path.AddArc($r.Right - $radius, $r.Bottom - $radius, $radius, $radius, 0, 90)
$path.AddArc($r.X, $r.Bottom - $radius, $radius, $radius, 90, 90)
$path.CloseFigure()
# $g.FillPath([System.Drawing.Brushes]::LightSteelBlue, $path)
$pen = New-Object System.Drawing.Pen([System.Drawing.Color]::Silver, 3)
$s.Region = New-Object System.Drawing.Region($path)
$g.DrawPath($pen, $path)
if ($icon) {
$y = ($s.Height - $iconSize) / 2 + 1
$g.DrawImage($icon, 3, $y, $iconSize, $iconSize)
$textleft = $iconSize + 1
} else {
$textleft = 0
}
$y = ($s.Height - $btnFont.Height) / 2
$g.DrawString($entry.タイトル, $btnFont, $btnColor, $textleft, $y)
})
# コンテキストメニュー作成
$btnPanelContext = New-Object System.Windows.Forms.ContextMenuStrip
# フォルダを開くメニュー項目
$parentItem = New-Object System.Windows.Forms.ToolStripMenuItem
$parentItem.Text = "フォルダを開く"
$parentItem.Tag = $item
# セパレータ作成
$sep1 = New-Object System.Windows.Forms.ToolStripSeparator
# グループ変更メニュー項目
$changeGroupItem = New-Object System.Windows.Forms.ToolStripMenuItem
$changeGroupItem.Text = "グループ変更"
$changeGroupItem.Tag = $item
# ボタン削除メニュー項目
$delBtnPanelItem = New-Object System.Windows.Forms.ToolStripMenuItem
$delBtnPanelItem.Text = "ボタンを削除"
$delBtnPanelItem.Tag = $item
# メニューに追加
$btnPanelContext.Items.AddRange(@(
$parentItem,
$sep1,
$changeGroupItem,
$delBtnPanelItem
))
# パネルにメニューを割り当て
$Panel.ContextMenuStrip = $btnPanelContext
# コンテキストメニューイベント
$btnPanelContext.Add_Opening({
param($s, $e)
# 表示直前の処理
$items = $s.Items
$changeGroupItem = $items | Where-Object { $_.Text -eq "グループ変更" }
$delBtnPanelItem = $items | Where-Object { $_.Text -eq "ボタンを削除" }
$changeGroupItem.Enabled = $script:isEditMode
$delBtnPanelItem.Enabled = $script:isEditMode
})
$parentItem.Add_Click({
param($s, $e)
Open-ParentFolder $s.Tag.データ
})
$changeGroupItem.Add_Click({
param($s, $e)
$selectedGroup = Show-GroupSelector -groupPanels $groupPanels
if ($selectedGroup -ne $null) {
Write-Host "選択されたグループID: $selectedGroup"
$entry = $script:menutable | Where-Object { $_.ボタン番号 -eq $s.Tag.ボタン番号 }
$entry.グループ = [int]$selectedGroup
$groupRadios[$entry.グループ].Checked = $true
Save-MenuTable
Reset-Panels
}
})
$delBtnPanelItem.Add_Click({
param($s, $e)
Remove-MenuTable $s.Tag.ボタン番号
})
# イベント処理(パネルに対して)
$panel.Add_Click({
param($s, $e)
if (-not $script:isEditMode) {
Show-FoldForm
$entry = $s.Tag.Entry
$type = $entry.種類
$param = $entry.データ
switch ($type) {
'URL' {
& $BrowserPath $param
}
'PowerShell' {
Start-Process "powershell.exe" -ArgumentList "-ExecutionPolicy Bypass -NoProfile -File `"$param`""
}
'実行' {
& $param
}
'実行2' {
Invoke-Item $param
}
'フォルダ' {
& "explorer.exe" $param
}
'開く' {
Invoke-Item $param
}
default {
Write-Host "未定義の種類: `"$type`""
}
}
}
})
$Script:isDragging = $false
$Script:isResizing = $false
$Script:startMouse = [System.Drawing.Point]::Empty
$Script:offset = [System.Drawing.Point]::Empty
$Script:threshold = 20
$panel.Add_MouseHover({
param($s, $e)
$entry = $s.Tag.Entry
if ($script:isEditMode) {
$tooltext = "x:{0,4} y:{1,4} w:{2,4} h:{3,4} $($s.Tag.Entry.データ)" -f $s.Left ,$s.Top, $s.Width, $s.Height
$tooltip.Show($tooltext, $s, 0, $s.Height, 5000)
}
})
$panel.Add_MouseEnter({
param($s, $e)
$statusText.Text = $s.Tag.Entry.タイトル
$statusText.Tag = $s.Tag.Entry.ボタン番号
if(-not $script:isEditMode){
$s.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#4a4d51")
$s.Cursor = 'Hand'
} else {
$statusText.Focus()
$statusText.SelectAll()
}
})
$panel.Add_MouseLeave({
param($s, $e)
$statusText.Text = ""
$statusText.Tag = ""
$s.Cursor = $null
if(-not $script:isEditMode){
$s.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
}
})
$panel.Add_MouseDown({
param($s, $e)
if ($script:isEditMode) {
if ($e.Button -eq [System.Windows.Forms.MouseButtons]::Right) { return }
$Script:startMouse = $script:form.PointToClient([System.Windows.Forms.Control]::MousePosition)
$Script:offset = $e.Location
if ($e.X -gt ($s.Width - $Script:threshold) -and $e.Y -gt ($s.Height - $Script:threshold)) {
$Script:isResizing = $true
} else {
$Script:isDragging = $true
}
$s.Capture = $true
}
})
$panel.Add_MouseMove({
param($s, $e)
$mousePos = $script:form.PointToClient([System.Windows.Forms.Control]::MousePosition)
if ($script:isEditMode) {
# つかむ前でもカーソルを変える
if (-not $Script:isDragging -and -not $Script:isResizing) {
if ($e.X -ge $s.Width - 10 -and $e.Y -ge $s.Height - 10) {
$s.Cursor = 'Cross' # リサイズ予告
} else {
$s.Cursor = 'SizeAll' # ドラッグ予告
}
}
}
if ($script:isEditMode -and ($Script:isDragging -or $Script:isResizing)) {
$offsetX = $mousePos.X - $Script:startMouse.X
$offsetY = $mousePos.Y - $Script:startMouse.Y
if ($Script:isDragging) {
$s.Left += $offsetX
if ($s.Left -lt 0) {$s.Left = 0}
$s.Top += $offsetY
if ($s.Top -lt 0) {$s.Top = 0}
$s.BackColor = 'Pink'
}
if ($Script:isResizing) {
$s.Width = [Math]::Max($MinButtonWidth, $s.Width + $offsetX)
$s.Height = [Math]::Max($MinButtonHeight, $s.Height + $offsetY)
$s.Invalidate()
$s.BackColor = 'DarkBlue'
}
$Script:startMouse = $mousePos
$statusText.Text = "Left:$($s.Left) Top:$($s.Top) Width:$($s.Width) Height:$($s.Height)"
}
})
$panel.Add_MouseUp({
param($s, $e)
Write-Host $Script:isDragging , $Script:isResizing
if ($Script:isDragging -or $Script:isResizing) {
Write-Host $s.Tag.Entry.データ
Set-ButtonGeometory -item $s
}
$Script:isDragging = $false
$Script:isResizing = $false
$s.Capture = $false
$s.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
#$s.Cursor = 'Hand'
})
# Write-Host "targetPanel: $($targetPanel -ne $null)"
# Write-Host "panel: $($panel -ne $null)"
# 子コントロールを追加
$targetPanel.Controls.Add($panel)
}
# アイコンをパネルに追加
function Add-Button {
for ($i = 0; $i -lt $script:menutable.Count; $i++) {
$item = $script:menutable[$i]
$btnId = [int]$item.ボタン番号
if ($btnId -eq 0) { continue }
if ($null -eq $item.グループ -or $item.グループ -eq "" -or $item.グループ -eq 0 -or $item.グループ -eq "0") {
$groupId = [int][math]::Ceiling($btnId / $btnCount)
$script:menutable[$i].グループ = $groupId # ← ここで元データに反映
} else {
$groupId = [int]$item.グループ
}
if ($item.種類 -eq "") {
$script:menutable[$i].種類 = Get-EntryType -data $item.データ
}
$script:menutable[$i].タイトル = $item.タイトル -replace "(`r`n|`r|`n)", ""
if (-not $groupPanels.ContainsKey($groupId)) {
$groupId = [int]$groupId
Add-NewPanel $groupId
}
Add-LauncherPanel $item $groupPanels[$groupId]
}
}
function Reset-Panels {
Write-Host "reset"
$currentId = $script:currentGroupId
Get-MenuTable
$deletePanels = @($groupPanels.Keys)
$script:form.SuspendLayout()
ForEach ($groupId in $deletePanels) {
$groupId = [int]$groupId
Add-NewPanel $groupId
}
Add-Button
$groupPanels[$currentId].BringToFront()
$groupRadios[$currentId].Checked = $true
$script:form.ResumeLayout()
}
# データ種類判定
function Get-EntryType {
param (
[string]$data
)
if ($data -match '"([^"]+)"') {
$data = $matches[1]
}
if ($data -eq "") {
return ''
} elseif ($data -match '(?i)^(?:https?|file)://\S+') {
return 'URL'
} elseif ($data -like '*.ps1') {
return 'PowerShell'
} elseif ($data -like '*.exe') {
return '実行'
} elseif ($data -match '\.cmd$|\.bat$') {
return '実行2'
} elseif ((Get-Item $data).PSIsContainer) {
return 'フォルダ'
} else {
return '開く'
}
}
# 文字数カウンタ
function Get-HalfWidthLength {
param($text)
return ($text -replace "[^\u0020-\u007E]", "11").Length
}
# フォーム作成
$script:form = New-Object System.Windows.Forms.Form
$script:form.Text = "ランチャー"
$script:form.Size = New-Object Drawing.Size($script:menutable[0].Width,$script:menutable[0].Height)
$script:form.StartPosition = "Manual" # 手動指定を有効化
$script:form.Location = New-Object Drawing.Point($script:menutable[0].Left, $script:menutable[0].Top)
$script:form.FormBorderStyle = 'None'
$script:form.GetType().GetProperty("DoubleBuffered", $flags).SetValue($script:form, $true, $null)
# 展開表示ボタン
$expandFormBtn = New-Object System.Windows.Forms.Button
$expandFormBtn.Text = "◆"
$expandFormBtn.Font = New-Object System.Drawing.Font("Meyrio",24,[System.Drawing.FontStyle]::Bold)
$expandFormBtn.TextAlign = 'BottomCenter'
#$expandFormBtn.FlatStyle = 'Standard'
$expandFormBtn.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$expandFormBtn.ForeColor = "LightGreen"
$expandFormBtn.Size = New-Object Drawing.Size($script:fold.w, $script:fold.h)
$expandFormBtn.Location = '0,0'
$expandFormBtn.Visible = $true
$script:form.Controls.Add($expandFormBtn)
# 右パネル
$rightPanel = New-Object System.Windows.Forms.Panel
$rightPanel.Dock = 'Fill'
$script:form.Controls.Add($rightPanel)
# 表示領域
$statusPanel = New-Object System.Windows.Forms.Panel
$statusPanel.Dock = 'Top'
$statusPanel.Height = $script:fold.h
$statusPanel.Padding = '0,0,0,0'
$statusPanel.BorderStyle = 'None'
$rightPanel.Controls.Add($statusPanel)
# 格納表示ボタン
$foldFormBtn = New-Object System.Windows.Forms.Button
$foldFormBtn.Text = "◇"
$foldFormBtn.Font = New-Object System.Drawing.Font("Meyrio",24,[System.Drawing.FontStyle]::Bold)
$foldFormBtn.TextAlign = 'BottomCenter'
$foldFormBtn.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$foldFormBtn.ForeColor = "LightGreen"
$foldFormBtn.Size = New-Object Drawing.Size($script:fold.w, $script:fold.h)
$foldFormBtn.Dock = 'Right'
$statusPanel.Controls.Add($foldFormBtn)
# ステータス表示テキストボックス
$statusText = New-Object System.Windows.Forms.TextBox
$statusText.Dock = 'Fill'
#$statusText.BorderStyle = 'None'
$statusText.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$statusText.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#ccc")
$statusText.Height = $script:fold.h
$statusText.Font = 'Meyrio,29'
$statusPanel.Controls.Add($statusText)
# 左メニューパネル
$menuPanel = New-Object System.Windows.Forms.Panel
$menuPanel.Size = '120,700'
$menuPanel.Dock = 'Left'
$script:form.Controls.Add($menuPanel)
# グループ選択ボタン用パネル(上寄せ)
$groupPanel = New-Object Windows.Forms.FlowLayoutPanel
$groupPanel.Dock = 'Fill'
$groupPanel.FlowDirection = 'TopDown'
$groupPanel.WrapContents = $false
$groupPanel.AutoScroll = $true
$groupPanel.Padding = '0,0,0,0'
$groupPanel.Font = New-Object System.Drawing.Font("Meyrio", 12)
$groupPanel.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$groupPanel.ForeColor = [System.Drawing.ColorTranslator]::FromHtml("#ccc")
$menuPanel.Controls.Add($groupPanel)
# 編集・追加ボタン用パネル(下寄せ)
$editPanel = New-Object Windows.Forms.Panel
$editPanel.Dock = 'Bottom'
$editPanel.BackColor = [System.Drawing.ColorTranslator]::FromHtml("#333")
$menuPanel.Controls.Add($editPanel)
# パネル追加ボタン
$addPanelBtn = New-Object System.Windows.Forms.Button
$addPanelBtn.Text = "パネル追加"
$addPanelBtn.Dock = 'Bottom'
$addPanelBtn.BackColor = 'LightGreen'
$addPanelBtn.Visible = $script:isEditMode
$editPanel.Controls.Add($addPanelBtn)
# パネル再構築ボタン
$resetBtn = New-Object System.Windows.Forms.Button
$resetBtn.Text = "リセット"
$resetBtn.Dock = 'Bottom'
$resetBtn.BackColor = 'LightBlue'
$resetBtn.Visible = $script:isEditMode
$editPanel.Controls.Add($resetBtn)
# 編集モードトグルボタン
$editToggle = New-Object System.Windows.Forms.CheckBox
$editToggle.Appearance = 'Button'
$editToggle.FlatStyle = 'Standard'
$editToggle.Text = "編集モード: OFF"
$editToggle.Checked = $script:isEditMode
$editToggle.Dock = 'Bottom'
$editToggle.BackColor = 'LightGray'
$editPanel.Controls.Add($editToggle)
# コンテキストメニュー作成
$editPanelContext = New-Object System.Windows.Forms.ContextMenuStrip
# 展開ボタン移動モードメニュー項目
$moveBtnItem = New-Object System.Windows.Forms.ToolStripMenuItem
$moveBtnItem.Text = "移動"
# セパレータ作成
$separator1 = New-Object System.Windows.Forms.ToolStripSeparator
# 編集モードメニュー項目
$editBtnItem = New-Object System.Windows.Forms.ToolStripMenuItem
$editBtnItem.Text = "編集"
# 編集モードメニュー項目
$editMenuItem = New-Object System.Windows.Forms.ToolStripMenuItem
$editMenuItem.Text = "編集メニュー"
# セパレータ作成
$separator2 = New-Object System.Windows.Forms.ToolStripSeparator
# スクリプトフォルダ開くメニュー項目
$openRootItem = New-Object System.Windows.Forms.ToolStripMenuItem
$openRootItem.Text = "フォルダを開く"
# 終了メニュー項目
$exitItem = New-Object System.Windows.Forms.ToolStripMenuItem
$exitItem.Text = "終了"
# 再起動メニュー項目
$restartItem = New-Object System.Windows.Forms.ToolStripMenuItem
$restartItem.Text = "再起動"
# メニューに追加
$editPanelContext.Items.AddRange(@(
$openRootItem,
$moveBtnItem,
$separator1,
$editBtnItem,
$editMenuItem,
$separator2,
$exitItem,
$restartItem
))
# パネルにメニューを割り当て
$editPanel.ContextMenuStrip = $editPanelContext
$expandFormBtn.ContextMenuStrip = $editPanelContext
$foldFormBtn.ContextMenuStrip = $editPanelContext
##########
#イベント
$script:form.Add_Resize({
Set-FormSizeSettings
})
# ドラッグ移動用イベント
$groupPanel.Add_MouseDown({
[NativeMethods]::ReleaseCapture() | Out-Null
[NativeMethods]::SendMessage($form.Handle, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
})
$editPanel.Add_MouseDown({
[NativeMethods]::ReleaseCapture() | Out-Null
[NativeMethods]::SendMessage($form.Handle, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
})
$expandFormBtn.Add_MouseDown({
if ($script:isMoveBtn) {
[NativeMethods]::ReleaseCapture() | Out-Null
[NativeMethods]::SendMessage($form.Handle, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
}
})
$expandFormBtn.Add_Click({
if ($script:isEditMode) { return }
Toggle-FormSize
})
$foldFormBtn.Add_Click({
if ($script:isEditMode) { return }
Toggle-FormSize
})
$foldFormBtn.Add_MouseDown({
if ($script:isMoveBtn) {
[NativeMethods]::ReleaseCapture() | Out-Null
[NativeMethods]::SendMessage($form.Handle, $WM_NCLBUTTONDOWN, $HTCAPTION, 0)
}
})
$statusText.Add_KeyDown({
param($s, $e)
if ($e.KeyCode -eq [System.Windows.Forms.Keys]::Enter) {
if ($s.Tag -ne "" -and $s.Text -ne "" -and $script:isEditMode){
$entry = $script:menutable | Where-Object { $_.ボタン番号 -eq $s.Tag }
$entry.タイトル = $s.Text
Save-MenuTable
Reset-Panels
}
}
})
$addPanelBtn.Add_Click({
Add-NewPanel
})
$resetBtn.Add_Click({
Save-MenuTable
Reset-Panels
})
$editToggle.Add_CheckedChanged({
Save-MenuTable
Toggle-EditMode
})
# コンテキストメニューイベント
$moveBtnItem.Add_Click({
Toggle-MoveButton
})
$editBtnItem.Add_Click({
$editToggle.Checked = -not $editToggle.Checked
})
$editMenuItem.Add_Click({
$script:isMenuPanel = -not $script:isMenuPanel
Toggle-MenuPanelView
})
$openRootItem.Add_Click({
Show-FoldForm
& explorer.exe "$PSScriptRoot"
})
$exitItem.Add_Click({
$form.Close()
})
$restartItem.Add_Click({
# 再起動処理(フォームを閉じて再度起動)
# Start-Process powershell -ArgumentList "-ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -File `"$PSCommandPath`""
Start-Process conhost.exe -ArgumentList "powershell -ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -File `"$PSCommandPath`""
$script:form.Close()
})
$script:form.Add_Paint({
param($s, $e)
if ( -not $script:isEditMode ) {
$g = $s.Graphics
$rect = $script:form.ClientRectangle
[System.Windows.Forms.ControlPaint]::DrawBorder(
$g, $rect,
[System.Drawing.Color]::Red, 3, 'Solid',
[System.Drawing.Color]::Red, 3, 'Solid',
[System.Drawing.Color]::Red, 3, 'Solid',
[System.Drawing.Color]::Red, 3, 'Solid'
)
}
})
$script:form.Add_Load({
# 設定読込
Get-MenuTable
# アイコンパネル生成
Add-Button
$script:form.Location = New-Object Drawing.Point($script:fold.x, $script:fold.y)
$script:form.Size = New-Object Drawing.Size($script:fold.w, $script:fold.h)
$menuPanel.Visible = $false
$editBtnItem.Enabled = $false
$editMenuItem.Enabled = $false
})
$script:form.Add_Shown({
$groupRadios[1].Checked = $true
$expandFormBtn.BringToFront()
if (-not $script:isMenuPanel -and $groupPanels.Keys.Count -gt 1) {
$script:isMenuPanel = $true
Toggle-MenuPanelView
}
})
$script:form.TopMost = $true
$script:form.ShowDialog()