diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4d6f1a1 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: System.Runtime.CompilerServices.DisableRuntimeMarshalling] diff --git a/Services/WindowInteractionService.cs b/Services/WindowInteractionService.cs index 54cd6d3..7184264 100644 --- a/Services/WindowInteractionService.cs +++ b/Services/WindowInteractionService.cs @@ -8,7 +8,7 @@ using IPClab1.Enums; namespace IPClab1.Services; -public class WindowInteractionService +public partial class WindowInteractionService { private const uint WM_MOUSEMOVE = 0x0200; private const uint WM_LBUTTONDOWN = 0x0201; @@ -21,22 +21,22 @@ public class WindowInteractionService private const int SC_MAXIMIZE = 0xF030; private const int SC_RESTORE = 0xF120; - [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam); + [LibraryImport("user32.dll", StringMarshalling = StringMarshalling.Utf16)] + private static partial IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam); - [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - // 1. Get Class Name - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] - private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + [LibraryImport("user32.dll", EntryPoint = "PostMessageW")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - // 2. Get Geometry - [DllImport("user32.dll", SetLastError = true)] - private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + [LibraryImport("user32.dll", EntryPoint = "GetClassNameW", SetLastError = true)] + private static partial int GetClassName(IntPtr hWnd, [Out] char[] lpClassName, int nMaxCount); - // 3. Get Parent - [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] - private static extern IntPtr GetParent(IntPtr hWnd); + [LibraryImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + + [LibraryImport("user32.dll")] + private static partial IntPtr GetParent(IntPtr hWnd); public void SimulateClick(IntPtr hwnd, int x, int y) { @@ -81,9 +81,9 @@ public class WindowInteractionService public string GetWindowDetails(IntPtr hwnd) { - StringBuilder classNameBuffer = new StringBuilder(256); - GetClassName(hwnd, classNameBuffer, classNameBuffer.Capacity); - string className = classNameBuffer.ToString(); + char[] classNameBuffer = new char[256]; + int length = GetClassName(hwnd, classNameBuffer, classNameBuffer.Length); + string className = length > 0 ? new string(classNameBuffer, 0, length) : string.Empty; GetWindowRect(hwnd, out RECT rect); diff --git a/Services/WindowListService.cs b/Services/WindowListService.cs index 3261eba..9dbea0d 100644 --- a/Services/WindowListService.cs +++ b/Services/WindowListService.cs @@ -13,7 +13,7 @@ using Windows.Graphics.Imaging; namespace IPClab1.Services; -public class WindowListService +public partial class WindowListService { #region Win32 P/Invoke Declarations @@ -27,34 +27,34 @@ public class WindowListService private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); - [DllImport("user32.dll")] + [LibraryImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); + private static partial bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); - [DllImport("user32.dll")] + [LibraryImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool IsWindowVisible(IntPtr hWnd); + private static partial bool IsWindowVisible(IntPtr hWnd); - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + [LibraryImport("user32.dll", EntryPoint = "GetWindowTextW", SetLastError = true)] + private static partial int GetWindowText(IntPtr hWnd, [Out] char[] lpString, int nMaxCount); - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern int GetWindowTextLength(IntPtr hWnd); + [LibraryImport("user32.dll", EntryPoint = "GetWindowTextLengthW", SetLastError = true)] + private static partial int GetWindowTextLength(IntPtr hWnd); - [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + [LibraryImport("user32.dll", EntryPoint = "SendMessageW")] + private static partial IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - [DllImport("user32.dll", EntryPoint = "GetClassLongPtr", CharSet = CharSet.Auto)] - private static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); + [LibraryImport("user32.dll", EntryPoint = "GetClassLongPtrW")] + private static partial IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); - [DllImport("user32.dll", EntryPoint = "GetClassLong", CharSet = CharSet.Auto)] - private static extern uint GetClassLong32(IntPtr hWnd, int nIndex); + [LibraryImport("user32.dll", EntryPoint = "GetClassLongW")] + private static partial uint GetClassLong32(IntPtr hWnd, int nIndex); - [DllImport("user32.dll", SetLastError = true)] - private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + [LibraryImport("user32.dll", SetLastError = true)] + private static partial uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); - [DllImport("shell32.dll", CharSet = CharSet.Auto)] - private static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex); + [LibraryImport("shell32.dll", EntryPoint = "ExtractIconW", StringMarshalling = StringMarshalling.Utf16)] + private static partial IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex); private IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) { @@ -85,13 +85,14 @@ public class WindowListService foreach (var hWnd in handles) { // Fetch window text title cleanly - int length = GetWindowTextLength(hWnd); - var builder = new StringBuilder(length + 1); - GetWindowText(hWnd, builder, builder.Capacity); - string title = builder.ToString(); + var length = GetWindowTextLength(hWnd); + var titleBuffer = new char[length + 1]; + + var actualLength = GetWindowText(hWnd, titleBuffer, titleBuffer.Length); + var title = actualLength > 0 ? new string(titleBuffer, 0, actualLength) : string.Empty; // Fetch numeric process identifier - GetWindowThreadProcessId(hWnd, out uint processId); + GetWindowThreadProcessId(hWnd, out var processId); // Fetch and map the icon image synchronously/asynchronously into WinUI structures SoftwareBitmapSource iconSource = await GetWinUi3IconAsync(hWnd); @@ -110,7 +111,7 @@ public class WindowListService private Icon GetIconFromHwnd(IntPtr hWnd) { - IntPtr hIcon = SendMessage(hWnd, WM_GETICON, ICON_BIG, IntPtr.Zero); + var hIcon = SendMessage(hWnd, WM_GETICON, ICON_BIG, IntPtr.Zero); if (hIcon == IntPtr.Zero) hIcon = SendMessage(hWnd, WM_GETICON, ICON_SMALL2, IntPtr.Zero);