Prev: APPDATA folder question
Next: Alternatives
From: C Kevin Provance on 23 Dec 2008 20:53 Okay, you really need to ignore McCarthy. He has no clue what he is talking about and deliberately misleading you with .NET code when what you need is real VB 6 code. You only need to subclass a control if you want to detect changes in the text...and if you are doing is cross process, you cannot subclass using standard VB code, .NET or otherwise. He thinks he is some kind of professional, but he isn't. Here is the best way to onbtain text from another program, using REAL VB Classic code, Simply pass the handle of the window/control you want to retrieve the text from to this function. Public Function GetAPIText(hwnd As Long) As String Dim GTL As Long Dim Buffer As String Const WM_GETTEXT As Long = &HD Const WM_GETTEXTLENGTH As Long = &HE GTL = SendMessageByNum(hwnd, WM_GETTEXTLENGTH, 0, 0) Buffer = String$(GTL, 0) SendMessageByString hwnd, WM_GETTEXT, GTL + 1, Buffer GetAPIText = Buffer Exit Function "Steve" <sredmyer(a)rfcorp.com> wrote in message news:4d49cbf5-f563-4d26-acc3-910ad56d4776(a)r37g2000prr.googlegroups.com... On Dec 23, 7:39 pm, "Bill McCarthy" <B...(a)localhost.com> wrote: > Hi Steve, > > "Steve" <sredm...(a)rfcorp.com> wrote in message > > news:af6f1a1e-619f-4378-b9bb-e959d1977ee6(a)o4g2000pra.googlegroups.com > > > On Dec 23, 7:19 pm, "mayayana" <mayaXXy...(a)rcXXn.com> wrote: > >>> Does anyone know how this ispossible? > > >> You might check the class name given in Spy++. > >> Maybe it's notr really a textbox. That's not unusual. > >> At one point someone was looking to read the URL > >> in the Firefox address bar and it turned out that none > >> of that was actually a window. It was all painted. > > > As I said in my origianl post. I did just that and Spy++ says the > > class is "Edit" hence my confusion. > > I just did a quick test. Excuse the .Net code, but it shows the concept > easiest: > > Class TextBoxEx : Inherits TextBox > > Private Const WM_GETTEXT As Int32 = &HD > > Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) > If m.Msg <> WM_GETTEXT Then > MyBase.WndProc(m) > End If > End Sub > > End Class > > That's basically subclassing a textbox, and swallowing any WM_GETTEXT > requests. The textbox works fine, but Spy can't read the text. Further, is there any way to get around this to retreive the text in the control? Thanks, Steve
From: Steve on 23 Dec 2008 21:22 On Dec 23, 8:53 pm, "C Kevin Provance" <bm_paws(a)my_balls.com> wrote: > Okay, you really need to ignore McCarthy. He has no clue what he is talking > about and deliberately misleading you with .NET code when what you need is > real VB 6 code. You only need to subclass a control if you want to detect > changes in the text...and if you are doing is cross process, you cannot > subclass using standard VB code, .NET or otherwise. He thinks he is some > kind of professional, but he isn't. > > Here is the best way to onbtain text from another program, using REAL VB > Classic code, Simply pass the handle of the window/control you want to > retrieve the text from to this function. > > Public Function GetAPIText(hwnd As Long) As String > > Dim GTL As Long > Dim Buffer As String > > Const WM_GETTEXT As Long = &HD > Const WM_GETTEXTLENGTH As Long = &HE > > GTL = SendMessageByNum(hwnd, WM_GETTEXTLENGTH, 0, 0) > Buffer = String$(GTL, 0) > SendMessageByString hwnd, WM_GETTEXT, GTL + 1, Buffer > GetAPIText = Buffer > > Exit Function > Yep that worked. So is it normal practice to hide user entered UI information in this way. Did the developer likely do this on purpose or is it more likely he just neglected to handle the WM_GETTEXT message in his windowproc? I realize that nobody here can read the mind of some unknown developer I am just wondering outloud. Thanks, Steve
From: Bill McCarthy on 23 Dec 2008 21:43 Hi Steve, "Steve" <sredmyer(a)rfcorp.com> wrote in message news:30cc276e-3d27-46f8-a3e0-347a1084fa7c(a)s1g2000prg.googlegroups.com >> >> Public Function GetAPIText(hwnd As Long) As String >> >> Dim GTL As Long >> Dim Buffer As String >> >> Const WM_GETTEXT As Long = &HD >> Const WM_GETTEXTLENGTH As Long = &HE >> >> GTL = SendMessageByNum(hwnd, WM_GETTEXTLENGTH, 0, 0) >> Buffer = String$(GTL, 0) >> SendMessageByString hwnd, WM_GETTEXT, GTL + 1, Buffer >> GetAPIText = Buffer >> >> Exit Function >> > > Yep that worked. > If that code worked then the control is not ignoring WM_GETTEXT. If you tried that code on the TextBox example I showed it would NOT work. Oh also note that the above code is dangerous as it says the buffer allocated is larger than it is. Vb6 strings do not have a null terminator so the length of the string must include that. The buffer in this case should be one char larger as WM_GETTEXTLENGTH does not include hte null character but WM_GETTEXT does. To make that code safe, change it to: GTL = SendMessageByNum(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1 Buffer = String$(GTL, 0) SendMessageByString hwnd, WM_GETTEXT, GTL, Buffer > So is it normal practice to hide user entered UI information in this > way. Did the developer likely do this on purpose or is it more likely > he just neglected to handle the WM_GETTEXT message in his windowproc? > I realize that nobody here can read the mind of some unknown developer > I am just wondering outloud. > Hard to say without knowing the specific control. As has been demonstrated there's vast array of possibilities
From: Steve on 23 Dec 2008 21:59 > If that code worked then the control is not ignoring WM_GETTEXT. > If you tried that code on the TextBox example I showed it would NOT work. > Well duh...it obviously is using WM_GETTEXT. I guess I should have looked more closely at the code to see what it was. I just pasted in to a project and tried it real quickly to see if it would work. Wonder why my previous attempts using Sendmessage and WM_GETTEXT failed. Also I am still curious why Spy++ does not return the edit controls contents. Anybody got any ideas there. Since the code posted by Kevin does indeed return the text and it is using WM_GETTEXT (which is what I presume Spy++ does). Oh well I have my solution. Thanks to all for your help. Steve
From: expvb on 24 Dec 2008 14:19
"Bill McCarthy" <Bill(a)localhost.com> wrote in message news:O%23g6wFXZJHA.5676(a)TK2MSFTNGP03.phx.gbl... > Vb6 strings do not have a null terminator so the length of the string must > include that. That's not correct. VB6 strings have 32 bit unsigned length(byte count, not char count), followed by the Unicode string, followed by a null terminator(2 bytes). This is explained with graphic illustration in MSDN Library - October 2001. Search for "bstr strptr", the topic title is "Chapter 6: Strings". Built-in VB6 String functions use the length field, so you can have nulls in the middle of the string, but the actual string in memory has one extra character that is the null character. > should be one char larger as WM_GETTEXTLENGTH does not include hte null > character but WM_GETTEXT does. To make that code safe, change it to: > > GTL = SendMessageByNum(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1 > Buffer = String$(GTL, 0) > SendMessageByString hwnd, WM_GETTEXT, GTL, Buffer This code will allocate one extra character to Buffer, so the string will have two null chars at the end, so it's necessary in this case to use a NullTrim() function to remove the extra null. |