Get all Windows with Names and Size
This commit is contained in:
parent
bb20666cce
commit
231b592610
29
OBSBlur/POINT.cs
Normal file
29
OBSBlur/POINT.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public POINT(int x, int y)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
}
|
||||
|
||||
public static implicit operator System.Drawing.Point(POINT p)
|
||||
{
|
||||
return new System.Drawing.Point(p.X, p.Y);
|
||||
}
|
||||
|
||||
public static implicit operator POINT(System.Drawing.Point p)
|
||||
{
|
||||
return new POINT(p.X, p.Y);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{{X={X,-7:####0}, Y={Y,-7:####0}}}";
|
||||
}
|
||||
}
|
@ -1 +1,79 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
new WindowManager();
|
||||
|
||||
internal class WindowManager
|
||||
{
|
||||
internal Dictionary<IntPtr, WINDOWPLACEMENT> placements = new();
|
||||
internal Dictionary<IntPtr, string> windowTitles = new();
|
||||
internal Dictionary<IntPtr, Process> processes = new();
|
||||
private const int cutoffStr = 17;
|
||||
public WindowManager()
|
||||
{
|
||||
EnumWindows(WindowPlacement, 0);
|
||||
uint hwndCount = 1;
|
||||
//Group and print by pid
|
||||
foreach (int pid in processes.DistinctBy(kv => kv.Value.Id).Select(kv => kv.Value.Id).ToArray())
|
||||
{
|
||||
foreach(IntPtr hwnd in processes.Where(kv => kv.Value.Id == pid).Select(x => x.Key))
|
||||
Console.WriteLine($"{hwndCount++,3} {hwnd,8} {processes[hwnd].Id,8} {processes[hwnd].ProcessName.Substring(0, Math.Min(cutoffStr, processes[hwnd].ProcessName.Length)),cutoffStr} {windowTitles[hwnd].Substring(0, Math.Min(cutoffStr, windowTitles[hwnd].Length)),-cutoffStr} {placements[hwnd]}");
|
||||
}
|
||||
}
|
||||
|
||||
private bool WindowPlacement(IntPtr hwnd, IntPtr lParam)
|
||||
{
|
||||
WINDOWPLACEMENT placement = new ();
|
||||
GetWindowPlacement(hwnd, ref placement);
|
||||
RECT n = placement.NormalPosition;
|
||||
//Do not add if Window is not a drawable
|
||||
if (n is { Left: 0, Top: 0, Right: 0, Bottom: 0 })
|
||||
return true;
|
||||
|
||||
uint pid;
|
||||
GetWindowThreadProcessId(hwnd, out pid);
|
||||
Process process = Process.GetProcessById((int)pid);
|
||||
//nvcontainer does not have a window name
|
||||
if (process.ProcessName.Equals("nvcontainer"))
|
||||
return true;
|
||||
string name = GetWindowTextRaw(hwnd);
|
||||
//Do not add, if window does not have a name
|
||||
if (name.Length < 1)
|
||||
return true;
|
||||
|
||||
processes.Add(hwnd, process);
|
||||
windowTitles.Add(hwnd, name);
|
||||
placements.Add(hwnd, placement);
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
||||
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [Out] StringBuilder lParam);
|
||||
|
||||
public static string GetWindowTextRaw(IntPtr hwnd)
|
||||
{
|
||||
UInt32 WM_GETTEXTLENGTH = 0x000E;
|
||||
UInt32 WM_GETTEXT = 0x000D;
|
||||
// Allocate correct string length first
|
||||
int length = (int)SendMessage(hwnd, WM_GETTEXTLENGTH, IntPtr.Zero, null);
|
||||
StringBuilder sb = new (length + 1);
|
||||
SendMessage(hwnd, WM_GETTEXT, sb.Capacity, sb);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
97
OBSBlur/RECT.cs
Normal file
97
OBSBlur/RECT.cs
Normal file
@ -0,0 +1,97 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left, Top, Right, Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }
|
||||
|
||||
public int X
|
||||
{
|
||||
get { return Left; }
|
||||
set { Right -= (Left - value); Left = value; }
|
||||
}
|
||||
|
||||
public int Y
|
||||
{
|
||||
get { return Top; }
|
||||
set { Bottom -= (Top - value); Top = value; }
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return Bottom - Top; }
|
||||
set { Bottom = value + Top; }
|
||||
}
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return Right - Left; }
|
||||
set { Right = value + Left; }
|
||||
}
|
||||
|
||||
public System.Drawing.Point Location
|
||||
{
|
||||
get { return new System.Drawing.Point(Left, Top); }
|
||||
set { X = value.X; Y = value.Y; }
|
||||
}
|
||||
|
||||
public System.Drawing.Size Size
|
||||
{
|
||||
get { return new System.Drawing.Size(Width, Height); }
|
||||
set { Width = value.Width; Height = value.Height; }
|
||||
}
|
||||
|
||||
public static implicit operator System.Drawing.Rectangle(RECT r)
|
||||
{
|
||||
return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
|
||||
}
|
||||
|
||||
public static implicit operator RECT(System.Drawing.Rectangle r)
|
||||
{
|
||||
return new RECT(r);
|
||||
}
|
||||
|
||||
public static bool operator ==(RECT r1, RECT r2)
|
||||
{
|
||||
return r1.Equals(r2);
|
||||
}
|
||||
|
||||
public static bool operator !=(RECT r1, RECT r2)
|
||||
{
|
||||
return !r1.Equals(r2);
|
||||
}
|
||||
|
||||
public bool Equals(RECT r)
|
||||
{
|
||||
return r.Left == Left && r.Top == Top && r.Right == Right && r.Bottom == Bottom;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is RECT)
|
||||
return Equals((RECT)obj);
|
||||
else if (obj is System.Drawing.Rectangle)
|
||||
return Equals(new RECT((System.Drawing.Rectangle)obj));
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ((System.Drawing.Rectangle)this).GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{{Left={Left,-7:####0}, Top={Top,-7:####0}, Right={Right,-7:####0}, Bottom={Bottom,-7:####0}}}";
|
||||
}
|
||||
}
|
71
OBSBlur/ShowWindowCommands.cs
Normal file
71
OBSBlur/ShowWindowCommands.cs
Normal file
@ -0,0 +1,71 @@
|
||||
enum ShowWindowCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// Hides the window and activates another window.
|
||||
/// </summary>
|
||||
Hide = 0,
|
||||
/// <summary>
|
||||
/// Activates and displays a window. If the window is minimized or
|
||||
/// maximized, the system restores it to its original size and position.
|
||||
/// An application should specify this flag when displaying the window
|
||||
/// for the first time.
|
||||
/// </summary>
|
||||
Normal = 1,
|
||||
/// <summary>
|
||||
/// Activates the window and displays it as a minimized window.
|
||||
/// </summary>
|
||||
ShowMinimized = 2,
|
||||
/// <summary>
|
||||
/// Maximizes the specified window.
|
||||
/// </summary>
|
||||
Maximize = 3, // is this the right value?
|
||||
/// <summary>
|
||||
/// Activates the window and displays it as a maximized window.
|
||||
/// </summary>
|
||||
ShowMaximized = 3,
|
||||
/// <summary>
|
||||
/// Displays a window in its most recent size and position. This value
|
||||
/// is similar to <see cref="Win32.ShowWindowCommand.Normal"/>, except
|
||||
/// the window is not activated.
|
||||
/// </summary>
|
||||
ShowNoActivate = 4,
|
||||
/// <summary>
|
||||
/// Activates the window and displays it in its current size and position.
|
||||
/// </summary>
|
||||
Show = 5,
|
||||
/// <summary>
|
||||
/// Minimizes the specified window and activates the next top-level
|
||||
/// window in the Z order.
|
||||
/// </summary>
|
||||
Minimize = 6,
|
||||
/// <summary>
|
||||
/// Displays the window as a minimized window. This value is similar to
|
||||
/// <see cref="Win32.ShowWindowCommand.ShowMinimized"/>, except the
|
||||
/// window is not activated.
|
||||
/// </summary>
|
||||
ShowMinNoActive = 7,
|
||||
/// <summary>
|
||||
/// Displays the window in its current size and position. This value is
|
||||
/// similar to <see cref="Win32.ShowWindowCommand.Show"/>, except the
|
||||
/// window is not activated.
|
||||
/// </summary>
|
||||
ShowNA = 8,
|
||||
/// <summary>
|
||||
/// Activates and displays the window. If the window is minimized or
|
||||
/// maximized, the system restores it to its original size and position.
|
||||
/// An application should specify this flag when restoring a minimized window.
|
||||
/// </summary>
|
||||
Restore = 9,
|
||||
/// <summary>
|
||||
/// Sets the show state based on the SW_* value specified in the
|
||||
/// STARTUPINFO structure passed to the CreateProcess function by the
|
||||
/// program that started the application.
|
||||
/// </summary>
|
||||
ShowDefault = 10,
|
||||
/// <summary>
|
||||
/// <b>Windows 2000/XP:</b> Minimizes a window, even if the thread
|
||||
/// that owns the window is not responding. This flag should only be
|
||||
/// used when minimizing windows from a different thread.
|
||||
/// </summary>
|
||||
ForceMinimize = 11
|
||||
}
|
60
OBSBlur/WINDOWPLACEMENT.cs
Normal file
60
OBSBlur/WINDOWPLACEMENT.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
/// <summary>
|
||||
/// Contains information about the placement of a window on the screen.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WINDOWPLACEMENT
|
||||
{
|
||||
/// <summary>
|
||||
/// The length of the structure, in bytes. Before calling the GetWindowPlacement or SetWindowPlacement functions, set this member to sizeof(WINDOWPLACEMENT).
|
||||
/// <para>
|
||||
/// GetWindowPlacement and SetWindowPlacement fail if this member is not set correctly.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public int Length;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies flags that control the position of the minimized window and the method by which the window is restored.
|
||||
/// </summary>
|
||||
public int Flags;
|
||||
|
||||
/// <summary>
|
||||
/// The current show state of the window.
|
||||
/// </summary>
|
||||
public ShowWindowCommands ShowCmd;
|
||||
|
||||
/// <summary>
|
||||
/// The coordinates of the window's upper-left corner when the window is minimized.
|
||||
/// </summary>
|
||||
public POINT MinPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The coordinates of the window's upper-left corner when the window is maximized.
|
||||
/// </summary>
|
||||
public POINT MaxPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The window's coordinates when the window is in the restored position.
|
||||
/// </summary>
|
||||
public RECT NormalPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default (empty) value.
|
||||
/// </summary>
|
||||
public static WINDOWPLACEMENT Default
|
||||
{
|
||||
get
|
||||
{
|
||||
WINDOWPLACEMENT result = new WINDOWPLACEMENT();
|
||||
result.Length = Marshal.SizeOf( result );
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"CMD: {ShowCmd,13} Min: {MinPosition} Max: {MaxPosition} Normal: {NormalPosition}";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user