Imports System Imports System.Text Imports System.ComponentModel Imports DD_Clipboard_Watcher.ClassWindowsAPINativeMethods Public Class ClassWindowAPIUtils Private Shared GetControlNameMessage As Integer = 0 Sub New() GetControlNameMessage = ClassWindowsAPINativeMethods.RegisterWindowMessage("WM_GETCONTROLNAME") End Sub Public Function GetWinFormsId(ByVal hWnd As IntPtr) As String Return XProcGetControlName(hWnd, GetControlNameMessage) End Function Protected Function XProcGetControlName(ByVal hwnd As IntPtr, ByVal msg As Integer) As String Dim bytearray As Byte() = New Byte(65535) {} Dim bufferMem As IntPtr = IntPtr.Zero Dim written As IntPtr = IntPtr.Zero Dim retHandle As IntPtr = IntPtr.Zero Dim retVal As Boolean Dim processHandle As IntPtr = IntPtr.Zero Dim fileHandle As IntPtr = IntPtr.Zero If Not (Environment.OSVersion.Platform = PlatformID.Win32Windows) Then Try Dim size As UInteger size = 65536 processHandle = ClassWindowsAPINativeMethods.OpenProcess(ClassWindowsAPINativeMethods.PROCESS_VM_OPERATION Or ClassWindowsAPINativeMethods.PROCESS_VM_READ Or ClassWindowsAPINativeMethods.PROCESS_VM_WRITE, False, GetProcessIdFromHWnd(hwnd)) If processHandle.ToInt64() = 0 Then Throw New Win32Exception() End If bufferMem = ClassWindowsAPINativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, New UIntPtr(size), ClassWindowsAPINativeMethods.MEM_RESERVE Or ClassWindowsAPINativeMethods.MEM_COMMIT, PageProtection.ReadWrite) If bufferMem.ToInt64() = 0 Then Throw New Win32Exception() End If retHandle = ClassWindowsAPINativeMethods.SendMessage(hwnd, msg, New IntPtr(size), bufferMem) retVal = ClassWindowsAPINativeMethods.ReadProcessMemory(processHandle, bufferMem, bytearray, New UIntPtr(size), written) If Not retVal Then Throw New Win32Exception() End If Finally retVal = ClassWindowsAPINativeMethods.VirtualFreeEx(processHandle, bufferMem, New UIntPtr(0), ClassWindowsAPINativeMethods.MEM_RELEASE) If Not retVal Then Throw New Win32Exception() End If ClassWindowsAPINativeMethods.CloseHandle(processHandle) End Try Else Try Dim size2 As Integer size2 = 65536 fileHandle = ClassWindowsAPINativeMethods.CreateFileMapping(New IntPtr(ClassWindowsAPINativeMethods.INVALID_HANDLE_VALUE), IntPtr.Zero, PageProtection.ReadWrite, 0, size2, Nothing) If fileHandle.ToInt64() = 0 Then Throw New Win32Exception() End If bufferMem = ClassWindowsAPINativeMethods.MapViewOfFile(fileHandle, ClassWindowsAPINativeMethods.FILE_MAP_ALL_ACCESS, 0, 0, New UIntPtr(0)) If bufferMem.ToInt64() = 0 Then Throw New Win32Exception() End If ClassWindowsAPINativeMethods.MoveMemoryFromByte(bufferMem, bytearray(0), size2) retHandle = ClassWindowsAPINativeMethods.SendMessage(hwnd, msg, New IntPtr(size2), bufferMem) ClassWindowsAPINativeMethods.MoveMemoryToByte(bytearray(0), bufferMem, 1024) Finally ClassWindowsAPINativeMethods.UnmapViewOfFile(bufferMem) ClassWindowsAPINativeMethods.CloseHandle(fileHandle) End Try End If Return ByteArrayToString(bytearray) End Function Private Function GetProcessIdFromHWnd(ByVal hwnd As IntPtr) As UInteger Dim pid As UInteger ClassWindowsAPINativeMethods.GetWindowThreadProcessId(hwnd, pid) Return pid End Function Private Function ByteArrayToString(ByVal bytes As Byte()) As String If Environment.OSVersion.Platform = PlatformID.Win32Windows Then Return Encoding.[Default].GetString(bytes).TrimEnd(vbNullChar) Else Return Encoding.Unicode.GetString(bytes).TrimEnd(vbNullChar) End If End Function End Class