获取Excel InputBox方法的hwnd

获取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

我想我有一个相当简单的问题。我正在寻找一种方法来获取excel输入框的hwnd。我正在自动化一个过程,我注意到一个8型输入框始终位于excel窗口下面(如果有帮助的话,我正在从另一个应用程序自动化excel)。显然,我希望它显示在顶部,我正在尝试使用setForeGroundIndow函数。有什么建议吗

根据要求,我发现唯一值得一试的东西是:

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