【发布时间】:2021-06-25 22:18:52
【问题描述】:
我需要有关获取 VBA 项目属性对话框的 hWnd 的帮助。 我正在尝试学习 VBA,并且对 VBE 编程很感兴趣。 我阅读并成功测试了以下链接中的说明:
Unprotect VBProject from VB code
在以下链接进一步阅读后:
http://www.standards.com/Office/SetVBAProjectPassword.html
在尝试处理那里的信息时,我发现如果不运行另一个 Excel 实例,我无法获得 VBA 项目属性对话框窗口的窗口句柄 hWnd...
我的问题是:
1.如何获取当前运行的Excel实例的VBA项目属性对话框窗口的hWnd?
2.为什么不运行第二个 Excel 实例就无法获得 VBA 项目属性对话框窗口的 hWnd?
我还附上了我复制和编辑的代码,如下所示。 这是我在这里的第一个问题,所以请原谅我的任何格式问题,如果有人发现这篇文章不遵守论坛规则,请告诉我。我已经准备好纠正它了。 我已经搜索了论坛帖子,但只找到了一些相关的话题,这些话题并不能完全解决我的问题。 提前致谢。
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private 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
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias _
"GetWindowTextLengthA" (ByVal hWnd As Long) 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 Function GetActiveWindow Lib "user32.dll" () As Long
Dim Ret As Long, ChildRet As Long, OpenRet As Long
Dim strBuff As String, ButCap As String
Const WM_SETTEXT = &HC
Const BM_CLICK = &HF5
'ThisWorkbook.VBProject.References.AddFromGuid _
GUID:="{0002E157-0000-0000-C000-000000000046}", _
Major:=5, Minor:=3
Sub test1()
Dim hWndOfProjectPropertiesOfThisProject As Long
ThisWorkbook.VBProject.VBE.CommandBars(1).FindControl(ID:=2578, recursive:=True, Visible:=False).Execute
'hWndOfProjectPropertiesOfThisProject = GetActiveWindow
'Debug.Print hWndOfProjectPropertiesOfThisProject
GethWndOfProjectPropertiesWindow
End Sub
Sub test2()
OpenANewExcel
GethWndOfProjectPropertiesWindow
End Sub
Sub OpenANewExcel()
Dim xlAp As Object, oWb As Object, sWb As Object
Dim strpath As String
Set xlAp = CreateObject("Excel.Application")
xlAp.Visible = True
strpath = ThisWorkbook.Path + "\" + ThisWorkbook.Name
Set oWb = xlAp.Workbooks.Open(strpath)
oWb.Activate
xlAp.Parent.Windows(1).Visible = True
xlAp.VBE.CommandBars(1).FindControl(ID:=2578, recursive:=True, Visible:=False).Execute
End Sub
Sub GethWndOfProjectPropertiesWindow()
Dim hWndProjectProperties As Long
hWndProjectProperties = FindWindow(vbNullString, "VBAProject - Project Properties")
Debug.Print "hWnd = " & hWndProjectProperties
End Sub
我还阅读了 cpearson.com/excel/vbe.aspx(不能发布超过 2 个链接)
【问题讨论】:
-
1.使用计时器;和 2. 因为当您显示该对话框时您的代码将停止。 3. 为什么不能使用单独的实例?
-
我可以使用单独的实例。单独实例的问题是,在我关闭原始实例后,第二个实例将等待片刻以显示读/写对话框,我认为这不是很优雅。我不确定,但我认为当我显示该对话框时代码执行并没有停止(我已经通过在显示该对话框之前和之后添加 debug.prints 进行了检查。但可能是我错了。如果代码执行在那个时候停止显示对话框,为什么在运行第二个实例时它没有停止?我不想变得聪明,因为我不聪明,我只是在学习。
-
没关系,我可能记错了,对话框可能不是模态的。但是您需要暂停一下,以便在 FindWindow 运行之前显示窗口。
-
定时器是指使用Application.OnTime函数?调用 FindWindow API 函数?抱歉,我还在学习 VBA。该对话框是模态的。但是当我检查 debug.print 时,它会在 API 调用前后打印出来。
-
不,使用 SetTimer API 的 windows 计时器。请参阅下面的示例。