Skip to content

Instantly share code, notes, and snippets.

@edjdavid
Last active February 8, 2025 12:30
Show Gist options
  • Save edjdavid/244aca18099a2d3a5bddaad6f23f5276 to your computer and use it in GitHub Desktop.
Save edjdavid/244aca18099a2d3a5bddaad6f23f5276 to your computer and use it in GitHub Desktop.

Revisions

  1. edjdavid revised this gist Oct 25, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion transparent-kb.ps1
    Original file line number Diff line number Diff line change
    @@ -103,7 +103,7 @@ BEGIN{
    PROCESS{
    $MainWindowHandle = [apifuncs]::GetDesktopWindow();
    foreach ($child in ([apifuncs]::GetChildWindows($MainWindowHandle))){
    if ((Get-WindowName($child)) -ne "Microsoft Text Input Application") {continue}
    if ((Get-WindowName($child)) -ne "Windows Input Experience") {continue}

    # there are three "Microsoft Text Input Application" on my system, (touch keyboard, emoji panel)
    # I don't know what the other one is for
  2. edjdavid created this gist Aug 28, 2020.
    121 changes: 121 additions & 0 deletions transparent-kb.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,121 @@
    # No need for admin privileges. Working on Windows 10 2004
    # Save as ps1 file, right click, then select Run with PowerShell

    # https://stackoverflow.com/questions/25369285/how-can-i-get-all-window-handles-by-a-process-in-powershell
    # https://www.reddit.com/r/PowerShell/comments/5etxgq/make_the_touch_keyboard_windows_810_transparent/

    function Set-KBTransparent {
    [CmdletBinding()]
    param ()

    BEGIN{
    function Get-WindowName($hwnd) {
    $len = [apifuncs]::GetWindowTextLength($hwnd)
    if($len -gt 0){
    $sb = New-Object text.stringbuilder -ArgumentList ($len + 1)
    $rtnlen = [apifuncs]::GetWindowText($hwnd,$sb,$sb.Capacity)
    $sb.tostring()
    }
    }

    if (("APIFuncs" -as [type]) -eq $null){
    Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    using System.Text;
    public class APIFuncs
    {
    internal const int GWL_EXSTYLE = -20;
    internal const int WS_EX_LAYERED = 0x80000;
    internal const int LWA_ALPHA = 0x2;
    internal const int LWA_COLORKEY = 0x1;
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString, int cch);
    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd,out Int32 lpdwProcessId);
    [DllImport("user32.dll", EntryPoint="SetLayeredWindowAttributes")]
    public static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
    [DllImport("user32.dll")]
    public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    [DllImport("user32.dll")]
    public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
    public static extern Int32 GetWindowTextLength(IntPtr hWnd);
    [DllImport("user32.dll")]
    public static extern IntPtr GetDesktopWindow();
    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
    public static bool SetWindowTransparent(IntPtr hWnd)
    {
    SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) ^ WS_EX_LAYERED);
    return SetLayeredWindowAttributes(hWnd, 0, 200, LWA_ALPHA);
    }
    public static List<IntPtr> GetChildWindows(IntPtr parent)
    {
    List<IntPtr> result = new List<IntPtr>();
    GCHandle listHandle = GCHandle.Alloc(result);
    try
    {
    EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
    EnumChildWindows(parent, childProc,GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
    if (listHandle.IsAllocated)
    listHandle.Free();
    }
    return result;
    }
    private static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
    GCHandle gch = GCHandle.FromIntPtr(pointer);
    List<IntPtr> list = gch.Target as List<IntPtr>;
    if (list == null)
    {
    throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
    }
    list.Add(handle);
    // You can modify this to check to see if you want to cancel the operation, then return a null here
    return true;
    }
    public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
    }
    "@
    }
    }

    PROCESS{
    $MainWindowHandle = [apifuncs]::GetDesktopWindow();
    foreach ($child in ([apifuncs]::GetChildWindows($MainWindowHandle))){
    if ((Get-WindowName($child)) -ne "Microsoft Text Input Application") {continue}

    # there are three "Microsoft Text Input Application" on my system, (touch keyboard, emoji panel)
    # I don't know what the other one is for

    # SetLayeredWindowAttributes toggles on/off, make sure it stays on on
    For ($i=0; $i -le 1; $i++) {
    if ([APIFuncs]::setWindowTransparent($child)) {
    break;
    }
    }
    }
    }
    }

    Set-KBTransparent