mods/ps-always-on-top.psm1
|
# ====================================================================================== # ~/Source/mods/ps-always-on-top.psm1 # ====================================================================================== $signature = @" [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); public static IntPtr FindWindow(string windowName){ return FindWindow(null,windowName); } [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); const UInt32 SWP_NOSIZE = 0x0001; const UInt32 SWP_NOMOVE = 0x0002; const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE; public static void MakeTopMost (IntPtr fHandle) { SetWindowPos(fHandle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); } public static void MakeNormal (IntPtr fHandle) { SetWindowPos(fHandle, HWND_NOTOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS); } "@ # ====================================================================================== $app = Add-Type -MemberDefinition $signature -Name Win32Window -Namespace ScriptFanatic.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru # ====================================================================================== function Set-TopMost { param( [Parameter( Position=0,ValueFromPipelineByPropertyName=$true )][Alias('MainWindowHandle')]$hWnd=0, [Parameter()][switch]$Disable ) if($hWnd -ne 0) { if($Disable) { Write-Host "TODO - need a reset" -ForegroundColor "Cyan"; return; Write-Verbose "Set process handle :$hWnd to NORMAL state" $null = $app::MakeNormal($hWnd) return } Write-Verbose "Set process handle :$hWnd to TOPMOST state" $null = $app::MakeTopMost($hWnd) } else { Write-Verbose "$hWnd is 0" } } # -------------------------------------------------------------------------------------- function getOpenApplications(){ $openApplications = Get-Process | Where-Object {$_.MainWindowTitle -ne ""} | Select-Object MainWindowTitle #This block was for getting a windows explorer window, which supposedlly didn't get caught in the above line, but it is... #$a = New-Object -com "Shell.Application" #$b = $a.windows() | select-object LocationName #$c = "Windows Explorer: " + $b.LocationName #$openApplications += $c return $openApplications } # -------------------------------------------------------------------------------------- function Get-WindowByTitle($WindowTitle="*") { Write-Verbose "WindowTitle is: $WindowTitle" if($WindowTitle -eq "*") { Write-Verbose "WindowTitle is *, print all windows title" Get-Process | Where-Object {$_.MainWindowTitle} | Select-Object Id,Name,MainWindowHandle,MainWindowTitle } else { Write-Verbose "WindowTitle is $WindowTitle" Get-Process | Where-Object {$_.MainWindowTitle -like "*$WindowTitle*"} | Select-Object Id,Name,MainWindowHandle,MainWindowTitle } } # -------------------------------------------------------------------------------------- function forceApplicationOnTop($chosenApplication){ #Exaples: # set powershell console on top of other windows #gps powershell | Set-TopMost # unset #gps powershell | Set-TopMost -disable # set an application on top of other windows by its windows title (wildcard is supported) #Get-WindowByTitle *pad* | Set-TopMost # unset #Get-WindowByTitle textpad | Set-TopMost -Disable Write-Host "Chosen Window: "$chosenApplication # $openApplications = getOpenApplications # $openApplications | ForEach-Object { # Get-WindowByTitle $_.MainWindowTitle | Set-TopMost -Disable # } Get-WindowByTitle $chosenApplication | Set-TopMost } # -------------------------------------------------------------------------------------- function createDropdownBox($openApplications){ [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") $__SIZE_WIDTH_WINDOW = 500; $__SIZE_HEIGHT_WINDOW = 300; $__SIZE_WIDTH_LABEL = 280; $__SIZE_HEIGHT_LABEL = 20; $__SIZE_WIDTH_BUTTON = 75; $__SIZE_HEIGHT_BUTTON = 23; $__LOCATION_X_LABEL = $__SIZE_WIDTH_WINDOW * .03; $__LOCATION_Y_LABEL = $__SIZE_HEIGHT_WINDOW * .03; $__SIZE_WIDTH_LISTBOX = $__SIZE_WIDTH_WINDOW * .90; $__SIZE_HEIGHT_LISTBOX = ($__SIZE_HEIGHT_WINDOW * .50); $__LOCATION_X_BUTTON_OK = $__LOCATION_X_LABEL + $__SIZE_WIDTH_LISTBOX - $__SIZE_WIDTH_BUTTON; $__LOCATION_Y_BUTTON_OK = $__LOCATION_Y_LABEL + ($__SIZE_HEIGHT_LABEL * 2) + $__SIZE_HEIGHT_LISTBOX; $__LOCATION_X_BUTTON_CANCEL = $__LOCATION_X_BUTTON_OK - $__SIZE_WIDTH_BUTTON - $__SIZE_HEIGHT_LABEL; $__LOCATION_Y_BUTTON_CANCEL = $__LOCATION_Y_BUTTON_OK; $__LOCATION_X_LISTBOX = $__LOCATION_X_LABEL; $__LOCATION_Y_LISTBOX = $__LOCATION_Y_LABEL + ($__SIZE_HEIGHT_LABEL * 1.2); $objForm = New-Object System.Windows.Forms.Form $objForm.Text = "Always On Top" $objForm.Size = New-Object System.Drawing.Size($__SIZE_WIDTH_WINDOW,$__SIZE_HEIGHT_WINDOW) $objForm.StartPosition = "CenterScreen" $objForm.KeyPreview = $True $objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") {$x=$objListBox.SelectedItem;$objForm.Close()}}) $objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") {$objForm.Close()}}) $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Size($__LOCATION_X_BUTTON_OK,$__LOCATION_Y_BUTTON_OK) $OKButton.Size = New-Object System.Drawing.Size($__SIZE_WIDTH_BUTTON,$__SIZE_HEIGHT_BUTTON) $OKButton.Text = "OK" $OKButton.Add_Click({$x=$objListBox.SelectedItem;$objForm.Close()}) $objForm.Controls.Add($OKButton) $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Size($__LOCATION_X_BUTTON_CANCEL,$__LOCATION_Y_BUTTON_CANCEL) $CancelButton.Size = New-Object System.Drawing.Size($__SIZE_WIDTH_BUTTON,$__SIZE_HEIGHT_BUTTON) $CancelButton.Text = "Cancel" $CancelButton.Add_Click({$objForm.Close()}) $objForm.Controls.Add($CancelButton) $objLabel = New-Object System.Windows.Forms.Label $objLabel.Location = New-Object System.Drawing.Size($__LOCATION_X_LABEL,$__LOCATION_Y_LABEL) $objLabel.Size = New-Object System.Drawing.Size($__SIZE_WIDTH_LABEL,$__SIZE_HEIGHT_LABEL) $objLabel.Text = "Select a window to keep on top:" $objForm.Controls.Add($objLabel) $objListBox = New-Object System.Windows.Forms.ListBox $objListBox.Location = New-Object System.Drawing.Size($__LOCATION_X_LISTBOX,$__LOCATION_Y_LISTBOX) $objListBox.Size = New-Object System.Drawing.Size($__SIZE_WIDTH_LISTBOX,$__SIZE_HEIGHT_LISTBOX) $objListBox.Height = $__SIZE_HEIGHT_LISTBOX $openApplications | ForEach-Object { [void] $objListBox.Items.Add( $_.MainWindowTitle) } $objForm.Controls.Add($objListBox) $objForm.Topmost = $True $objForm.Add_Shown({$objForm.Activate()}) [void] $objForm.ShowDialog() $x=$objListBox.SelectedItem; return $x } # -------------------------------------------------------------------------------------- function ps-always-on-top { $openApplications = getOpenApplications $chosenApplication = createDropdownBox($openApplications) forceApplicationOnTop($chosenApplication) } # ====================================================================================== Export-ModuleMember -Function "ps-always-on-top"; # ====================================================================================== |