# PackageWindowsFunctions.ps1 # Require : PackageDebugTools.ps1 # function Invoke-Win32 (http://www.leeholmes.com/blog/GetTheOwnerOfAProcessInPowerShellPInvokeAndRefOutParameters.aspx) # # Contient une suite d'API Windows encapsulées (P/Invoke). # # Documentation # Windows référence-functions : http://msdn.microsoft.com/en-us/library/ms674884(VS.85).aspx # UnmanagedType, énumération : http://msdn.microsoft.com/fr-fr/library/system.runtime.interopservices.unmanagedtype(VS.80).aspx # Marshaling d'interopérabilité : http://msdn.microsoft.com/fr-fr/library/04fy9ya1.aspx # Types de données d'appel de plate-forme : http://msdn.microsoft.com/fr-fr/library/ac7ay120.aspx # C et les constantes littérales : http://c.developpez.com/cours/poly-c/?page=page_1#LI-C # Constantes P/Invoke : http://pinvoke.net/default.aspx/Constants/HWND.html# # # # Version : 1.2.4 # Auteur : Laurent Dardenne # Remerciements à Medinoc pour ces précisions sur les tranformations du typage C vers .NET # http://www.developpez.net/forums/u72598/medinoc/ # Date : 5/04/2009 # testée sous PS1 XP sp3 - 32 Bits # # Fonctions implémentées : # # function d'initialisation # function Set-Constant( [string] $VariableName, [HashTable] $Data, [String] $Description) # function Set-cstApiWindows # # Functions Windows # function ShowWindowAsync([IntPtr] $hWnd, [Int32] $nCmdShow) # function SetActiveWindow([IntPtr] $hWnd) # function SendMessage([IntPtr] $hWnd, [Int32] $message, [Int32] $wParam, [Int32] $lParam) # function GetConsoleWindow() # function BringWindowToTop([IntPtr] $hWnd) # function SetWindowPos([IntPtr] $hWnd, [IntPtr] $hWndInsertAfter, [Int32] $X, [Int32] $Y, [Int32] $cx, [Int32] $cy, [UInt32] $uFlags) # function SetFocus([IntPtr] $hWnd) # function SwitchToThisWindow([IntPtr] $hWnd, [Boolean] $fAltTab=$false) # function SetForegroundWindow([IntPtr] $hWnd) # function GetWindowRect([IntPtr] $hWnd, [REF] $lpRect) # function MoveWindow([IntPtr] $hWnd, [Int32] $X, [Int32] $Y, [Int32] $nWidth, [Int32] $nHeight,[Int32] $bRepaint) # function FindWindow([String] $lpClassName, [string] $lpWindowName) # function GetTopWindow([IntPtr] $hWnd) # function CallWindowProc([IntPtr] $lpPrevWndFunc, [IntPtr] $hWnd, [UInt32] $Msg, [IntPtr] $wParam, [IntPtr] $lParam) # function IsIconic([IntPtr] $hWnd) # function IsWindowVisible([IntPtr] $hWnd) # function IsZoomed([IntPtr] $hWnd) # function IsHungAppWindow([IntPtr] $hWnd) # function GetWindowLong([IntPtr] $hWnd, [Int32] $nIndex) # function SetWindowLong([IntPtr] $hWnd, [Int32] $nIndex, [Int32] $dwNewLong) # # Functions Menu # function GetSystemMenu([IntPtr] $hWnd, [Boolean] $bRevert) # function AppendMenu([IntPtr] $hMenu, [UInt32] $uFlags, [UInt32] $uIDNewItem,[String] $lpNewItem) # function RemoveMenu([IntPtr] $hMenu, [Int32] $uPosition, [Int32] $uFlags) # function GetMenuItemCount([IntPtr] $hMenu) # function EnableMenuItem([IntPtr] $hMenu, [Int32] $uIDEnableItem, [Int32] $uEnable) # function GetMenuState([IntPtr] $hMenu, [UInt32] $uId, [UInt32] $uFlags) # function InsertMenu([IntPtr] $hMenu,[UInt32] $Position, [UInt32] $Flags, [UInt32] $NewId,[String] $Item ) # function DestroyMenu([IntPtr] $hMenu) # function DrawMenuBar([IntPtr] $hMenu) # # Function Tools # function Show-PSWindow([IntPtr] $WindowHandle=$PSWindowHandle){ # function Hide-PSWindow([IntPtr] $WindowHandle=$PSWindowHandle) { # function Minimize-PowerShell([IntPtr] $WindowHandle=$PSWindowHandle) { # function Set-ForegroundWindow ([IntPtr] $WindowHandle=$PSWindowHandle) { # Function Set-ConsoleIcon([string] $iconFile) # function Enable-MenuItem([IntPtr] $hMenu, [Int32] $uIDEnableItem) # function Disable-MenuItem([IntPtr] $hMenu, [Int32] $uIDEnableItem) # function Remove-CloseMenu([IntPtr] $hMenu) # function Add-CloseMenu([IntPtr] $hMenu) # function Remove-MinimizeMenu([IntPtr] $hMenu) # function Add-MinimizeMenu([IntPtr] $hMenu) # function StayOnTop([IntPtr] $WindowHandle=$PSWindowHandle, [switch] $OFF) # templates : # # function ([IntPtr] $hWnd) # { # $parameterTypes = [IntPtr] # $parameters = $hWnd # # Invoke-Win32 "user32.dll" ([Boolean]) "" $parameterTypes $parameters # } # function ([] $ ,[] $) # { # $parameterTypes = [],[] # $parameters = $ ,$ # Invoke-Win32 "" ([Boolean]) "" $parameterTypes $parameters # } # # Limitation sous PS V1 : "Version 1 of PowerShell doen't natively support unsigned types." Bruce payette # http://www.vistax64.com/powershell/11103-cant-create-uint32-values-outside-int32-range.html # if( $Env:PROCESSOR_ARCHITECTURE -ne "x86") {Throw "Les fonctions contenues dans le fichier PackageWindowsFunctions.ps1 n'ont pas été testées sous x64."} #Déclare une variable contenant le handle de la fenêtre de PowerShell if ( -not (Test-Path Variable:PSWindowHandle)) { Set-Variable PSWindowHandle -value ((Get-Process -Id $pid).MainWindowHandle) -option Constant} function Set-Constant( [string] $VariableName, [HashTable] $Data, [String] $Description, [Int32] $Scope=1) { #Crée une variable constante de nom $VariableName dans la portée de l'appelant #La variable est créé par défaut dans la portée de l'appelant, sinon dans celle précisée par $Scope # #Exemple : # $Const=@{ # NomConstante=[Intptr] 567} # Set-Constant "cConst" $Const "Constantes test" # #Pour chaque entrée de la hashtable $DATA on crée un membre de type ScriptProperty en lecture seule : # cConst.NomConstante {get=[System.IntPtr] 567;set=Throw "La propriété NomConstante est en lecture seule.";} # #Pour retrouver les constantes : dir variable:c*|Where { (gv $_.name).options -match "constant"} if ( !(Test-Path Variable:$VariableName) ) { Write-Debug "La variable $VariableName n'existe pas.`r`nPile d'appel : $(ParseStack $(Get-CallStack))" $obj= New-Object PSObject $VariableName #Ajoute le nom de la variable d'origine car $this à pour nom "this" :/ . #Ainsi en cas d'erreur on peut indiquer quelle variable est concernée. $Code="`$obj| add-member -memberType Scriptproperty -Name Name -value {`"$VariableName`"} -SecondValue {Throw `"La propriété $VariableName est en lecture seule.`"}" invoke-expression $Code $Code=$null #Dans les appels d'API on avoir à additionner plusieurs valeurs : # $cApiWindows.SWP_NOSIZE + $cApiWindows.SWP_NOMOVE + $cApiWindows.SWP_NOZORDER + $cApiWindows.SWP_NOACTIVATE + $cApiWindows.SWP_SHOWWINDOW #On facilite donc la saisie en ajoutant une méthode Add. # $cApiWindows.Add("SWP_NOSIZE","SWP_NOMOVE","SWP_NOZORDER","SWP_NOACTIVATE","SWP_SHOWWINDOW") $obj| add-member -memberType ScriptMethod -name Add { #Additionne le contenu des noms de propriétés, de l'objet courant $this, passées en paramètre. # Si add("P1") renvoi la valeur de $this.p1 # Si add("P1","P2") renvoi la somme de $this.p1 + $this.p2 # Si add() renvoi $NULL # Si add("Propriété inconnue") déclenche une exception # $Args est un tableau d'objet, on le cast en un tableau de chaîne $Parameters=$Args -as [String[]] if ($Parameters.count -ne 0) { $Result=0; $Parameters|Foreach { if ($this."$_" -eq $null) {Throw "Le nom de propriété $_ n'existe pas pour la variable $($this.Name)."} $Result +=$this."$_" Write-Debug "$($this.Name).Add() : $_`tResult=$Result" }#For $Result }#If count = 0 else { Write-Debug "$($this.Name).Add(): le tableau d'arguments est vide." $null } } # ScriptMethod Add $Data.GetEnumerator()|` %{ #Construit le code de la création d'un objet ayant des propriétés en lecture seule $TypeName="" if ($_.Value -ne $null) {$TypeName=$_.Value.GetType().FullName} else {Write-Error "La valeur de la clé $($_.Key) est null."} Write-Debug ("Key :{0} Value:{1} [{2}]" -F $_.Key,$_.Value,$TypeName) $C1="`$obj| add-member -memberType Scriptproperty" $C2="-Name $($_.Key)" $C3="-value {[$TypeName] $($_.Value)}" $C4="-SecondValue {Throw `"La propriété $($_.Key) est en lecture seule.`"}" $Code="$C1 $C2 $C3 $C4" #Exécute le code créé invoke-expression $Code }#Foreach #on évite de nombreuses variables globales au prix de possible constructions fréquentes Set-Variable $VariableName -value $Obj -option constant -scope $Scope -description $Description } else { Write-Warning "La variable $VariableName existe déjà." Write-Debug "Pile d'appel : $(ParseStack $(Get-CallStack))" } } $APIConst=@{ HWND_TOP=[Intptr]0 HWND_BOTTOM=[Intptr]1 HWND_TOPMOST=[Intptr]-1 HWND_NOTOPMOST=[Intptr]-2 ICON_SMALL =[IntPtr]0 #typedef UINT WPARAM =[IntPtr] #BS_PUSHBUTTON=[IntPtr]0 # typedef LONG LPARAM = [IntPtr] GWL_WNDPROC =[Int32]-4 GWL_HINSTANCE =[Int32]-6 GWL_HWNDPARENT =[Int32]-8 GWL_STYLE =[Int32]-16 GWL_EXSTYLE =[Int32]-20 GWL_USERDATA =[Int32]-21 GWL_ID =[Int32]-12 DWL_MSGRESULT =[Int32]0 DWL_DLGPROC =[Int32]4 DWL_USER =[Int32]8 MF_BYCOMMAND =[UInt32]0 MF_BYPOSITION =[UInt32]1024 MF_STRING =[UInt32]0 MF_BITMAP =[UInt32]4 MF_OWNERDRAW =[UInt32]256 MF_ENABLED =[UInt32]0 MF_GRAYED =[UInt32]1 MF_DISABLED =[UInt32]2 SC_SIZE =[UInt32] 0xF000 SC_MOVE =[UInt32] 0xF010 SC_MINIMIZE =[UInt32] 0xF020 SC_MAXIMIZE =[UInt32] 0xF030 SC_NEXTWINDOW =[UInt32]0xF040 SC_PREVWINDOW=[UInt32]0xF050 SC_CLOSE =[UInt32]0xF060 SC_VSCROLL=[UInt32]0xF070 SC_HSCROLL=[UInt32]0xF080 SC_MOUSEMENU=[UInt32]0xF090 SC_KEYMENU =[UInt32]0xF100 SC_ARRANGE =[UInt32]0xF110 SC_RESTORE =[UInt32]0xF120 SC_TASKLIST =[UInt32]0xF130 SC_SCREENSAVE =[UInt32]0xF140 SC_HOTKEY =[UInt32]0xF150 SC_DEFAULT =[UInt32]0xF160 SC_MONITORPOWER =[UInt32]0xF170 SC_CONTEXTHELP =[UInt32]0xF180 SC_SEPARATOR =[UInt32]0xF00F SW_HIDE =[Int32]0 SW_SHOWNORMAL =[Int32]1 SW_NORMAL =[Int32]1 SW_SHOWMINIMIZED =[Int32]2 SW_SHOWMAXIMIZED =[Int32]3 SW_MAXIMIZE =[Int32]3 SW_SHOWNOACTIVATE =[Int32]4 SW_SHOW =[Int32]5 SW_MINIMIZE =[Int32]6 SW_SHOWMINNOACTIVE =[Int32]7 SW_SHOWNA =[Int32]8 SW_RESTORE =[Int32]9 SW_SHOWDEFAULT =[Int32]10 SW_MAX =[Int32]10 SWP_NOSIZE =[UInt32]1 SWP_NOMOVE =[UInt32]2 SWP_NOZORDER =[UInt32]4 SWP_NOREDRAW =[UInt32]8 SWP_NOACTIVATE =[UInt32]16 SWP_FRAMECHANGED =[UInt32]32 SWP_SHOWWINDOW =[UInt32]64 SWP_HIDEWINDOW =[UInt32]128 SWP_NOCOPYBITS =[UInt32]256 SWP_NOOWNERZORDER =[UInt32]512 SWP_NOSENDCHANGING =[UInt32]1204 SWP_DRAWFRAME =[UInt32]32 #SWP_FRAMECHANGED SWP_NOREPOSITION =[UInt32]512 #SWP_NOOWNERZORDER SWP_DEFERERASE =[UInt32]8192 SWP_ASYNCWINDOWPOS =[UInt32]16384 WM_SETICON =[UInt32]0x0080 # Window Styles WS_OVERLAPPED =[UInt32]0 #Pour la valeur 0x80000000, les guillemets forcent #sa prise en compte en tant qu'entier non-signé. WS_POPUP =[UInt32]"0x80000000" #Ou [UInt32]0x80000000L (2 conversions) WS_CHILD =[UInt32]0x40000000 WS_MINIMIZE =[UInt32]0x20000000 WS_VISIBLE =[UInt32]0x10000000 WS_DISABLED =[UInt32]0x08000000 WS_CLIPSIBLINGS =[UInt32]0x04000000 WS_CLIPCHILDREN =[UInt32]0x02000000 WS_MAXIMIZE =[UInt32]0x01000000 WS_CAPTION =[UInt32]0x00C00000# WS_BORDER or WS_DLGFRAME WS_BORDER =[UInt32]0x00800000 WS_DLGFRAME =[UInt32]0x00400000 WS_VSCROLL =[UInt32]0x00200000 WS_HSCROLL =[UInt32]0x00100000 WS_SYSMENU =[UInt32]0x00080000 WS_THICKFRAME =[UInt32]0x00040000 WS_GROUP =[UInt32]0x00020000 WS_TABSTOP =[UInt32]0x00010000 WS_MINIMIZEBOX =[UInt32]0x00020000 WS_MAXIMIZEBOX =[UInt32]0x00010000 WS_TILED =[UInt32]0 #WS_OVERLAPPED WS_ICONIC =[UInt32]0x20000000 #WS_MINIMIZE WS_SIZEBOX =[UInt32]0x00040000 #WS_THICKFRAME #Common Window Styles #(WS_OVERLAPPED -bor WS_CAPTION -bor WS_SYSMENU -bor WS_THICKFRAME -bor WS_MINIMIZEBOX -bor WS_MAXIMIZEBOX) WS_OVERLAPPEDWINDOW =[UInt32](0 -bor 0x00C00000 -bor 0x00080000 -bor 0x00040000 -bor 0x00020000 -bor 0x00010000) # =WS_OVERLAPPEDWINDOW WS_TILEDWINDOW =[UInt32](0 -bor 0x00C00000 -bor 0x00080000 -bor 0x00040000 -bor 0x00020000 -bor 0x00010000) #(WS_POPUP or WS_BORDER or WS_SYSMENU) # *** Construction impossible : [UInt32]("0x80000000" -bor 0x00800000 -bor 0x00080000) *** WS_POPUPWINDOW =[uint32](0x80000000L + 0x00800000L + 0x00080000L) # WS_CHILD WS_CHILDWINDOW =[UInt32]0x40000000 # Extended Window Styles WS_EX_DLGMODALFRAME =[UInt32]1 WS_EX_NOPARENTNOTIFY =[UInt32]4 WS_EX_TOPMOST =[UInt32]8 WS_EX_ACCEPTFILES =[UInt32]0x10 WS_EX_TRANSPARENT =[UInt32]0x20 WS_EX_MDICHILD =[UInt32]0x40 WS_EX_TOOLWINDOW =[UInt32]0x80 WS_EX_WINDOWEDGE =[UInt32]0x100 WS_EX_CLIENTEDGE =[UInt32]0x200 WS_EX_CONTEXTHELP =[UInt32]0x400 WS_EX_RIGHT =[UInt32]0x1000 WS_EX_LEFT =[UInt32]0 WS_EX_RTLREADING =[UInt32]0x2000 WS_EX_LTRREADING =[UInt32]0 WS_EX_LEFTSCROLLBAR =[UInt32]0x4000 WS_EX_RIGHTSCROLLBAR =[UInt32]0 WS_EX_CONTROLPARENT =[UInt32]0x10000 WS_EX_STATICEDGE =[UInt32]0x20000 WS_EX_APPWINDOW =[UInt32]0x40000 # (WS_EX_WINDOWEDGE -bor WS_EX_CLIENTEDGE) WS_EX_OVERLAPPEDWINDOW =[UInt32](0x100 -bor 0x200) #(WS_EX_WINDOWEDGE -bor WS_EX_TOOLWINDOW -bor WS_EX_TOPMOST) WS_EX_PALETTEWINDOW =[UInt32](0x100 -bor 0x80 -bor 8) WS_EX_LAYERED =[UInt32]0x00080000 WS_EX_NOINHERITLAYOUT =[UInt32]0x00100000 #Disable inheritence of mirroring by children WS_EX_LAYOUTRTL =[UInt32]0x00400000 #Right to left mirroring WS_EX_COMPOSITED =[UInt32]0x02000000 WS_EX_NOACTIVATE =[UInt32]0x08000000 }#APIConst #Crée dans la portée de l'appelant la constante globale nommée cApiWindows. #Cette constante est utilisée par les fonctions qui suivent. Set-Constant "cApiWindows" $APIConst "Constantes des API Windows Win32" remove-variable APIConst #Functions Windows function ShowWindowAsync([IntPtr] $hWnd, [Int32] $nCmdShow) { $parameterTypes = [IntPtr], [Int32] $parameters = $hWnd, $nCmdShow Invoke-Win32 "user32.dll" ([Boolean]) "ShowWindowAsync" $parameterTypes $parameters # possible Valeurs du paramètre nCmdShow # $SW_HIDE = 0; # $SW_SHOWNORMAL = 1; # $SW_NORMAL = 1; # $SW_SHOWMINIMIZED = 2; # $SW_SHOWMAXIMIZED = 3; # $SW_MAXIMIZE = 3; # $SW_SHOWNOACTIVATE = 4; # $SW_SHOW = 5; # $SW_MINIMIZE = 6; # $SW_SHOWMINNOACTIVE = 7; # $SW_SHOWNA = 8; # $SW_RESTORE = 9; # $SW_SHOWDEFAULT = 10; # $SW_MAX = 10 } function SetActiveWindow([IntPtr] $hWnd) { #The SetActiveWindow function activates a window, but not if the application is #in the background. The window will be brought into the foreground (top of Z-Order) #if its application is in the foreground when the system activates the window. $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([IntPtr]) "SetActiveWindow" $parameterTypes $parameters } function SendMessage([IntPtr] $hWnd, [Int32] $message, [Int32] $wParam, [Int32] $lParam) { #Envoi un message à une fenêtre $parameterTypes = [IntPtr], [Int32], [Int32], [Int32] $parameters = $hWnd, $message, $wParam, $lParam Invoke-Win32 "user32.dll" ([Int32]) "SendMessage" $parameterTypes $parameters } function GetConsoleWindow() { #récupère le handle de la console courante, celui de la session powershell. # Récupération Possible directement par : # $MyHandle=(Get-Process –id $pid).MainWindowHandle Invoke-Win32 "kernel32" ([IntPtr]) "GetConsoleWindow" } function BringWindowToTop([IntPtr] $hWnd) { #Place la fenêtre au premier plan, peut nécessiter une combinaison d'appel d'autres API $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([Boolean]) "BringWindowToTop" $parameterTypes $parameters } function SetWindowPos([IntPtr] $hWnd, [IntPtr] $hWndInsertAfter, [Int32] $X, [Int32] $Y, [Int32] $cx, [Int32] $cy, [UInt32] $uFlags) { #Modifie les coordonnées et le style d'une fenêtre. $parameterTypes = [IntPtr] , [IntPtr] , [Int32] , [Int32] , [Int32], [Int32] , [UInt32] $parameters = $hWnd, $hWndInsertAfter, $X, $Y, $cx, $cy, $uFlags Invoke-Win32 "user32.dll" ([Boolean]) "SetWindowPos" $parameterTypes $parameters # $X : Specifies the new position of the left side of the window, in client coordinates. # $Y : Specifies the new position of the top of the window, in client coordinates. # $cx : Specifies the new width of the window, in pixels. # $cy : Specifies the new height of the window, in pixels. #Possible valeurs du paramètre $hWndInsertAfter # HWND_TOP=0 -as [Intptr] # HWND_BOTTOM=1 -as [Intptr] # HWND_TOPMOST=-1 -as [Intptr] # HWND_NOTOPMOST=-2 -as [Intptr] #Combinaison des possibles valeurs du paramètre $uFlags # SWP_NOSIZE = 1; # SWP_NOMOVE = 2; # SWP_NOZORDER = 4; # SWP_NOREDRAW = 8; # SWP_NOACTIVATE = 16; # SWP_FRAMECHANGED = 32; # SWP_SHOWWINDOW = 64; # SWP_HIDEWINDOW = 128; # SWP_NOCOPYBITS = 256; # SWP_NOOWNERZORDER = 512; # SWP_NOSENDCHANGING = 1204; # SWP_DRAWFRAME = 32; #SWP_FRAMECHANGED # SWP_NOREPOSITION =512; #SWP_NOOWNERZORDER # SWP_DEFERERASE = 8192; # SWP_ASYNCWINDOWPOS = 16384; } function SetFocus([IntPtr] $hWnd) { #Donne le focus à une fenêtre mais ne la place pas au premier plan, peut nécessiter une combinaison d'appels à d'autres API $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([IntPtr]) "SetFocus" $parameterTypes $parameters } function SwitchToThisWindow([IntPtr] $hWnd, [Boolean] $fAltTab=$false) { #The SwitchToThisWindow function is called to switch focus to a specified window #and bring it to the foreground. $parameterTypes = [IntPtr], [boolean] $parameters = $hWnd,$fAltTab Invoke-Win32 "user32.dll" ([Void]) "SwitchToThisWindow" $parameterTypes $parameters } function SetForegroundWindow([IntPtr] $hWnd) { #The SetForegroundWindow function puts the thread that created the specified window #into the foreground and activates the window. Keyboard input is directed to the window, #and various visual cues are changed for the user. The system assigns a slightly #higher priority to the thread that created the foreground window than it does to #other threads. $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([Boolean]) "SetForegroundWindow" $parameterTypes $parameters } function GetWindowRect([IntPtr] $hWnd, [REF] $lpRect) { #Obtient les dimensions de la fenêtre possédant le handle $hWnd # *Attention* le premier appel à cette API peut échouer pour une raison inconnue ( ps v1 et ps v2 ctp2). # Exception calling "InvokeMember" with "5" argument(s): "Méthode 'PInvokeType.GetWindowRect' introuvable." # le second apple réussie. $parameterTypes = [IntPtr],[REF] $parameters = $hWnd,$lpRect Invoke-Win32 "user32.dll" ([Int32]) "GetWindowRect" $parameterTypes $parameters } function MoveWindow([IntPtr] $hWnd, [Int32] $X, [Int32] $Y, [Int32] $nWidth, [Int32] $nHeight,[Int32] $bRepaint) { #The MoveWindow function changes the position and dimensions of the specified window. For a top-level window, #the position and dimensions are relative to the upper-left corner of the screen. #For a child window, they are relative to the upper-left corner of the parent window's client area. $parameterTypes = [IntPtr], [Int32], [Int32], [Int32], [Int32], [Int32] $parameters = $hWnd, $X, $Y, $nWidth, $nHeight, $bRepaint Invoke-Win32 "user32.dll" ([Boolean]) "MoveWindow" $parameterTypes $parameters } function FindWindow([String] $lpClassName, [string] $lpWindowName) { #The FindWindow function retrieves a handle to the top-level window whose class name and #window name match the specified strings. This function does not search child windows. #This function does not perform a case-sensitive search. # #To search child windows, beginning with a specified child window, use the FindWindowEx function. $parameterTypes = [String], [String] $parameters = $lpClassName, $lpWindowName Invoke-Win32 "user32.dll" ([IntPtr]) "FindWindow" $parameterTypes $parameters } function GetTopWindow([IntPtr] $hWnd) { $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([IntPtr]) "" $parameterTypes $parameters } function CallWindowProc([IntPtr] $lpPrevWndFunc, [IntPtr] $hWnd, [UInt32] $Msg, [IntPtr] $wParam, [IntPtr] $lParam) { $parameterTypes = [IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr] $parameters = $lpPrevWndFunc, $hWnd, $Msg, $wParam, $lParam Invoke-Win32 "user32.dll" ([IntPtr]) "CallWindowProc" $parameterTypes $parameters } function IsIconic([IntPtr] $hWnd) { #La fenêtre est-elle minimisée ? $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([Boolean]) "IsIconic" $parameterTypes $parameters } function IsWindowVisible([IntPtr] $hWnd) { #la fenêtre (ou un contrôle) est-elle visible ? $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([Boolean]) "IsWindowVisible" $parameterTypes $parameters } function IsZoomed([IntPtr] $hWnd) { #La fenêtre est-elle maximisée ? $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([Boolean]) "IsZoomed" $parameterTypes $parameters } function IsHungAppWindow([IntPtr] $hWnd) { #L'application répond elle ? $parameterTypes = [IntPtr] $parameters = $hWnd Invoke-Win32 "user32.dll" ([Boolean]) "IsHungAppWindow" $parameterTypes $parameters } function GetWindowLong([IntPtr] $hWnd, [Int32] $nIndex) { $parameterTypes = [IntPtr] , [Int32] $parameters = $hWnd, $nIndex Invoke-Win32 "user32.dll" ([Int32]) "GetWindowLong" $parameterTypes $parameters } function SetWindowLong([IntPtr] $hWnd, [Int32] $nIndex, [Int32] $dwNewLong) { $parameterTypes = [IntPtr] , [Int32] , [Int32] $parameters = $hWnd, $nIndex,$dwNewLong Invoke-Win32 "user32.dll" ([Int32]) "SetWindowLong" $parameterTypes $parameters } #Functions Menu function GetSystemMenu([IntPtr] $hWnd, [Boolean] $bRevert) { #Obtient le handle du menu system d'une fenêtre $parameterTypes = [IntPtr],[Boolean] $parameters = $hWnd,$bRevert Invoke-Win32 "user32.dll" ([IntPtr]) "GetSystemMenu" $parameterTypes $parameters } function AppendMenu([IntPtr] $hMenu, [UInt32] $uFlags, [UInt32] $uIDNewItem,[String] $lpNewItem) { #Ajoute une entrée de menu. voir DrawMenuBar $parameterTypes = [IntPtr], [UInt32], [UInt32],[String] $parameters = $hMenu, $uFlags, $uIDNewItem, $lpNewItem Invoke-Win32 "user32.dll" ([Boolean]) "AppendMenu" $parameterTypes $parameters # $MF_STRING = 0 # $MF_BITMAP = 4 # $MF_OWNERDRAW = 256 } function RemoveMenu([IntPtr] $hMenu, [Int32] $uPosition, [Int32] $uFlags) { #Supprime une entrée de menu. $parameterTypes = [IntPtr],[Int32],[Int32] $parameters = $hMenu,$uPosition,$uFlags Invoke-Win32 "user32.dll" ([Boolean]) "RemoveMenu" $parameterTypes $parameters #Valeur des menus, il est possible de les utiliser pour $uPosition # $SC_SIZE = 61440; # $SC_MOVE = 61456; # $SC_MINIMIZE = 61472; # $SC_MAXIMIZE = 61488; # $SC_RESTORE = 61728; # $SC_SEPARATOR = 61455; # $SC_CLOSE = 61536; # Menu "Modifier" # $SC_DEFAULT = 61792; # Menu "Propriétés" #Valeur de Uflags # $MF_BYCOMMAND = 0 # $MF_BYPOSITION = 1024 } function GetMenuItemCount([IntPtr] $hMenu) { #Renvoi le nombre d'items dans le menu spécifié $parameterTypes = [IntPtr] $parameters = $hMenu Invoke-Win32 "user32.dll" ([Int32]) "GetMenuItemCount" $parameterTypes $parameters } function EnableMenuItem([IntPtr] $hMenu, [Int32] $uIDEnableItem, [Int32] $uEnable) { #Supprime une entrée de menu. #Todo : EnableMenuItem valide s'il existe un gestionnaire de message à vérifier $parameterTypes = [IntPtr],[Int32],[Int32] $parameters = $hMenu,$uIDEnableItem,$uEnable Invoke-Win32 "user32.dll" ([Boolean]) "EnableMenuItem" $parameterTypes $parameters # $MF_ENABLED =0 # $MF_GRAYED =1 # $MF_DISABLED =2 } function GetMenuState([IntPtr] $hMenu, [UInt32] $uId, [UInt32] $uFlags) { # The GetMenuState function retrieves the menu flags associated with the specified menu item. # If the menu item opens a submenu, this function also returns the number of items in the submenu. $parameterTypes = [IntPtr],[UInt32],[UInt32] $parameters = $hMenu,$uId,$uFlags Invoke-Win32 "user32.dll" ([Int32]) "GetMenuState" $parameterTypes $parameters } function InsertMenu([IntPtr] $hMenu,[UInt32] $Position, [UInt32] $Flags, [UInt32] $NewId,[String] $Item ) { #Ajoute une entrée de menu. TODO A été remplacée par InsertMenuItem #voir DrawMenuBar $parameterTypes = [IntPtr], [UInt32], [UInt32], [UInt32], [String] $parameters = $hMenu, $Position, $Flags, $NewId,$Item Invoke-Win32 "user32.dll" ([Int32]) "InsertMenu" $parameterTypes $parameters } function DestroyMenu([IntPtr] $hMenu) { #Supprime un menu. voir DrawMenuBar $parameterTypes = [IntPtr] $parameters = $hMenu Invoke-Win32 "user32.dll" ([Boolean]) "DestroyMenu" $parameterTypes $parameters } function DrawMenuBar([IntPtr] $hMenu) { #Redessine le menu. Doit être appelé en cas de modification du menu $parameterTypes = [IntPtr] $parameters = $hMenu Invoke-Win32 "user32.dll" ([Boolean]) "DrawMenuBar" $parameterTypes $parameters } #Retrouver la dernière erreur rencontrée par un appel PInvoke # $Code=[System.Runtime.InteropServices.Marshal]::GetLastWin32Error() # throw New-object System.ComponentModel.Win32Exception $code #Function Tools function Show-PSWindow([IntPtr] $WindowHandle=$PSWindowHandle){ #Affiche la fenêtre possédant le handle $WindowHandle au premier plan $null = ShowWindowAsync $WindowHandle $cApiWindows.SW_SHOWNORMAL } function Hide-PSWindow([IntPtr] $WindowHandle=$PSWindowHandle) { #Cache la fenêtre possédant le handle WindowHandle #l'application n'est plus disponible dans la barre de tâches et dans le gestionnaire de tâches. $null = ShowWindowAsync $WindowHandle $cApiWindows.SW_HIDE } function Minimize-PowerShell([IntPtr] $WindowHandle=$PSWindowHandle) { #Minimize la fenêtre possédant le handle $WindowHandle #l'application est disponible dans la barre de tâches et dans le gestionnaire de tâches. $null = ShowWindowAsync $WindowHandle $cApiWindows.SW_SHOWMINIMIZED } function Set-ForegroundWindow ([IntPtr] $WindowHandle=$PSWindowHandle) { #TODO : Valider la gestion des erreurs # Permet de repositionner une fenêtre au premier plan et ayant le focus #usage : # Start-process "C:\dev\DebugView\Dbgview.exe" -WindowStyle Minimized >$null # #Dbgview.exe prend le focus et se place au premier plan ( z-order) # Set-ForegroundWindow if ($WindowHandle -eq 0) {Throw "Le handle de fenêtre est invalide (Handle=0)."} # On laisse au process le temps de se placer au premier plan start-sleep -m 200 #Ensuite on replace le process désigné par $WindowHandle au premier plan et en lui donnant le focus #The SetActiveWindow function activates a window, but not if the application is #in the background. The window will be brought into the foreground (top of Z-Order) #if its application is in the foreground when the system activates the window. $ret=SetActiveWindow $WindowHandle If ($ret -eq $null) { # If the function fails, the return value is NULL. To get extended error information, call GetLastError. $Code=[System.Runtime.InteropServices.Marshal]::GetLastWin32Error() throw New-object System.ComponentModel.Win32Exception $code } #The SetForegroundWindow function puts the thread that created the specified window #into the foreground and activates the window. Keyboard input is directed to the window, #and various visual cues are changed for the user. The system assigns a slightly #higher priority to the thread that created the foreground window than it does to #other threads. $ret=SetForegroundWindow $WindowHandle if ($ret -ne 0) { #If the window was not brought to the foreground, the return value is zero. Write-debug "L'appel de SetForegroundWindow a échoué." } #The SwitchToThisWindow function is called to switch focus to a specified window #and bring it to the foreground. SwitchToThisWindow $WindowHandle $true } Function Set-ConsoleIcon([string] $iconFile) { # Adaptation # # Script: Set-ConsoleIcon.ps1 # By: Aaron Lerch # Website: www.aaronlerch.com/blog # # Remplace l'icone d'une fenêtre par celui indiqué. # Il s'agit de l'icone affiché dans la barre de tâche ou la liste de tâches. # # Usage: Set-ConsoleIcon [string] # # exemple : # # PS c:\> Set-ConsoleIcon "C:\Icons\special_powershell_icon.ico" # [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null # Verify the file exists if ([System.IO.File]::Exists($iconFile) -eq $TRUE) { $icon = new-object System.Drawing.Icon($iconFile) if ($icon -ne $null) { $consoleHandle = $PSWindowHandle #An application sends the WM_SETICON message to associate a new large or #small icon with a window. The system displays the large icon in the #ALT+TAB dialog box, and the small icon in the window caption. SendMessage $consoleHandle $cApiWindows.WM_SETICON $cApiWindows.ICON_SMALL $icon.Handle | out-null } } else { Write-Host "Fichier d'icone introuvable : $iconFile" } } function Enable-MenuItem([IntPtr] $hMenu, [Int32] $uIDEnableItem) { #Active un menu return EnableMenuItem $hMenu $uIDEnableItem $cApiWindows.MF_ENABLED } function Disable-MenuItem([IntPtr] $hMenu, [Int32] $uIDEnableItem) { #Désactive un menu return EnableMenuItem $hMenu $uIDEnableItem ($cApiWindows.Add("MF_BYCOMMAND","MF_DISABLED","MF_GRAYED")) } function Remove-CloseMenu([IntPtr] $hMenu) { #Supprime le menu close du menu système d'une fenêtre RemoveMenu $hMenu $cApiWindows.SC_CLOSE $cApiWindows.MF_BYCOMMAND } function Add-CloseMenu([IntPtr] $hMenu) { #Ajoute un menu close au menu système d'une fenêtre AppendMenu $hMenu $cApiWindows.MF_STRING $cApiWindows.SC_CLOSE 'Fermer' } #TODO Remove-Menu SC_CLOSE,SC_MINIMIZE function Remove-MinimizeMenu([IntPtr] $hMenu) { #Supprime le menu "Réduire" du menu système d'une fenêtre RemoveMenu $hMenu $cApiWindows.SC_MINIMIZE $cApiWindows.MF_BYCOMMAND } function Add-MinimizeMenu([IntPtr] $hMenu) { #Ajoute un menu "Réduire" au menu système d'une fenêtre AppendMenu $hMenu $cApiWindows.MF_STRING 3 $cApiWindows.MF_BYPOSITION 'Réduire' } function StayOnTop([IntPtr] $WindowHandle=$PSWindowHandle, [switch] $OFF) { #La fenêtre cible reste toujours au premier Plan (Always on top) [IntPtr]$FlagTop=$cApiWindows.HWND_TOPMOST if ($Off) {$FlagTop=$cApiWindows.HWND_NOTOPMOST} [Uint32] $Uflags=$cApiWindows.Add("SWP_NOSIZE","SWP_NOMOVE","SWP_NOOWNERZORDER","SWP_NOACTIVATE") #Pas de modification de la taille de la fenêtre ni de la position [void](SetWindowPos $WindowHandle $FlagTop 0 0 0 0 $Uflags ) }