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…
x
Reference in New Issue
Block a user