From: Bill McCarthy on

"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 :)


















First  |  Prev  | 
Pages: 1 2 3 4
Prev: APPDATA folder question
Next: Alternatives