При использовании WM_GETTEXT в SendMessage VBA аварийно завершает работу - PullRequest
0 голосов
/ 17 июня 2020

В приведенном ниже коде я пытаюсь получить строку из стороннего приложения в переменную, но программа вылетает, когда достигает строки 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

1 Ответ

1 голос
/ 17 июня 2020

Во-первых, SendMessage возвращает Long, как вы указали, но s является типом String, согласно WM_GETTEXT:

возвращаемое значение - это количество скопированных символов, не включая завершающий нулевой символ.

Итак, добавьте:

Dim ret As Long

Затем WM_GETTEXTLENGTH возвращает длину текста в символах, также без завершающего нулевого символа . Но wParam из WM_GETTEXT должен включать пробел для завершающего нулевого символа .

Наконец, вам нужно передать ByVal buff в качестве последнего параметра. Или просто используйте GetWindowText, который вы объявили:

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)
  Dim ret As String
  ret = SendMessage(textbox, WM_GETTEXT, textlen + 1, buff) 
  ret = GetWindowText(textbox, buff, textlen + 1)
END SUB
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...