Подключиться к дочернему классу SysTreeView32 окна VBE

Я новичок в вызовах WinApi, хотя знаком с VBA. Я пытаюсь подключиться к дочернему классу SysTreeView32 окна VBE (Project Explorer TreeView). Я хотел бы развернуть / свернуть элементы представления в виде дерева, изменив ключи реестра (или, в качестве альтернативы, отправив щелчки мыши (mouse_event), хотя я предпочитаю первый вариант).
Я могу найти главное окно Excel, используя этот код: < br>

Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
              (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Sub Find_Window()
    Dim hWndExcel As Long
    hWndExcel = FindWindow("XLMAIN", Application.Caption)
    MsgBox hWndExcel
End Sub

С помощью Window Detective я могу получить доступ к именам, свойствам и т. Д. Дочернего элемента. классы.
Дочерние классы Window Detective
Но я не могу понять, как получить доступ / активировать (или даже вернуть HWID) SysTreeView32 дочернего класса, чтобы свернуть / развернуть элементы (папки). Я еще не уверен, как перебирать элементы, но позже я исследую это. Проблема здесь в доступе к классу SysTreeView32. Как я могу этого добиться?

Когда я пытаюсь отправить в msgbox это
FindWindow("wndclass_desked_gsk", Application.Caption)
или
FindWindow("SysTreeView32", Application.Caption)
возвращается 0, поэтому я, очевидно, делаю что-то не так: /
Спасибо на ваше время.


person Community    schedule 11.06.2013    source источник


Ответы (2)


вам следует использовать:

application.vbe.mainwindow.caption

вот пример кода коллапса

Private Const TVE_COLLAPSE = &H1
Private Const TVE_COLLAPSERESET = &H8000
Private Const TVE_EXPAND = &H2
Private Const TVE_EXPANDPARTIAL = &H4000
Private Const TVE_TOGGLE = &H3
Private Const TV_FIRST = &H1100
Private Const TVM_EXPAND = (TV_FIRST + 2)
Private Const TVM_GETNEXTITEM = (TV_FIRST + 10)
Private Const TVGN_ROOT = &H0
Private Const TVGN_NEXTVISIBLE = &H6

Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
                              (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                                    (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Sub CollapseProjects()
   Dim hWndVBE As Long, hWndPE As Long, hWndTvw As Long, hNode As Long, varReturn
   hWndVBE = FindWindowEx(0, 0, "wndclass_desked_gsk", Application.VBE.MainWindow.Caption)
   hWndPE = FindWindowEx(hWndVBE, 0, "PROJECT", vbNullString)
   hWndTvw = FindWindowEx(hWndPE, 0, "SysTreeView32", vbNullString)
   hNode = SendMessage(hWndTvw, TVM_GETNEXTITEM, TVGN_ROOT, 0&)
   Do While hNode <> 0
      varReturn = SendMessage(hWndTvw, TVM_EXPAND, TVE_COLLAPSE, hNode)
      hNode = SendMessage(hWndTvw, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hNode)
   Loop
End Sub

далее к вашему комментарию, вот код, чтобы свернуть только узлы «Объекты Microsoft Excel»

Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
                              (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                                    (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SendMessageB Lib "user32" Alias "SendMessageA" _
                                     (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long

Private Const MAX_ITEM        As Long = 256
Private Const TV_FIRST        As Long = &H1100
Private Const TVM_EXPAND      As Long = (TV_FIRST + 2)
Private Const TVM_GETNEXTITEM As Long = (TV_FIRST + 10)
Private Const TVM_GETITEM     As Long = (TV_FIRST + 12)
Const TVE_COLLAPSE            As Long = &H1
Const TVE_EXPAND              As Long = &H2
Private Const TVGN_ROOT       As Long = &H0
Private Const TVGN_NEXT       As Long = &H1
Private Const TVIF_TEXT       As Long = &H1
Private Const TVGN_NEXTVISIBLE = &H6

Private Type TVITEM   ' was TV_ITEM
   mask                       As Long
   hItem                      As Long
   state                      As Long
   stateMask                  As Long
   pszText                    As String
   cchTextMax                 As Long
   iImage                     As Long
   iSelectedImage             As Long
   cChildren                  As Long
   lParam                     As Long
End Type


Sub CollapseXLObjects()
   Dim hWndVBE                As Long
   Dim hWndPE                 As Long
   Dim hWndTvw                As Long
   Dim hNode                  As Long
   Dim tvi                    As TVITEM
   Dim nChild                 As Long
   Dim sText                  As String
   Dim varReturn

   hWndVBE = FindWindowEx(0, 0, "wndclass_desked_gsk", Application.VBE.MainWindow.Caption)
   hWndPE = FindWindowEx(hWndVBE, 0, "PROJECT", vbNullString)
   hWndTvw = FindWindowEx(hWndPE, 0, "SysTreeView32", vbNullString)

   hNode = SendMessage(hWndTvw, TVM_GETNEXTITEM, TVGN_ROOT, 0&)

   Do While hNode <> 0
      tvi.hItem = hNode
      tvi.mask = TVIF_TEXT
      tvi.cchTextMax = MAX_ITEM
      tvi.pszText = String(MAX_ITEM, 0)
      nChild = SendMessageB(hWndTvw, TVM_GETITEM, 0&, tvi)
      If InStr(1, tvi.pszText, "Microsoft Excel Objects", vbTextCompare) > 0 Then
         varReturn = SendMessage(hWndTvw, TVM_EXPAND, TVE_COLLAPSE, hNode)
      Else
         varReturn = SendMessage(hWndTvw, TVM_EXPAND, TVE_EXPAND, hNode)
      End If
      hNode = SendMessage(hWndTvw, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hNode)
   Loop
End Sub
person JosieP    schedule 11.06.2013
comment
+ ∞ это просто идеально! Мне просто нужно будет изменить его, чтобы свернуть только объекты Microsoft Excel, но я думаю, что смогу управлять им самостоятельно! ... ну, я не думаю, что я просто буду играть с ним сейчас, и я не полностью понимая это еще - person ; 11.06.2013
comment
Я обновил код, чтобы проверить текст узла и скрыть только объекты Excel. - person JosieP; 12.06.2013

Если вы вызываете эту подпрограмму из другой подпрограммы (в моем случае подпрограмма в надстройке XL связана с настраиваемой кнопкой, которая открывает VBE), и выделяется другой модуль (который может быть в другом проекте), то я обнаружил

    Application.VBE.MainWindow.Caption

не работает. Для захвата выделенного модуля я использую:

    Private Sub VisualBasicEditor()
      On Error Resume Next
      WinName = "Microsoft Visual Basic - " + ActiveWorkbook.Name + " [Running] - [" + Application.VBE.ActiveCodePane.CodeModule.Name + " (Code)]"
      Application.VBE.MainWindow.Visible = True
      Call CollapseXLObjects
    End Sub

и в модуле, содержащем Sub CollapseXLObjects declare

    Public WinName As String

и в Sub CollapseXLObjects

    hWndVBE = FindWindowEx(0, 0, "wndclass_desked_gsk", WinName)
person Adam Pride    schedule 28.10.2015