mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-30 13:04:20 +01:00
171 lines
7.2 KiB
C#
171 lines
7.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
|
|
namespace DS4Windows
|
|
{
|
|
[System.ComponentModel.DesignerCategory("")]
|
|
public class AdvancedColorDialog : ColorDialog
|
|
{
|
|
#region WinAPI
|
|
internal class ApiWindow
|
|
{
|
|
public IntPtr hWnd;
|
|
public string ClassName;
|
|
public string MainWindowTitle;
|
|
}
|
|
internal class WindowsEnumerator
|
|
{
|
|
private delegate int EnumCallBackDelegate(IntPtr hwnd, int lParam);
|
|
|
|
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int EnumWindows(EnumCallBackDelegate lpEnumFunc, int lParam);
|
|
|
|
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int EnumChildWindows(IntPtr hWndParent, EnumCallBackDelegate lpEnumFunc, int lParam);
|
|
|
|
[DllImport("user32", EntryPoint = "GetClassNameA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int GetClassName(IntPtr hwnd, System.Text.StringBuilder lpClassName, int nMaxCount);
|
|
|
|
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int IsWindowVisible(IntPtr hwnd);
|
|
|
|
[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int GetParent(IntPtr hwnd);
|
|
|
|
[DllImport("user32", EntryPoint = "SendMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
|
|
|
|
[DllImport("user32", EntryPoint = "SendMessageA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, System.Text.StringBuilder lParam);
|
|
|
|
private List<ApiWindow> _listChildren = new List<ApiWindow>();
|
|
|
|
private List<ApiWindow> _listTopLevel = new List<ApiWindow>();
|
|
private string _topLevelClass = string.Empty;
|
|
|
|
private string _childClass = string.Empty;
|
|
public ApiWindow[] GetTopLevelWindows()
|
|
{
|
|
EnumWindows(EnumWindowProc, 0x0);
|
|
return _listTopLevel.ToArray();
|
|
}
|
|
|
|
public ApiWindow[] GetTopLevelWindows(string className)
|
|
{
|
|
_topLevelClass = className;
|
|
return this.GetTopLevelWindows();
|
|
}
|
|
|
|
public ApiWindow[] GetChildWindows(IntPtr hwnd)
|
|
{
|
|
_listChildren.Clear();
|
|
EnumChildWindows(hwnd, EnumChildWindowProc, 0x0);
|
|
return _listChildren.ToArray();
|
|
}
|
|
|
|
public ApiWindow[] GetChildWindows(IntPtr hwnd, string childClass)
|
|
{
|
|
_childClass = childClass;
|
|
return this.GetChildWindows(hwnd);
|
|
}
|
|
|
|
private Int32 EnumWindowProc(IntPtr hwnd, Int32 lParam)
|
|
{
|
|
if (GetParent(hwnd) == 0 && IsWindowVisible(hwnd) != 0)
|
|
{
|
|
ApiWindow window = GetWindowIdentification(hwnd);
|
|
if (_topLevelClass.Length == 0 || window.ClassName.ToLower() == _topLevelClass.ToLower())
|
|
{
|
|
_listTopLevel.Add(window);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
private Int32 EnumChildWindowProc(IntPtr hwnd, Int32 lParam)
|
|
{
|
|
ApiWindow window = GetWindowIdentification(hwnd);
|
|
if (_childClass.Length == 0 || window.ClassName.ToLower() == _childClass.ToLower())
|
|
{
|
|
_listChildren.Add(window);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
private ApiWindow GetWindowIdentification(IntPtr hwnd)
|
|
{
|
|
System.Text.StringBuilder classBuilder = new System.Text.StringBuilder(64);
|
|
GetClassName(hwnd, classBuilder, 64);
|
|
|
|
ApiWindow window = new ApiWindow();
|
|
window.ClassName = classBuilder.ToString();
|
|
window.MainWindowTitle = WindowText(hwnd);
|
|
window.hWnd = hwnd;
|
|
return window;
|
|
}
|
|
|
|
public static string WindowText(IntPtr hwnd)
|
|
{
|
|
const int W_GETTEXT = 0xd;
|
|
const int W_GETTEXTLENGTH = 0xe;
|
|
|
|
System.Text.StringBuilder SB = new System.Text.StringBuilder();
|
|
int length = SendMessage(hwnd, W_GETTEXTLENGTH, 0, 0);
|
|
if (length > 0)
|
|
{
|
|
SB = new System.Text.StringBuilder(length + 1);
|
|
SendMessage(hwnd, W_GETTEXT, SB.Capacity, SB);
|
|
}
|
|
return SB.ToString();
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
private const int GA_ROOT = 2;
|
|
private const int WM_CTLCOLOREDIT = 0x133;
|
|
private const int WM_LBUTTONDOWN = 0x0201;
|
|
private const int WM_INITDIALOG = 0x0110;
|
|
|
|
private List<ApiWindow> EditWindows = null;
|
|
public delegate void ColorUpdateHandler(object sender, EventArgs e);
|
|
public event ColorUpdateHandler OnUpdateColor;
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
|
|
public static extern IntPtr GetAncestor(IntPtr hWnd, int gaFlags);
|
|
|
|
// Overrides the base class hook procedure...
|
|
//[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
|
|
protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
|
|
{
|
|
if (msg == WM_INITDIALOG)
|
|
{
|
|
IntPtr mainWindow = GetAncestor(hWnd, GA_ROOT);
|
|
if (!mainWindow.Equals(IntPtr.Zero))
|
|
EditWindows = new List<ApiWindow>((new WindowsEnumerator()).GetChildWindows(mainWindow, "Edit"));
|
|
}
|
|
else if (msg == WM_CTLCOLOREDIT)
|
|
{
|
|
if ((EditWindows == null))
|
|
{
|
|
IntPtr mainWindow = GetAncestor(hWnd, GA_ROOT);
|
|
if (!mainWindow.Equals(IntPtr.Zero))
|
|
EditWindows = new List<ApiWindow>((new WindowsEnumerator()).GetChildWindows(mainWindow, "Edit"));
|
|
}
|
|
if ((EditWindows != null) && EditWindows.Count == 6)
|
|
{
|
|
byte red = 0, green = 0, blue = 0;
|
|
if (Byte.TryParse(WindowsEnumerator.WindowText(EditWindows[3].hWnd), out red))
|
|
if (Byte.TryParse(WindowsEnumerator.WindowText(EditWindows[4].hWnd), out green))
|
|
if (Byte.TryParse(WindowsEnumerator.WindowText(EditWindows[5].hWnd), out blue))
|
|
OnUpdateColor?.Invoke(Color.FromArgb(red, green, blue), EventArgs.Empty);
|
|
}
|
|
}
|
|
// Always call the base class hook procedure.
|
|
return base.HookProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
}
|
|
}
|