首页 > 解决方案 > 在 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

标签: excelvbawinapi

解决方案


首先,按照您的要求SendMessage返回 a Long,但s它是一种String类型,根据WM_GETTEXT

返回值是复制的字符数,不包括终止空字符。

所以添加:

Dim ret As Long

然后WM_GETTEXTLENGTH以字符为单位返回文本的长度,也不包括终止的空字符。但是wParamofWM_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

推荐阅读