Reputation: 221
I try to read text from another app(for example Notepad or Wordpad). I must do that in VB 6 in witch I not have programmed before, but i cannot use other language.
I find code for Vb.Net and i modified it for VB 6, but i always get error: "Run-time Error '424': Object Required"
Code is:
Const WM_GETTEXTLENGTH = &HE
Const WM_GETTEXT = &HD
Private Declare Function FindWindow Lib "USER32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String _
) As Long
Private Declare Function FindWindowEx Lib "USER32" Alias "FindWindowExA" ( _
ByVal hWndParent As Long, _
ByVal hWndChildAfter As Long, _
ByVal lpszClassName As String, _
ByVal lpszWindowName As String _
) As Long
Private Declare Function GetWindowText Lib "USER32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "USER32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" ( _
ByVal hWnd As Long, ByVal Msg As Long, _
wParam As Any, lParam As Any) As Long
Private Sub Command1_Click()
Dim notepadHandle As Long
notepadHandle = FindWindow("Notepad", vbNullString)
Dim childhandle As Long
childhandle = FindWindowEx(notepadHandle, 0, "Edit", vbNullString)
If notepadHandle = 0 Then
MessageBox.Show ("can't find")
Else
'MessageBox.Show (CStr(childhandle))
' MessageBox.Show (WindowText(childhandle))
MessageBox.Show (WindowText(childhandle))
End If
End Sub
Public Function WindowText(ByVal window_hwnd As Long) As String
Dim txtlen As Integer
WindowText = ""
If window_hwnd = 0 Then Exit Function
txtlen = SendMessage(window_hwnd, WM_GETTEXTLENGTH, 0, _
0)
If txtlen = 0 Then Exit Function
txtlen = txtlen + 1
Dim txt As String
txt = String(txtlen + 1, Chr$(0))
txt = Convert.ToString(SendMessage(window_hwnd, WM_GETTEXT, txtlen, txt))
WindowText = Convert.ToString(txt)
End Function
Where I make mistake?
Thanx
Upvotes: 1
Views: 5696
Reputation: 5689
Don't expect VB.NET samples to work in VB6. The two languages are incompatible on a number of levels, not just because VB6 doesn't use the .NET framework. The syntax is slightly different, too.
First of all stylistically, declarations in VB are generally at the top of the procedure. This is because VB scoping rules are done per procedure, and ignores all blocks in the code.
VB6 doesn't really have static objects, per se, although you can fake it with "global" objects, which automatically instantiate a public (i.e. from an external component) multi-use class the first time you try to bind to it.
The VB6 message box command is simply MsgBox(). Convert.ToString is simply CStr(), although VB tends to automatically convert to string when it is required without you having to do any work.
In any case, the line::
txt = Convert.ToString(SendMessage(window_hwnd, WM_GETTEXT, txtlen, txt))
... is wrong on more than the conversion. The SendMessage() API call returns a Long value, not a string. In this case txt
is the string buffer.
In my version, I have greatly simplified this by using the Unicode version of SendMessage(). This means that I can simply preload the return value WindowText
with null chars, and use this directly with the API call. StrPtr() returns a pointer to the Unicode buffer relating to the VB string. The API understands this, and uses this buffer with no problem. I just have to add one to the length when calling SendMessage() so that it takes into account that VB6 strings are automatically null-terminated.
Private Const WM_GETTEXT As Long = &HD
Private Const WM_GETTEXTLENGTH As Long = &HE
Private Declare Function FindWindow Lib "USER32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String _
) As Long
Private Declare Function FindWindowEx Lib "USER32" Alias "FindWindowExA" ( _
ByVal hWndParent As Long, _
ByVal hWndChildAfter As Long, _
ByVal lpszClassName As String, _
ByVal lpszWindowName As String _
) As Long
Private Declare Function SendMessage Lib "USER32" Alias "SendMessageW" ( _
ByVal hWnd As Long, ByVal Msg As Long, ByRef wParam As Any, ByRef lParam As Any _
) As Long
Private Sub Command1_Click()
Dim notepadHandle As Long
Dim childhandle As Long
notepadHandle = FindWindow("Notepad", vbNullString)
childhandle = FindWindowEx(notepadHandle, 0, "Edit", vbNullString)
If notepadHandle = 0 Then
MessageBox.Show "can't find"
Else
MsgBox WindowText(childhandle)
End If
End Sub
Public Function WindowText(ByVal window_hwnd As Long) As String
Dim txtlen As Long
If window_hwnd = 0 Then
Exit Function
End If
txtlen = SendMessage(window_hwnd, WM_GETTEXTLENGTH, ByVal 0, ByVal 0)
If txtlen = 0 Then
Exit Function
End If
WindowText = String$(txtlen, vbNullChar)
SendMessage window_hwnd, WM_GETTEXT, ByVal (txtlen + 1), ByVal StrPtr(WindowText)
End Function
Upvotes: 2
Reputation: 503
Thereis no object in your code. However msgbox is just msgbox not msgbox.show. This tricks VB into thinking it's an object rather than a function (being used as a sub).
Also as it's a sub there are no brackets. Only things that return values require brackets. Of all the basics only vb.net has brackets for subs.
Upvotes: 2