mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-12-27 09:01:48 +01:00
b4a6249fa3
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
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(Color.FromArgb(red, green, blue), EventArgs.Empty);
|
|
}
|
|
}
|
|
// Always call the base class hook procedure.
|
|
return base.HookProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
}
|
|
}
|