[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.vb.general.discussion

Getting the width of an unicode word

mm

3/25/2012 10:23:00 AM

Hello, I have a MSHFlexGrid that in a column I display Greek or Hebrew
words. The MSHFlexGrid properly displays these unicode words (previously
setting the proper font), but the problem comes when I want to adjust the
width of the column according to the widest word.

For the other columns, that have normal characters (and font) I use
Textwidth in an auxiliary picturebox to measure the size, but I can't do
that with unicode words.

So, researching a bit I found that the API GetTextExtentPoint32W supposedly
does it. But I can't get it to work.

The declaration:

Private Declare Function GetTextExtentPoint32W _
Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
String, ByVal cbString As Long, lpSize As POINTAPI) As Long

The ANSI version is the same but with the "A":

Private Declare Function GetTextExtentPoint32A _
Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
String, ByVal cbString As Long, lpSize As POINTAPI) As Long

The ANSI version works fine, but the unicode version returns greater values
than the real width of the word.

Anyone knows anything about this?

Thanks in advance.


6 Answers

Jim Mack

3/25/2012 12:00:00 PM

0

> Hello, I have a MSHFlexGrid that in a column I display Greek or Hebrew
> words. The MSHFlexGrid properly displays these unicode words (previously
> setting the proper font), but the problem comes when I want to adjust the
> width of the column according to the widest word.
>
> For the other columns, that have normal characters (and font) I use
> Textwidth in an auxiliary picturebox to measure the size, but I can't do
> that with unicode words.
>
> So, researching a bit I found that the API GetTextExtentPoint32W
> supposedly does it. But I can't get it to work.
>
> The declaration:
>
> Private Declare Function GetTextExtentPoint32W _
> Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
> String, ByVal cbString As Long, lpSize As POINTAPI) As Long
>
> The ANSI version is the same but with the "A":
>
> Private Declare Function GetTextExtentPoint32A _
> Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
> String, ByVal cbString As Long, lpSize As POINTAPI) As Long
>
> The ANSI version works fine, but the unicode version returns greater
> values than the real width of the word.

You need to modify the Declare for the W version (or use a typelib).

Private Declare Function GetTextExtentPoint32W _
Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
Long, ByVal cbString As Long, lpSize As POINTAPI) As Long

Note that the second parameter is now ByVal As Long. Pass
StrPtr(Ustring) here, and pass LenB(Ustring) in the third parameter.
That should do what you want.

--
Jim


MikeD

3/25/2012 1:48:00 PM

0



"Eduardo" <mm@mm.com> wrote in message
news:jkmrlt$t76$1@speranza.aioe.org...
> So, researching a bit I found that the API GetTextExtentPoint32W
> supposedly does it. But I can't get it to work.
>
> The declaration:
>
> Private Declare Function GetTextExtentPoint32W _
> Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
> String, ByVal cbString As Long, lpSize As POINTAPI) As Long
>
> The ANSI version is the same but with the "A":
>
> Private Declare Function GetTextExtentPoint32A _
> Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
> String, ByVal cbString As Long, lpSize As POINTAPI) As Long
>
> The ANSI version works fine, but the unicode version returns greater
> values than the real width of the word.
>
> Anyone knows anything about this?
>

In the future, you should post your code showing how you're calling the
function too. In this particular case, I think Jim is probably right and
could base his answer solely on the declaration (since that's all you
provided to even go on). But it's *always* better to include both the
declaration and your call to it.

Also for future reference, for practically all unicode versions of API
functions, you need to do as Jim described.

Mike


mm

3/25/2012 2:05:00 PM

0

"Jim Mack" <no-uce-ube@mdxi.com> escribió en el mensaje
news:XKudnST84PYzlfLSnZ2dnUVZ_t6dnZ2d@giganews.com...

> You need to modify the Declare for the W version (or use a typelib).
>
> Private Declare Function GetTextExtentPoint32W _
> Lib "gdi32" (ByVal hdc As Long, ByVal lpsz As _
> Long, ByVal cbString As Long, lpSize As POINTAPI) As Long
>
> Note that the second parameter is now ByVal As Long. Pass StrPtr(Ustring)
> here, and pass LenB(Ustring) in the third parameter. That should do what
> you want.

Thanks, it works better. But the reported width is still not accurate.

I see that the problem is with the cbString parameter, that is the Length of
the string.
LenB make it worse. LenB provides the size in bytes.

If I manually set the right number of characters of the string, it works
fine.
With Len I get larger numbers for the width, and with LenB I get twice the
width that I get with Len.

I tried converting the string inside the Len and the LenB with StrConv ( ,
vbUnicode) (, vbFromUnicode) but it's the same.

I know that there are more than one way to encode Unicode, VB uses Unicode
of two bytes per character, but the "other" Unicode (I believe it's UTF-8)
can have from one to four bytes for each character, I think that I recall
(or something like that). May be the issue has something to do with it.

If that is the case (and I'm guessing) I would need a way to count the
characters of the unicode string.
I'll study this.

And thanks, I have it half solved.


mm

3/25/2012 2:20:00 PM

0


"Eduardo" <mm@mm.com> escribió en el mensaje
news:jkn8mf$t14$1@speranza.aioe.org...
> "Jim Mack" <no-uce-ube@mdxi.com> escribió en el mensaje
> news:XKudnST84PYzlfLSnZ2dnUVZ_t6dnZ2d@giganews.com...

> If I manually set the right number of characters of the string, it works

It was something more trivial, the unicode String(s) that I'm getting from a
database had a carriage return at the end, that wasn't displayed but counted
by the function.

At last, the accurate result is with Len (TheString) or LenB (TheString) / 2



Jim Mack

3/25/2012 4:11:00 PM

0

> At last, the accurate result is with Len (TheString) or LenB (TheString)
> / 2

Good. I didn't actually try it, I was going by the parameter name:
cbString would correctly be the number of bytes in the string, where
the function instead expects the number of characters.

--
Jim


mm

3/25/2012 9:41:00 PM

0


"Jim Mack" <no-uce-ube@mdxi.com> escribió en el mensaje
news:qt6dnWB3B9Tu3vLSnZ2dnUVZ_uWdnZ2d@giganews.com...
>> At last, the accurate result is with Len (TheString) or LenB (TheString)
>> / 2
>
> Good. I didn't actually try it, I was going by the parameter name:
> cbString would correctly be the number of bytes in the string, where the
> function instead expects the number of characters.

I copied the declaration from some internet page, but I see the the
parameter in the msdn is called "c":
http://msdn.microsoft.com/en-us/library/dd144938%28v=vs....

About the length of the string:
http://msdn.microsoft.com/en-us/library/dd145112%28v=vs....