Api 钩住VBE窗口的子类SysTreeView32

Api 钩住VBE窗口的子类SysTreeView32,api,winapi,vba,parent-child,Api,Winapi,Vba,Parent Child,虽然熟悉VBA,但我对WinApi调用还是相当陌生。我试图做的是挂接到VBE窗口(Project Explorer TreeView)的子类SysTreeView32。我希望通过修改注册表项(或者发送鼠标点击(鼠标事件))来展开/折叠树视图元素,尽管我更喜欢第一个选项。 我可以使用以下代码找到Excel主窗口: Declare Function FindWindow Lib "user32" Alias "FindWindowA" _

虽然熟悉VBA,但我对WinApi调用还是相当陌生。我试图做的是挂接到VBE窗口(Project Explorer TreeView)的子类SysTreeView32。我希望通过修改注册表项(或者发送鼠标点击(鼠标事件))来展开/折叠树视图元素,尽管我更喜欢第一个选项。
我可以使用以下代码找到Excel主窗口:

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
在的帮助下,我可以访问子类的名称、属性等

但我无法确定如何访问/激活(甚至返回)子类的HWID以折叠/展开元素(文件夹)。我还不确定如何迭代这些元素,但我将在以后对此进行研究。这里的问题是访问
SysTreeView32
类。我怎样才能实现它?

当我尝试msgbox这个
FindWindow(“wndclass\u desked\u gsk”,Application.Caption)


FindWindow(“系统视图32”,Application.Caption)

返回了
0
,因此我显然做错了什么:/
谢谢你抽出时间。
您应该使用:

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
Private Const TVE_COLLAPSE=&H1
私人康斯特电视大学学院设置=&H8000
专用常量TVE_EXPAND=&H2
专用常数TVE_EXPANDPARTIAL=&H4000
私有常量TVE_切换=&H3
私人康斯特电视台优先=&H1100
专用Const TVM_EXPAND=(TV_FIRST+2)
私有Const TVM_GETNEXTITEM=(TV_FIRST+10)
Private Const TVGN_ROOT=&H0
私有Const TVGN_NEXTVISIBLE=&H6
声明函数FindWindowEx Lib“user32”别名“FindWindowExA”_
(ByVal hWnd1为长,ByVal hWnd2为长,ByVal lpsz1为字符串,ByVal lpsz2为字符串)为长
公共声明函数SendMessage Lib“user32”别名“SendMessageA”_
(ByVal hWnd为长,ByVal wMsg为长,ByVal wParam为长,ByVal lParam为长)为长
子CollapseProjects()
Dim hWndVBE为长,hWndPE为长,HWNDTWW为长,hNode为长,VARROUNT
hWndVBE=FindWindowEx(0,0,“wndclass_desked_gsk”,Application.VBE.MainWindow.Caption)
hWndPE=FindWindowEx(hWndVBE,0,“项目”,vbNullString)
hWndTvw=FindWindowEx(hWndPE,0,“系统视图32”,vbNullString)
hNode=SendMessage(hWndTvw、TVM\u GETNEXTITEM、TVGN\u根目录、0&)
在hNode 0时执行此操作
varReturn=SendMessage(hWndTvw,TVM_展开,TVE_折叠,hNode)
hNode=SendMessage(hWndTvw、TVM_GETNEXTITEM、TVGN_NEXTVISIBLE、hNode)
环
端接头
除您的评论外,以下是仅折叠“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
声明函数FindWindowEx Lib“user32”别名“FindWindowExA”_
(ByVal hWnd1为长,ByVal hWnd2为长,ByVal lpsz1为字符串,ByVal lpsz2为字符串)为长
公共声明函数SendMessage Lib“user32”别名“SendMessageA”_
(ByVal hwnd为长,ByVal wMsg为长,ByVal wParam为长,ByVal lParam为长)为长
公共声明函数SendMessageB Lib“user32”别名“SendMessageA”_
(ByVal hwnd为Long,ByVal wMsg为Long,ByVal wParam为Long,ByRef lParam为任意)为Long
专用常量最大项目长度=256
私人Const TV_第一个长度=&H1100
私有Const TVM_扩展为Long=(TV_FIRST+2)
私有Const TVM_GETNEXTITEM As Long=(TVM_FIRST+10)
私有Const TVM_GETITEM As Long=(TV_FIRST+12)
Const TVE_坍缩长度=&H1
常数TVE_展开为Long=&H2
Private Const TVGN_根长度=&H0
私有Const TVGN_下一个长度=&H1
Private Const TVIF_文本长度=&H1
私有Const TVGN_NEXTVISIBLE=&H6
私有类型tviitem'是TV_项
面具一样长
希特姆,只要
国家只要
国家面具
pszText作为字符串
cchTextMax尽可能长
我想象的一样长
我选择的图像越长越好
孩子们只要
lpram尽可能长
端型
子CollapseXLObjects()
变暗hWndVBE为长
暗淡的hWndPE与长的一样
变暗HWndtWw为长
与长一样暗的hNode
变暗tvi作为tviitem
灰白如长
作为字符串的Dim sText
暗变回
hWndVBE=FindWindowEx(0,0,“wndclass_desked_gsk”,Application.VBE.MainWindow.Caption)
hWndPE=FindWindowEx(hWndVBE,0,“项目”,vbNullString)
hWndTvw=FindWindowEx(hWndPE,0,“系统视图32”,vbNullString)
hNode=SendMessage(hWndTvw、TVM\u GETNEXTITEM、TVGN\u根目录、0&)
在hNode 0时执行此操作
tvi.hItem=hNode
tvi.mask=TVIF\u文本
tvi.cchTextMax=最大项目
tvi.pszText=字符串(最大项,0)
nChild=SendMessageB(hWndTvw,TVM\u GETITEM,0&,tvi)
如果InStr(1,tvi.pszText,“Microsoft Excel对象”,vbTextCompare)>0,则
varReturn=SendMessage(hWndTvw,TVM_展开,TVE_折叠,hNode)
其他的
varReturn=SendMessage(hWndTvw,TVM_EXPAND,TVE_EXPAND,hNode)
如果结束
hNode=SendMessage(hWndTvw、TVM_GETNEXTITEM、TVGN_NEXTVISIBLE、hNode)
环
端接头

如果从另一个子模块调用此子模块(在我的例子中,是链接到打开VBE的自定义按钮的XL加载项中的子模块),并且高亮显示另一个模块(可能在另一个项目中),则我已找到

    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
在包含
子CollapseXLObjects的模块中
声明

    Public WinName As String
以及在
子折叠对象中

    hWndVBE = FindWindowEx(0, 0, "wndclass_desked_gsk", WinName)

+∞ 这太完美了!我将不得不修改它,以便只折叠Microsoft Excel对象,但我认为我将能够自己管理它!。。。嗯,我不知道