Search code examples
powershellcontextmenunotifyiconcontextmenustrip

How to remove checked margin in tray icon context menu


I've created this little script running in tray. I've noticed that contex menu text is not placed completely to the left. After a little investigation I found out that it is because there is a space left for .checked state indicator. I found out that it can be removed by .showcheckedmargin property of ContextMenuStrip but have no idea how to implement that. Please advise.

add-type -AssemblyName 'System.Windows.Forms'
Add-Type -AssemblyName 'System.Drawing'
Add-Type -AssemblyName 'PresentationFramework'


$2 = "BASE64 CODE"

$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($2)
$bitmap.EndInit()
$bitmap.Freeze()

$image = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($bitmap.StreamSource)

$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())

$app = New-Object System.Windows.Forms.NotifyIcon
$app.Text = ""
$app.Icon = $icon
$app.Visible = $true

$Zenek = New-Object System.Windows.Forms.MenuItem
$Zenek.Text = "Zenek"

$NetExt = New-Object System.Windows.Forms.MenuItem
$NetExt.Text = "NetExt"

$Busy = New-Object System.Windows.Forms.MenuItem
$Busy.Text = "BUSY"

$Time = New-Object System.Windows.Forms.MenuItem
$Time.Text = "Time"

$Exit = New-object System.Windows.Forms.MenuItem
$Exit.Text = "Exit"

$context = New-Object System.Windows.Forms.ContextMenu

$app.ContextMenu = $context
$app.ContextMenu.MenuItems.AddRange(@($Zenek, $NetExt, $Busy, $Time, $Exit))

$keepAwakeScript = {
    while (1) {
      $wsh = New-Object -ComObject WScript.Shell
      $wsh.SendKeys('+{F15}')
      Start-Sleep -seconds 59
    }
}


Start-Job -ScriptBlock $keepAwakeScript -Name "keepAwake"|out-null

$Zenek.Add_Click({Set-Clipboard -Value "SOME TEXT"})

$NetExt.Add_Click({Set-Clipboard -Value "SOME OTHER TEXT"})

$Busy.Add_Click({
$running = Get-Job|?{$_.Name -like 'KAPS'}

$icon = new-object System.Drawing.Icon("MY PRIVATE LOCATION\red.ico")
$app.Icon = $icon
if($running -eq $null){
Start-Job -Name KAPS -ScriptBlock{
while ($true){
$shell = New-Object -ComObject WScript.Shell
$shell.SendKeys('{CAPSLOCK}')
Start-Sleep 1
}
}
}else{
Stop-Job KAPS
Remove-Job KAPS
$icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
$app.Icon = $icon
}
})

$Time.Add_Click({



$main = New-Object System.Windows.Forms.Form
$main.ClientSize = '200,200'
$main.MinimizeBox = $false
$main.MaximizeBox = $false

$label = New-Object System.Windows.Forms.Label
$label.Size = '190,30'
$label.Location = '10,10'
$label.Text = 'Ile minut?'
$font = New-Object System.Drawing.Font("Arial", 23)
$label.Font = $font

$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Size = '50,100'
$textbox.Location = '10,70'

$button = New-Object System.Windows.Forms.Button
$button.Size = '50,50'
$button.Location = '10,120'
$button.Text = 'GO'
$button.Add_Click({
$timer.Start()
$textbox.Visible =$false
$button.Visible = $false
$label.Visible = $false
$script:1 = New-TimeSpan -minutes ([int]$textbox.Text)
$label2.Visible = $true
$label2.Text = $1.ToString("mm\:ss")
})

$timer = New-Object System.Windows.Forms.Timer
$timer.Enabled = $false
$timer.Interval = '1000'
$second = New-TimeSpan -Seconds 1
$timer.Add_Tick({

$script:1 = $1.Subtract($second)

$label2.Text = $1.ToString("mm\:ss")
if($script:1.TotalSeconds -le 0){$timer.Stop(); $timer.Dispose(); [System.Windows.Forms.Application]::SetSuspendState("Hibernate", $true, $false); $main.Close(); $main.Dispose()}


})

$label2 = New-Object System.Windows.Forms.Label
$label2.Size = '190,30'
$label2.Location = '10,10'
$label2.Text = $1
$font = New-Object System.Drawing.Font("Arial", 23)
$label2.Font = $font 
$label2.Visible = $false

$main.Controls.Add($textbox)
$main.Controls.Add($button)
$main.Controls.Add($label)
$main.Controls.Add($label2)
$main.ShowDialog()

})

$Exit.Add_Click({
    $app.Visible = $false
    Stop-Job -Name "keepAwake"
    $appContext.ExitThread()
    Stop-Process -Id $PID
})

$appContext = New-Object System.Windows.Forms.ApplicationContext
[void][System.Windows.Forms.Application]::Run($appContext)

Solution

  • For anyone with the same problem. I've managed to figure it out. Another post from SO allowed me to do so.

    I had to replace .ContextMenu with .ContextMenuStrip for the Menu itself, replace .MenuItem with .ToolStripMenuItem, add .ShowImageMargin to ContextMenuStrip variable, then finall add items via .Items.AddRange(@()).

    Before
    enter image description here
    After
    enter image description here

    In the end the code looks like this and works as intended.

    add-type -AssemblyName 'System.Windows.Forms'
    Add-Type -AssemblyName 'System.Drawing'
    Add-Type -AssemblyName 'PresentationFramework'
    
    
    $2 = 
    "BASE 64 CODE"
    
    $bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
    $bitmap.BeginInit()
    $bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($2)
    $bitmap.EndInit()
    $bitmap.Freeze()
    
    $image = [System.Drawing.Bitmap][System.Drawing.Image]::FromStream($bitmap.StreamSource)
    
    $icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
    
    $app = New-Object System.Windows.Forms.NotifyIcon
    $app.Text = ""
    $app.Icon = $icon
    $app.Visible = $true
    
    $Zenek = New-Object System.Windows.Forms.ToolStripMenuItem
    $Zenek.Text = "Zenek"
    $Zenek.Checked = $true
    
    $NetExt = New-Object System.Windows.Forms.ToolStripMenuItem
    $NetExt.Text = "NetExt"
    
    $Busy = New-Object System.Windows.Forms.ToolStripMenuItem
    $Busy.Text = "BUSY"
    
    $Time = New-Object System.Windows.Forms.ToolStripMenuItem
    $Time.Text = "Time"
    
    $Exit = New-object System.Windows.Forms.ToolStripMenuItem
    $Exit.Text = "Exit"
    
    $sep = New-Object System.Windows.Forms.ToolStripSeparator
    
    $context = New-Object System.Windows.Forms.ContextMenuStrip
    $context.ShowImageMargin = $false
    $context.Items.AddRange(@($Zenek, $NetExt, $Busy, $Time, $sep, $Exit))
    
    $app.ContextMenuStrip = $context
    
    
    
    $keepAwakeScript = {
        while (1) {
          $wsh = New-Object -ComObject WScript.Shell
          $wsh.SendKeys('+{F15}')
          Start-Sleep -seconds 59
        }
    }
    
    
    Start-Job -ScriptBlock $keepAwakeScript -Name "keepAwake"|out-null
    
    $Zenek.Add_Click({Set-Clipboard -Value "SOME TEXT"})
    
    $NetExt.Add_Click({Set-Clipboard -Value "SOME OTHER TEXT"})
    
    $Busy.Add_Click({
    $running = Get-Job|?{$_.Name -like 'KAPS'}
    
    $icon = new-object System.Drawing.Icon("MY PRIVATE LOCATION\red.ico")
    $app.Icon = $icon
    if($running -eq $null){
    Start-Job -Name KAPS -ScriptBlock{
    while ($true){
    $shell = New-Object -ComObject WScript.Shell
    $shell.SendKeys('{CAPSLOCK}')
    Start-Sleep 1
    }
    }
    }else{
    Stop-Job KAPS
    Remove-Job KAPS
    $icon = [System.Drawing.Icon]::FromHandle($image.GetHicon())
    $app.Icon = $icon
    }
    })
    
    $Time.Add_Click({
    
    
    
    $main = New-Object System.Windows.Forms.Form
    $main.ClientSize = '200,200'
    $main.MinimizeBox = $false
    $main.MaximizeBox = $false
    
    $label = New-Object System.Windows.Forms.Label
    $label.Size = '190,30'
    $label.Location = '10,10'
    $label.Text = 'Ile minut?'
    $font = New-Object System.Drawing.Font("Arial", 23)
    $label.Font = $font
    
    $textbox = New-Object System.Windows.Forms.TextBox
    $textbox.Size = '50,100'
    $textbox.Location = '10,70'
    
    $button = New-Object System.Windows.Forms.Button
    $button.Size = '50,50'
    $button.Location = '10,120'
    $button.Text = 'GO'
    $button.Add_Click({
    $timer.Start()
    $textbox.Visible =$false
    $button.Visible = $false
    $label.Visible = $false
    $script:1 = New-TimeSpan -minutes ([int]$textbox.Text)
    $label2.Visible = $true
    $label2.Text = $1.ToString("mm\:ss")
    })
    
    $timer = New-Object System.Windows.Forms.Timer
    $timer.Enabled = $false
    $timer.Interval = '1000'
    $second = New-TimeSpan -Seconds 1
    $timer.Add_Tick({
    
    $script:1 = $1.Subtract($second)
    
    $label2.Text = $1.ToString("mm\:ss")
    if($script:1.TotalSeconds -le 0){$timer.Stop(); $timer.Dispose(); [System.Windows.Forms.Application]::SetSuspendState("Hibernate", $true, $false); $main.Close(); $main.Dispose()}
    
    
    })
    
    $label2 = New-Object System.Windows.Forms.Label
    $label2.Size = '190,30'
    $label2.Location = '10,10'
    $label2.Text = $1
    $font = New-Object System.Drawing.Font("Arial", 23)
    $label2.Font = $font 
    $label2.Visible = $false
    
    $main.Controls.Add($textbox)
    $main.Controls.Add($button)
    $main.Controls.Add($label)
    $main.Controls.Add($label2)
    $main.ShowDialog()
    
    })
    
    $Exit.Add_Click({
        $app.Visible = $false
        Stop-Job -Name "keepAwake"
        $appContext.ExitThread()
        #Stop-Process -Id $PID
    })
    
    $appContext = New-Object System.Windows.Forms.ApplicationContext
    [void][System.Windows.Forms.Application]::Run($appContext)