excel - 在 SendMessage 中使用 WM_GETTEXT 时,VBA 崩溃
问题描述
在下面的代码中,我试图从第三方应用程序中获取一个字符串到一个变量中,但是当它到达该SendMessage
行时程序崩溃了。请帮忙。
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Boolean
Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_GETTEXT As Integer = &HD
Private Const WM_GETTEXTLENGTH As Integer = &HE
sub test()
Dim hWndFind As Long, textbox As Long, main_win as long, s as string
main_win = FindWindow(vbNullString, "Exenta Solution")
hWndFind = FindWindowEx(main_win , 0, "WindowsForms10.MDICLIENT.app.0.141b42a_r6_ad1", vbNullString)
textbox = FindWindowEx(hWndFind, 0 , "WindowsForms10.EDIT.app.0.141b42a_r6_ad1", vbNullString)
Dim buff As String
textlen = SendMessage(textbox, WM_GETTEXTLENGTH, 0, 0)
buff = Space(textlen)
s = SendMessage(textbox, WM_GETTEXT, textlen, buff) **=========> crashes here**
END SUB
解决方案
首先,按照您的要求SendMessage
返回 a Long
,但s
它是一种String
类型,根据WM_GETTEXT
:
返回值是复制的字符数,不包括终止空字符。
所以添加:
Dim ret As Long
然后WM_GETTEXTLENGTH
以字符为单位返回文本的长度,也不包括终止的空字符。但是wParam
ofWM_GETTEXT
必须包含终止空字符的空格。
最后,您需要传递ByVal buff
作为最后一个参数。或者只使用GetWindowText
您声明的:
sub test()
Dim hWndFind As Long, textbox As Long, main_win as Long, textlen as Long
main_win = FindWindow(vbNullString, "Exenta Solution")
hWndFind = FindWindowEx(main_win , 0, "WindowsForms10.MDICLIENT.app.0.141b42a_r6_ad1", vbNullString)
textbox = FindWindowEx(hWndFind, 0 , "WindowsForms10.EDIT.app.0.141b42a_r6_ad1", vbNullString)
Dim buff As String
textlen = SendMessage(textbox, WM_GETTEXTLENGTH, 0, 0)
buff = Space(textlen)
Dim ret As Long
ret = SendMessage(textbox, WM_GETTEXT, textlen + 1, ByVal buff)
ret = GetWindowText(textbox, buff, textlen + 1)
END SUB
推荐阅读
- c++ - 参考折叠规则未按预期应用?
- amazon-web-services - 即使只有一个请求,AWS 上的 Websocket 连接也总是会导致太多请求
- c# - 如何在 CustomControl 中“注入”不同的 ControlTemplate?
- r - 在 dplyr 中使用 R DataFrame 中的用户定义函数
- python - RMSprop 优化器不会改变准确性和损失
- php - Laravel 关系使用 Where
- excel - VBA,如果不为空,则执行行
- javascript - 检查是否启用了第三方 cookie,页面在 iframe 中呈现
- html - 为什么不能在 flexbox 模型中居中 div
- string - Oracle 12c:在 SQLdeveloper 中尝试使用时,listagg 函数无法识别“on overflow”子句