Cleanup, Namespaces, Repeated updates in WindowManager
This commit is contained in:
parent
231b592610
commit
02314701f4
2
OBSBlur.sln.DotSettings
Normal file
2
OBSBlur.sln.DotSettings
Normal file
@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=GETTEXTLENGTH/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
@ -1,79 +1,3 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
using OBSBlur.Window;
|
||||
|
||||
new WindowManager();
|
@ -1,25 +1,27 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OBSBlur.Window;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
public struct Point
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
|
||||
public POINT(int x, int y)
|
||||
public Point(int x, int y)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
}
|
||||
|
||||
public static implicit operator System.Drawing.Point(POINT p)
|
||||
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)
|
||||
public static implicit operator Point(System.Drawing.Point p)
|
||||
{
|
||||
return new POINT(p.X, p.Y);
|
||||
return new Point(p.X, p.Y);
|
||||
}
|
||||
|
||||
public override string ToString()
|
@ -1,11 +1,13 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OBSBlur.Window;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
public struct Rectangle
|
||||
{
|
||||
public int Left, Top, Right, Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom)
|
||||
public Rectangle(int left, int top, int right, int bottom)
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
@ -13,10 +15,10 @@ public struct RECT
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public RECT(System.Drawing.Rectangle r) : this(r.Left, r.Top, r.Right, r.Bottom) { }
|
||||
public Rectangle(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; }
|
||||
}
|
||||
@ -51,37 +53,37 @@ public struct RECT
|
||||
set { Width = value.Width; Height = value.Height; }
|
||||
}
|
||||
|
||||
public static implicit operator System.Drawing.Rectangle(RECT r)
|
||||
public static implicit operator System.Drawing.Rectangle(Rectangle r)
|
||||
{
|
||||
return new System.Drawing.Rectangle(r.Left, r.Top, r.Width, r.Height);
|
||||
}
|
||||
|
||||
public static implicit operator RECT(System.Drawing.Rectangle r)
|
||||
public static implicit operator Rectangle(System.Drawing.Rectangle r)
|
||||
{
|
||||
return new RECT(r);
|
||||
return new Rectangle(r);
|
||||
}
|
||||
|
||||
public static bool operator ==(RECT r1, RECT r2)
|
||||
public static bool operator ==(Rectangle r1, Rectangle r2)
|
||||
{
|
||||
return r1.Equals(r2);
|
||||
}
|
||||
|
||||
public static bool operator !=(RECT r1, RECT r2)
|
||||
public static bool operator !=(Rectangle r1, Rectangle r2)
|
||||
{
|
||||
return !r1.Equals(r2);
|
||||
}
|
||||
|
||||
public bool Equals(RECT r)
|
||||
public bool Equals(Rectangle 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);
|
||||
if (obj is Rectangle)
|
||||
return Equals((Rectangle)obj);
|
||||
else if (obj is System.Drawing.Rectangle)
|
||||
return Equals(new RECT((System.Drawing.Rectangle)obj));
|
||||
return Equals(new Rectangle((System.Drawing.Rectangle)obj));
|
||||
return false;
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
enum ShowWindowCommands
|
||||
namespace OBSBlur.Window;
|
||||
|
||||
public enum ShowWindowCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// Hides the window and activates another window.
|
@ -1,11 +1,13 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OBSBlur.Window;
|
||||
|
||||
/// <summary>
|
||||
/// Contains information about the placement of a window on the screen.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WINDOWPLACEMENT
|
||||
public struct WINDOWPLACEMENT
|
||||
{
|
||||
/// <summary>
|
||||
/// The length of the structure, in bytes. Before calling the GetWindowPlacement or SetWindowPlacement functions, set this member to sizeof(WINDOWPLACEMENT).
|
||||
@ -28,17 +30,17 @@ internal struct WINDOWPLACEMENT
|
||||
/// <summary>
|
||||
/// The coordinates of the window's upper-left corner when the window is minimized.
|
||||
/// </summary>
|
||||
public POINT MinPosition;
|
||||
public Point MinPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The coordinates of the window's upper-left corner when the window is maximized.
|
||||
/// </summary>
|
||||
public POINT MaxPosition;
|
||||
public Point MaxPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The window's coordinates when the window is in the restored position.
|
||||
/// </summary>
|
||||
public RECT NormalPosition;
|
||||
public Rectangle NormalPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default (empty) value.
|
27
OBSBlur/Window/WindowInfo.cs
Normal file
27
OBSBlur/Window/WindowInfo.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OBSBlur.Window;
|
||||
|
||||
public struct WindowInfo
|
||||
{
|
||||
internal IntPtr WindowHandle { get; init; }
|
||||
public WINDOWPLACEMENT WindowPlacement { get; init; }
|
||||
public string WindowTitle { get; init; }
|
||||
public Process ProcessInfo { get; init; }
|
||||
|
||||
public WindowInfo(IntPtr windowHandle, string windowTitle, Process processInfo, WINDOWPLACEMENT windowPlacement)
|
||||
{
|
||||
this.WindowHandle = windowHandle;
|
||||
this.ProcessInfo = processInfo;
|
||||
this.WindowPlacement = windowPlacement;
|
||||
this.WindowTitle = windowTitle;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
const int cutoffStr = 17;
|
||||
string processNameStr = ProcessInfo.ProcessName.Substring(0, Math.Min(cutoffStr, ProcessInfo.ProcessName.Length));
|
||||
string windowTitleStr = WindowTitle.Substring(0, Math.Min(cutoffStr, WindowTitle.Length));
|
||||
return $"{WindowHandle,8} {ProcessInfo.Id,8} {processNameStr,cutoffStr} {windowTitleStr,-cutoffStr} {WindowPlacement}";
|
||||
}
|
||||
}
|
81
OBSBlur/Window/WindowManager.cs
Normal file
81
OBSBlur/Window/WindowManager.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace OBSBlur.Window;
|
||||
|
||||
public class WindowManager : IDisposable
|
||||
{
|
||||
public readonly HashSet<WindowInfo> Windows = new();
|
||||
public int UpdateInterval = 10;
|
||||
private bool KeepUpdating = true;
|
||||
public WindowManager()
|
||||
{
|
||||
Thread t = new (() =>
|
||||
{
|
||||
while(KeepUpdating)
|
||||
EnumWindows(WindowPlacement, 0);
|
||||
Thread.Sleep(UpdateInterval);
|
||||
});
|
||||
t.Start();
|
||||
}
|
||||
|
||||
private bool WindowPlacement(IntPtr windowHandle, IntPtr lParam)
|
||||
{
|
||||
WINDOWPLACEMENT windowPlacement = new ();
|
||||
GetWindowPlacement(windowHandle, ref windowPlacement);
|
||||
Rectangle n = windowPlacement.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(windowHandle, out pid);
|
||||
Process processInfo = Process.GetProcessById((int)pid);
|
||||
//nvcontainer does not have a window name
|
||||
if (processInfo.ProcessName.Equals("nvcontainer"))
|
||||
return true;
|
||||
string windowTitle = GetWindowTextRaw(windowHandle);
|
||||
//Do not add, if window does not have a name
|
||||
if (windowTitle.Length < 1)
|
||||
return true;
|
||||
|
||||
Windows.Add(new WindowInfo(windowHandle, windowTitle, processInfo, windowPlacement));
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
private delegate bool EnumWindowsProc(IntPtr windowHandle, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetWindowPlacement(IntPtr windowHandle, ref WINDOWPLACEMENT lpwndpl);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern uint GetWindowThreadProcessId(IntPtr windowHandle, out uint lpdwProcessId);
|
||||
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
static extern IntPtr SendMessage(IntPtr windowHandle, uint message, IntPtr wParam, [Out] StringBuilder lParam);
|
||||
|
||||
public static string GetWindowTextRaw(IntPtr windowHandle)
|
||||
{
|
||||
// ReSharper disable twice InconsistentNaming
|
||||
const uint WM_GETTEXTLENGTH = 0x000E;
|
||||
const uint WM_GETTEXT = 0x000D;
|
||||
// Allocate correct string length first
|
||||
int length = (int)SendMessage(windowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, null);
|
||||
StringBuilder sb = new (length + 1);
|
||||
SendMessage(windowHandle, WM_GETTEXT, sb.Capacity, sb);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
KeepUpdating = false;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user