获取Excel InputBox方法的hwnd
我想我有一个相当简单的问题。我正在寻找一种方法来获取excel输入框的hwnd。我正在自动化一个过程,我注意到一个8型输入框始终位于excel窗口下面(如果有帮助的话,我正在从另一个应用程序自动化excel)。显然,我希望它显示在顶部,我正在尝试使用setForeGroundIndow函数。有什么建议吗 根据要求,我发现唯一值得一试的东西是:获取Excel InputBox方法的hwnd,excel,vba,hwnd,inputbox,Excel,Vba,Hwnd,Inputbox,我想我有一个相当简单的问题。我正在寻找一种方法来获取excel输入框的hwnd。我正在自动化一个过程,我注意到一个8型输入框始终位于excel窗口下面(如果有帮助的话,我正在从另一个应用程序自动化excel)。显然,我希望它显示在顶部,我正在尝试使用setForeGroundIndow函数。有什么建议吗 根据要求,我发现唯一值得一试的东西是: Public Function GetHwnd() as Long GetHwnd = Excel.Application.InputBox.h
Public Function GetHwnd() as Long
GetHwnd = Excel.Application.InputBox.hwnd
End Function
这不是一个简单的问题——答案围绕着VBA中几个令人沮丧的漏洞 VBA.InputBox函数创建一个“模式对话框”,当您需要VBA获取窗口句柄并调用某些或其他API函数时,该对话框使应用程序的VBA代码处于等待状态 当“模态”状态被释放时,允许VBA再次运行命令和API函数,InputBox已经消失 幸运的是,“manish1239”在2003年10月发现了一个变通方法,他发布了一个巧妙的破解:他使用API计时器的延迟回调,将需要运行的代码放在围绕等待状态运行的VBA函数中 我使用他的代码在VBA InputBox中设置“PasswordChars”:这是一个需要InputBox窗口句柄的API调用,您可以根据需要修改代码 #如果VBA7,则“32位Office中的VBA7”仅使用LongPtr,LongLong不可用
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As LongPtr, _
ByVal hWnd2 As LongPtr, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String _
) As LongPtr
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByRef lParam As Any _
) As LongPtr
Private Declare PtrSafe Function SetTimer Lib "user32" _
(ByVal hwnd As LongPtr, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As LongPtr) As LongPtr
Private Declare PtrSafe Function KillTimer Lib "user32" _
(ByVal hwnd As LongPtr, _
ByVal nIDEvent As Long) As Long
#Else的32位Excel
Public Sub TimerProcInputBox(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal idEvent As Long, _
ByVal dwTime As Long)
On Error Resume Next
' REQUIRED for Function InputBoxPassword
' https://msdn.microsoft.com/en-US/library/windows/desktop/ms644907(v=vs.85).aspx
Dim hWndIbox As Long ' Handle to VBA InputBox
KillTimer hwnd, idEvent
hWndIbox = FindWindowEx(FindWindow("#32770", PASSBOX_INPUT_CAPTION), 0&, "Edit", "")
If hWndIbox <> 0 Then
SendMessage hWndIbox, EM_SETPASSWORDCHAR, Asc("*"), 0&
End If
End Sub
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 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, _
ByRef lParam As Any _
) As Long
Private Declare Function SetTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long) As Long
#如果结束
Private Const PASSBOX\u INPUT\u标题为String=“需要密码”
Private Const EM_SETPASSWORDCHAR As Long=&HCC
专用Const NV_输入框长度=&H5000&
我在我的博客Excellerando上发布了以下内容:
像往常一样,要注意代码中不必要的换行符。如果您有不起作用的代码,最好包含它。我会添加它,但它或多或少是无用的。我只是需要一些方法来获取输入框的hwnd。这个答案有用吗@RichardMorgan它应该回答这个问题:)OP需要使用WinAPI中的
findwindowe
和FindWindowEx
和SendMessage
函数。这些都包含在链接到问题的公认答案中。@RichardMorgan技术上是,技术上不是。这让我走上了我认为我在寻找的正确道路,但事实证明,我只需要调整隐藏和显示窗口的时间和顺序,以获得我想要的效果。至于查找输入框窗口,由于代码拖在该行上,我不确定您是否可以在vba中编写代码来查找该窗口的句柄。如果这有道理的话,但我也可能不对。无论如何,我找到了解决问题的方法,感谢大家的帮助和建议!
Option Explicit
Option Private Module
#If VBA7 And Win64 Then ' 64 bit Excel under 64-bit windows ' Use LongLong and LongPtr
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _ (ByVal hWnd1 As LongPtr, _ ByVal hWnd2 As LongPtr, _ ByVal lpsz1 As String, _ ByVal lpsz2 As String _ ) As LongPtr Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, _ ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As LongPtr, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any _ ) As LongPtr Private Declare PtrSafe Function SetTimer Lib "user32" _ (ByVal hwnd As LongPtr, _ ByVal nIDEvent As LongPtr, _ ByVal uElapse As Long, _ ByVal lpTimerFunc As LongPtr _ ) As Long Public Declare PtrSafe Function KillTimer Lib "user32" _ (ByVal hwnd As LongPtr, _ ByVal nIDEvent As LongPtr _ ) As Long
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _ (ByVal hWnd1 As LongPtr, _ ByVal hWnd2 As LongPtr, _ ByVal lpsz1 As String, _ ByVal lpsz2 As String _ ) As LongPtr Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, _ ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As LongPtr, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByRef lParam As Any _ ) As LongPtr Private Declare PtrSafe Function SetTimer Lib "user32" _ (ByVal hwnd As LongPtr, _ ByVal nIDEvent As Long, _ ByVal uElapse As Long, _ ByVal lpTimerFunc As LongPtr) As LongPtr Private Declare PtrSafe Function KillTimer Lib "user32" _ (ByVal hwnd As LongPtr, _ ByVal nIDEvent As Long) 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 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, _ ByRef lParam As Any _ ) As Long Private Declare Function SetTimer Lib "user32" _ (ByVal hwnd As Long, _ ByVal nIDEvent As Long, _ ByVal uElapse As Long, _ ByVal lpTimerFunc As Long) As Long Public Declare Function KillTimer Lib "user32" _ (ByVal hwnd As Long, _ ByVal nIDEvent As Long) As Long