У меня есть требование проходить элементы из древовидного элемента управления во внешней системе через Win32 API в коде VBA с помощью Spy ++.Я могу сказать, что имя класса элемента управления - SysTreeView32.
Возьмите в качестве примера обозреватель Win-7, слева от проводника, то есть элемента управления древовидной структуры, мне удается просмотреть все его элементы.с помощью sendmessage API, но не в состоянии получить детали каждого элемента.
Что касается моих кодов, строка result = SendMessage(hTreeView, TVM_GETITEMA, False, ByVal vPointer)
возвращает 0. Это может быть основной причиной.
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As String, ByVal Source As Long, ByVal Length As Long)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32.dll" (ByVal hProcess As Long, lpAddress As Any, ByRef dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32.dll" (ByVal hProcess As Long, lpAddress As Any, ByRef dwSize As Long, ByVal dwFreeType As Long) As Long
Private 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
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, llpBufferfer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Const TVGN_ROOT = &H0
Private Const TVGN_CHILD = &H4
Private Const TVGN_Next = &H1
Private Const TVGN_Caret = &H9
Private Const TVGN_Previous = &H2
Private Const TVGN_Parent = &H3
Private Const TVGN_FirstVisible = &H5
Private Const TVGN_NextVisible = &H6
Private Const TVGN_PreviousVisible = &H7
Private Const TVGN_LastVisible = &H10
Private Const TVGN_DropHilite = &H8
Private Const TV_FIRST = &H1100
Private Const TVM_GETITEMRECT As Long = (TV_FIRST + 4)
Private Const TVM_GETNEXTITEM As Long = (TV_FIRST + 10)
Private Const TVM_SELECTITEM As Long = (TV_FIRST + 11)
Private Const TVM_DELETEITEM As Long = (TV_FIRST + 1)
Private Const TVM_GETCOUNT = (TV_FIRST + 5)
Private Const TVM_HITTEST = (TV_FIRST + 17)
Private Const TVM_GETITEM = (TV_FIRST + 12)
Private Const TVM_GETITEMA = (TV_FIRST + 12)
Private Const TVM_GETITEMW = (TV_FIRST + 62)
Private Const TVHT_ONITEMLABEL = &H4
Private Const TVIF_TEXT = &H1
Private Const GMEM_FIXED = &H0
Private Const TVM_EXPAND As Long = &H1102
Private Const WM_SETREDRAW As Long = &HB
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Const MEM_DECOMMIT = &H4000
Private Const MEM_RELEASE = &H8000
Private Const MEM_COMMIT = &H1000
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Const MAX_LVMSTRING As Long = 255
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Type TVITEM
mask As Long
HTreeItem As Long
state As Long
stateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
iSelectedImage As Long
cChildren As Long
lParam As Long
End Type
Sub test2()
Dim Flag As Long
Dim hTreeView As Long
Dim hTVRoot As Long
Dim hTVItem As Long
Dim vProcessId As Long
Dim vProcess As Long
Dim vPointer As Long
Dim vItemCount As Long
Dim pMyItemMemory As Long
Dim i As Long
Dim result As Long
Dim bytes As Long
Dim vItem As TVITEM
Dim tmpItem As TVITEM
Dim strBuffer() As Byte
Dim tmpString As String
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ReDim strBuffer(MAX_LVMSTRING)
hTreeView = 1379188 'Handle by SPY++
Call GetWindowThreadProcessId(hTreeView, vProcessId)
vProcess = OpenProcess(PROCESS_ALL_ACCESS, False, vProcessId)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hTVRoot = SendMessage(hTreeView, TVM_GETNEXTITEM, TVGN_ROOT, ByVal 0&)
hTVItem = SendMessage(hTreeView, TVM_GETNEXTITEM, TVGN_CHILD, ByVal hTVRoot)
SendMessage hTreeView, TVM_SELECTITEM, TVGN_Caret, ByVal hTVItem
Flag = SendMessage(hTreeView, TVM_EXPAND, TVM_EXPAND, ByVal hTVRoot)
vPointer = VirtualAllocEx(vProcess, ByVal 0&, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
With vItem
.mask = TVIF_TEXT
.HTreeItem = hTVItem
.pszText = vPointer
.cchTextMax = MAX_LVMSTRING
End With
result = WriteProcessMemory(vProcess, ByVal vPointer, vItem, LenB(vItem), 0)
result = SendMessage(hTreeView, TVM_GETITEMA, False, ByVal vPointer)
result = ReadProcessMemory(vProcess, ByVal vPointer, strBuffer(0), LenB(tmpItem), 0)
tmpString = StrConv(strBuffer, vbUnicode)
Call VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE)
Call CloseHandle(vProcess)
End Sub