[How-To] Fade a window, or make it transparent to a certain extent (PowerShell hybrid)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

[How-To] Fade a window, or make it transparent to a certain extent (PowerShell hybrid)

#1 Post by aGerman » 27 Oct 2022 12:47

By default, the %Fade% macro targets the current console window. Optionally, you may pass the process ID of a process whose main window is to be faded.
If you target the Windows Terminal, or if you're unsure whether your script spawns a conhost or a Windows Terminal process, pass the PID returned by the %TermPid% macro. Refer to
viewtopic.php?f=3&t=10576

Steffen

Code: Select all

@echo off
setlocal EnableDelayedExpansion

call :init_Fade

%Fade% 0 1 100 1
%Fade% 100 -1 0 1
pause

%Fade% 30 0 30 0
pause
exit /b

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:init_Fade
setlocal DisableDelayedExpansion
:: prefer PowerShell Core if installed
for %%i in ("pwsh.exe") do if "%%~$PATH:i"=="" (set "ps=powershell") else set "ps=pwsh"

:: - BRIEF -
::  Use alpha blending to fade the window in or out.
:: - SYNTAX -
::  %Fade% start step end delay [pid]
::    start  percentage of transparency to begin with where 0 is for opaque,
::            and 100 is for limpid
::    step   number of percents the current value is advanced in each iteration
::    end    percentage of transparency to end with
::    delay  milliseconds to wait in each iteration to control the speed
::    pid    (optional) ID of a process whose main window is to be faded
::   To immediately set the window to a certain transparency, specify the same
::    value for both the start and end arguments.
:: - EXAMPLES -
::  Fade out the window to full transparency:
::    %Fade% 0 1 100 1
::  Fade in the window to full opacity:
::    %Fade% 100 -1 0 1
::  Instantly set window transprency to 30%:
::    %Fade% 30 0 30 0
set Fade=for %%# in (1 2) do if %%#==2 (for /f "tokens=1-5" %%- in ("^^!args^^! x x x x x") do^
%=% %ps%.exe -nop -ep Bypass -c ^"^
%===% $w=Add-Type -Name WAPI -PassThru -MemberDefinition '^
%=====% [DllImport(\"kernel32.dll\")]^
%=======% public static extern IntPtr GetConsoleWindow();^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int GetWindowLong(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern Int64 GetWindowLongPtr(IntPtr wnd, int idx);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLong(IntPtr wnd, int idx, int newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern void SetWindowLongPtr(IntPtr wnd, int idx, Int64 newLong);^
%=====% [DllImport(\"user32.dll\")]^
%=======% public static extern int SetLayeredWindowAttributes(IntPtr wnd, int color, byte alpha, int flags);^
%===% ';^
%===% $start=0; $step=0; $end=0; $delay=0; $tpid=0;^
%===% if (-not [Int32]::TryParse('%%~-', [ref]$start) -or^
%=====% -not [Int32]::TryParse('%%~.', [ref]$step) -or^
%=====% -not [Int32]::TryParse('%%~/', [ref]$end) -or^
%=====% -not [Int32]::TryParse('%%~0', [ref]$delay) -or^
%=====% $start -lt 0 -or $start -gt 100 -or^
%=====% $end -lt 0 -or $end -gt 100 -or^
%=====% $delay -lt 0^
%===% ) {exit 1}^
%===% $GWL_EXSTYLE=-20;^
%===% $WS_EX_LAYERED=0x80000;^
%===% if ([Int32]::TryParse('%%~1', [ref]$tpid)) {^
%=====% $wnd=(gps -id $tpid -ea SilentlyContinue).MainWindowHandle;^
%===% } else {^
%=====% $wnd=$w::GetConsoleWindow();^
%===% }^
%===   the legacy console needs to be turned into a layered window   =% ^
%===% if ([IntPtr]::Size -eq 4) { %= 32-bit =%^
%=====% $w::SetWindowLong($wnd, $GWL_EXSTYLE, $w::GetWindowLong($wnd, $GWL_EXSTYLE) -bOr $WS_EX_LAYERED);^
%===% } else { %= 64-bit =%^
%=====% $w::SetWindowLongPtr($wnd, $GWL_EXSTYLE, $w::GetWindowLongPtr($wnd, $GWL_EXSTYLE) -bOr [Int64]$WS_EX_LAYERED);^
%===% }^
%===% $LWA_ALPHA=2;^
%===% if (($start -lt $end) -and ($step -gt 0)) { %= fade out =%^
%=====% for ($i=$start; $i -lt $end; $i+=$step) {^
%=======% $null=$w::SetLayeredWindowAttributes($wnd, 0, [byte][math]::Round(255 - 2.55 * $i), $LWA_ALPHA);^
%=======% [Threading.Thread]::Sleep($delay);^
%=====% }^
%===% } elseif (($start -gt $end) -and ($step -lt 0)) { %= fade in =%^
%=====% for ($i=$start; $i -gt $end; $i+=$step) {^
%=======% $null=$w::SetLayeredWindowAttributes($wnd, 0, [byte][math]::Round(255 - 2.55 * $i), $LWA_ALPHA);^
%=======% [Threading.Thread]::Sleep($delay);^
%=====% }^
%===% } elseif ($start -ne $end) {exit 1} %= reject remaining inconclusive values =%^
%===   always use the 'end' value even if the distance between 'start' and 'end' is not a multiple of 'step'   =% ^
%===% exit [int]($w::SetLayeredWindowAttributes($wnd, 0, [byte][math]::Round(255 - 2.55 * $end), $LWA_ALPHA) -eq 0);^
%=% ^" ^&endlocal) else setlocal EnableDelayedExpansion ^&set args=

endlocal &set "Fade=%Fade%"
if !!# neq # set "Fade=%Fade:^^=%"
exit /b
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Post Reply