Prev: APPDATA folder question
Next: Alternatives
From: Bill McCarthy on 28 Dec 2008 21:24 "expvb" <nobody(a)cox.net> wrote in message news:%23UThSyfZJHA.5440(a)TK2MSFTNGP02.phx.gbl... > "Bill McCarthy" <Bill(a)localhost.com> wrote in message > news:O%23g6wFXZJHA.5676(a)TK2MSFTNGP03.phx.gbl... > > 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. > Well you are right as far as VB6's strings go when they are *NOT* used for win API calls, but as this example was with win API, then the strings are in fact ascii, not unicode. To use VB's OLE BSTR's, because BSTR's are dereferenced, you would have to use StrPtr calls with API. If you don't use StrPtr then the string is declared as "ByVal" and VB6 allocates a block of memory, does a Unicode to Ansi conversion on the string, then passes that out then does a ansi to unicode conversion on the way back in. If you aren't passing any value out, it's probably more efficient to use a Byte array > > 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. > Kevin's implementation was full of pitfalls. First there is the potential for latency between the call to WM_GETTEXTLENGTH and WM_GETTEXT. Also there is the fact that WM_GETTEXTLENGTH only returns an **approximation**, not the actual length. From the documentation: <quote> When the WM_GETTEXTLENGTH message is sent, the DefWindowProc function returns the length, in characters, of the text. Under certain conditions, the DefWindowProc function returns a value that is larger than the actual length of the text. This occurs with certain mixtures of ANSI and Unicode, and is due to the system allowing for the possible existence of double-byte character set (DBCS) characters within the text. The return value, however, will always be at least as large as the actual length of the text; you can thus always use it to guide buffer allocation. This behavior can occur when an application uses both ANSI functions and common dialogs, which use Unicode. </quote> So what you should do is allocate a buffer at least the size as returned by WM_GETTEXTLENGTH, pass that buffer out to WM_GETTEXT and check the return value from the WM_GETTEXT SendMessage call, and trim to that length. In fact the only way you can tell you got the complete text is if the returned value is less than the size of your buffer. You don't however call a NullTrim or TrimNull function, you use the return value from SendMessage. HTH's :) |