Automate Winforms

visual basic 6 , .net , automate , control Tulsa, United States
  • 12 years ago
    Hi all, I need to get handle of .NET controls. Here is my code. Sub Main() Dim hwndParent As Long hwndParent = Win32.user32.GetDesktopWindow Dim controlHandle As Long controlHandle = FindWindowsFormsControlRecursive(hwndParent, "listview_Report") End Sub Function FindWindowsFormsControlRecursive(startWnd As Long, controlName As String) As Long Dim childWnd As Long Dim tmpWnd As Long Dim retVal As Long ' Start with the first child. childWnd = GetWindow(startWnd, GW_CHILD) Do While childWnd <> 0 And retVal = 0 ' Compare the WindowsFormsID and see if this is the control. If GetWindowsFormsID(childWnd) <> controlName Then tmpWnd = childWnd ' Do depth-first recursion on the children. retVal = FindWindowsFormsControlRecursive(tmpWnd, controlName) childWnd = GetWindow(childWnd, GW_HWNDNEXT) Else ' Found it. retVal = childWnd Exit Do End If Loop FindWindowsFormsControlRecursive = retVal End Function Function GetWindowsFormsID(ByVal wnd As Long) As String Dim PID As Long 'pid of the process that contains the control Dim msg As Long ' Define the buffer that will eventually contain the desired ' component's name. Dim bytearray As String * 65526 ' Allocate space in the target process for the buffer as shared ' memory. Dim bufferMem As Long ' Base address of the allocated region for the buffer. Dim size As Long ' The amount of memory to be allocated. Dim written As Long ' Number of bytes written to memory. Dim retLength As Long Dim retVal As Long Dim errNum As Integer Dim errDescription As String Dim lp As Long size = 65527 '65536 'Len(bytearray) ' Creating and reading from a shared memory region is done ' differently in Win9x than in newer Oss. Dim processHandle As Long Dim fileHandle As Long msg = RegisterWindowMessage("WM_GETCONTROLNAME") If Not IsWin9x() Then On Local Error GoTo Error_Handler_NT 'Dim dwResult As Long 'dwResult = GetWindowThreadProcessId(wnd, VarPtr(PID)) Call GetWindowThreadProcessId(wnd, PID) processHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, PID) If processHandle = 0 Then Error Err 'OpenProcess API Failed End If bufferMem = VirtualAllocEx(processHandle, 0, size, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE) If bufferMem = 0 Then Error Err 'VirtualAllocEx API Failed End If ' Send message to the control's HWND for getting the ' Specified control name. retLength = SendMessage(wnd, msg, size, ByVal bufferMem) If retLength <> 0 Then ' Now read the component's name from the shared memory location. Call WriteProcessMemory(processHandle, bufferMem, bytearray, size, lp) retVal = ReadProcessMemory(processHandle, bufferMem, bytearray, size, lp) If retVal = 0 Then Error Err 'ReadProcessMemory API Failed End If End If Error_Handler_NT: errNum = Err errDescription = Error$ ' Free the memory that was allocated. retVal = VirtualFreeEx(processHandle, bufferMem, 0, MEM_RELEASE) If retVal = 0 Then Error Err 'VirtualFreeEx API Failed End If CloseHandle (processHandle) If errNum <> 0 Then On Local Error GoTo 0 Error errNum ', errDescription End If On Local Error GoTo 0 Else On Local Error GoTo Error_Handler_9x Dim SA As SECURITY_ATTRIBUTES fileHandle = CreateFileMapping(INVALID_HANDLE_VALUE, SA, PAGE_READWRITE, 0, size, Null) If fileHandle = 0 Then Error Err 'CreateFileMapping API Failed End If bufferMem = MapViewOfFile(fileHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0) If bufferMem = 0 Then Error Err 'MapViewOfFile API Failed End If Call CopyMemory(bufferMem, bytearray, size) ' Send message to the treeview control's HWND for ' getting the specified control's name. retLength = SendMessage(wnd, msg, size, bufferMem) ' Read the control's name from the specific shared memory ' for the buffer. Call CopyMemoryA(bytearray, bufferMem, 1024) Error_Handler_9x: errNum = Err errDescription = Error$ ' Unmap and close the file. UnmapViewOfFile (bufferMem) CloseHandle (fileHandle) If errNum <> 0 Then On Local Error GoTo 0 Error errNum 'errDescription End If On Local Error GoTo 0 End If If retLength <> 0 Then ' Get the string value for the Control name. GetWindowsFormsID = ByteArrayToString(bytearray, retLength) End If End Function Function IsWin9x() As Boolean Dim osVerInfo As OSVERSIONINFO osVerInfo.dwOSVersionInfoSize = 128 + 4 * 5 Dim l As Long l = GetVersionEx(osVerInfo) IsWin9x = osVerInfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS End Function Function ByteArrayToString(bytes As String, length As Long) As String Dim retValStr As String Dim l As Long If IsWin9x() Then retValStr = Left(bytes, InStr(1, bytes, Chr(0)) - 1) Else retValStr = String$(length + 1, Chr(0)) l = WideCharToMultiByte(CP_ACP, 0, bytes, -1, retValStr, length + 1, Null, Null) End If ByteArrayToString = retValStr End Function And some declarations: Public Const MEM_COMMIT As Long = &H1000 Public Const MEM_RESERVE As Long = &H2000 Public Const MEM_RELEASE = &H8000& Public Const PAGE_READWRITE = &H4 Public Const PROCESS_VM_OPERATION = &H8 Public Const PROCESS_VM_READ = &H10 Public Const PROCESS_VM_WRITE = &H20 Declare Function VirtualAllocEx Lib "kernel32" _ (ByVal hProcess As Long, _ ByVal lpAddress As Long, _ ByVal dwSize As Long, _ ByVal flAllocationType As Long, _ ByVal flProtect As Long) As Long Declare Function ReadProcessMemory Lib "kernel32" _ (ByVal hProcess As Long, _ ByVal lpBaseAddress As Long, _ lpBuffer As Any, _ ByVal nSize As Long, _ lpNumberOfBytesRead As Long) As Long Declare Function VirtualFreeEx Lib "kernel32" _ (ByVal hProcess As Long, _ ByVal lpAddress As Long, _ ByVal dwSize As Long, _ ByVal dwFreeType As Long) As Long Declare Function WriteProcessMemory Lib "kernel32" _ (ByVal hProcess As Long, _ ByVal lpBaseAddress As Long, _ lpBuffer As Any, _ ByVal nSize As Long, _ lpNumberOfBytesWritten As Long) As Long I got error in WideCharToMultiByte: Run-time error '94': Invalid use of Null It seems like bytes in ByteArrayToString is empty. What am I doing wrong?

Post a reply

No one has replied yet! Why not be the first?

Sign in or Join us (it's free).

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” - Brian Kernighan