cemu-DS4Windows/DS4Tool/AdvancedColorDialog.cs
jays2kings b4a6249fa3 Version 1.4.156
Significant CPU usage decrease by reworking how single instances work,
on a mobile i7 for example with a single controller connected usage went
from 4-6% to .5-1.5%. With no controllers connected the usage went from
2.5-4.5% to 0%!
As mentioned before, single instances has been reworked, so trying to
relaunch DS4W more reliably opens the previous instance
Fixed Shift modifier not working if main controls were not modified
Fixed Tilt Left for Shift modifier
Fixed default text of shift controls
Remove touchpad movement notification when swipe for controls is enabled
Can test the rumble motors separately via Heavy and Light
Truly implemented Flush HID (I think)
Slight change in profiles, when loading profiles in for the first time
in this new version, there may be a slight delay
Updated French Translations
Removed mouse moving as an option for touch swipes controls, as they
weren't implemented nor have a purpose to be
2014-11-18 16:23:41 -05:00

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(Color.FromArgb(red, green, blue), EventArgs.Empty);
}
}
// Always call the base class hook procedure.
return base.HookProc(hWnd, msg, wParam, lParam);
}
}
}