Windows Vista Vista and DrawText API

  • Thread starter Thread starter David DB
  • Start date Start date
D

David DB

Guest
Hi,

I have discovered a problem with Vista and the DrawText API.

Code (VB6):

Private Declare Function DrawText Lib "user32" Alias "DrawTextA" _
(ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, _
lpRect As RECT, ByVal wFormat As Long) As Long

Private Declare Function SetTextCharacterExtra Lib "gdi32" _
(ByVal hdc As Long, ByVal nCharExtra As Long) As Long

tR.Top = 1
tR.Left = 1
tR.Right = objPic.ScaleWidth \ Screen.TwipsPerPixelX
tR.Bottom = objPic.ScaleHeight \ Screen.TwipsPerPixelY

SetTextCharacterExtra lhDC, iCharSpacing

DrawText lhDC, sText, Len(sText), tR, DT_CENTER or DT_SINGLELINE

lhdc is the HDC of the picturebox
iCharSpacing the the characterspacing
sText is the text to be displayed

On XP this works great. With the text being displayed centered

On Vista it almost centers, but shifts many pixels to the right. This makes
long texts go off the screen to the right. This only happens when having a
character spacing bigger that 0. To me it sems that the center offset has
something to do with the character spacing. Without character spacing it is
centered correctly. The same thing happens when using DrawText with
DT_CALCRECT to calculate the with of the string. I can go around this by
adding the character spacing value for each char in the string to get the
correct result.

Anyone ?

And as I stated it works perfectly on versions up to Vista.
 
Re: Vista and DrawText API

Do you have Aero running? Just for kicks, try changing your Vista theme to
basic, without all the flashy Aero stuff and see if the results are the
same. I've noticed some oddities with the GDI based API with Aero running,
and there may well be another incompatibility.

Thanks.

- Kev

"David DB" <er_fortsatt@hotmail.com> wrote in message
news:%2353NwAF4HHA.1484@TK2MSFTNGP06.phx.gbl...
| Hi,
|
| I have discovered a problem with Vista and the DrawText API.
|
| Code (VB6):
|
| Private Declare Function DrawText Lib "user32" Alias "DrawTextA" _
| (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, _
| lpRect As RECT, ByVal wFormat As Long) As Long
|
| Private Declare Function SetTextCharacterExtra Lib "gdi32" _
| (ByVal hdc As Long, ByVal nCharExtra As Long) As Long
|
| tR.Top = 1
| tR.Left = 1
| tR.Right = objPic.ScaleWidth \ Screen.TwipsPerPixelX
| tR.Bottom = objPic.ScaleHeight \ Screen.TwipsPerPixelY
|
| SetTextCharacterExtra lhDC, iCharSpacing
|
| DrawText lhDC, sText, Len(sText), tR, DT_CENTER or DT_SINGLELINE
|
| lhdc is the HDC of the picturebox
| iCharSpacing the the characterspacing
| sText is the text to be displayed
|
| On XP this works great. With the text being displayed centered
|
| On Vista it almost centers, but shifts many pixels to the right. This
makes
| long texts go off the screen to the right. This only happens when having a
| character spacing bigger that 0. To me it sems that the center offset has
| something to do with the character spacing. Without character spacing it
is
| centered correctly. The same thing happens when using DrawText with
| DT_CALCRECT to calculate the with of the string. I can go around this by
| adding the character spacing value for each char in the string to get the
| correct result.
|
| Anyone ?
|
| And as I stated it works perfectly on versions up to Vista.
|
|
 
Re: Vista and DrawText API

"Kevin Provance" <casey@tpasoft.com> wrote ...

> Do you have Aero running? Just for kicks, try changing your Vista theme
> to
> basic, without all the flashy Aero stuff and see if the results are the
> same. I've noticed some oddities with the GDI based API with Aero
> running,
> and there may well be another incompatibility.



Hi Dave and Kevin,

I suspect Kev is right.

My first reaction to David's post was "he's gotta be smoking crack!" :-) But
I tried a quick repro, using plain C code (to avoid any VB weirdness) and I
got the same result! The string of centred text was skewed towards the right
margin of the window. This only occurs when I add SetTextCharacterExtra()
with a parameter > 0 ... DrawText() on its own, appears to work okay, as
does SetTextCharacterExtra(hdc, 0);

It worked correctly on an XP machine - the text was centrred in the window.

However, after I tried turning off Aero by using a Windows Basic theme, I
still saw the distortion in the centred text. It looks like even if Aero is
not active, there is some kind of distortion going on. There appear to be
several such issues floating around, in developer forums.

It's not a big problem for C code because you have much more fine-grained
control over the appearance, using DRAWTEXTPARAMS and the like. I'm pretty
sure a call to ExtTextOut would work instead. But I'm not sure how one might
do that from VB. You could report the issue to Microsoft; but I have to say,
I think fixing it will be a very low priority for them. DrawText is largely
superceded in C/C++ code by more Unicode-friedly functions; and
SetTextCharacterExtra() is already officially deprected for XP - see
http://support.microsoft.com/kb/305320

If I get any extra insights I'll report them back here.
--
Andrew McLaren
amclar (at) optusnet dot com dot au
 
Re: Vista and DrawText API

"Andrew McLaren" <andrew@fakeaddress.com> wrote in message
news:%23e8O%23nJ4HHA.4476@TK2MSFTNGP06.phx.gbl...

> It's not a big problem for C code because you have much
> more fine-grained control over the appearance, using
> DRAWTEXTPARAMS and the like.


Actually I've just tried DrawtextEx and it has exactly the same problem as
the DrawText API. The DRAWTEXTPARAMS do allow you to specify things like
left and right margin and tab spacing and return the number of draw
characters for you, but they don't help to solve the problem. I've also
tried the simpler Texout as well and that too does not work properly in
Vista (All when using extra characters spacing of course, they're all fine
when the spacing is the normal zero). The problem exists even with all the
Aero stuff turned off. In fact the positioning of the text is always exactly
where it would have been had no extra spacing been set, indicating that
these routines are reading the overall text extent without taking into
account the extra spacing, but are actually drawing the text taking it into
account. I haven't had time to try other things yet (ExtTextOut for example)
but I think it will probably also have the same problem. I suspect there may
also be similar problems with GetTextExtents, although I haven't had time to
try those with extra characters spacing in Vista yet. There will of course
be ways of overcoming the problem, but that doesn't help with code that is
already out there and I hope that Microsoft fix this bug soon.

Mike
 
Re: Vista and DrawText API

"Mike Williams" <mikea@whiskyandCoke.com> wrote ...
> account. I haven't had time to try other things yet (ExtTextOut for
> example) but I think it will probably also have the same problem. I
> suspect there may also be similar problems with GetTextExtents, although I
> haven't had time to try those with extra characters spacing in Vista yet.
> There will of course be ways of overcoming the problem, but that doesn't
> help with code that is already out there and I hope that Microsoft fix
> this bug soon.


Yeah, I agree with that ... if the problem really is pervasive across
several different APIs, then a fix is probably warranted.

Cheers,
--
Andrew McLaren
amclar (at) optusnet dot com dot au
 
Re: Vista and DrawText API

Hi,

Good that I have not been smoking some crack :-)

As some of you have mentioned with further testing, VB versus C++ is not an
issue and the other API's have the same flaws.

If someone has a API that works it would be appreciated.

I came up with genious quick and dirty solution that takes into account the
right shift on Vista. This will work until they fix it, and then I will make
a proper vesion. I shift the left coordinate out to the left to cater for
the right shift:

tR.Top = 1
tR.Left = 1
tR.Right = objPic.ScaleWidth \ Screen.TwipsPerPixelX
tR.Bottom = objPic.ScaleHeight \ Screen.TwipsPerPixelY

FillRect lhDC, tR, hBrush

SetTextCharacterExtra lhDC, iCharSpacing

If lWinMajorVer = 6 Then
' Special handling for Vista because of DrawText/SetTextCharExtra
bug

tR.Left = -((Len(sText) * iCharSpacing) * 1)
End If

DrawText lhDC, sText, Len(sText), tR, lFlags


Does anyone know how to contact Microsoft to report this bug ?

David

"Andrew McLaren" <andrew@fakeaddress.com> wrote in message
news:OhiEedN4HHA.1188@TK2MSFTNGP04.phx.gbl...
> "Mike Williams" <mikea@whiskyandCoke.com> wrote ...
>> account. I haven't had time to try other things yet (ExtTextOut for
>> example) but I think it will probably also have the same problem. I
>> suspect there may also be similar problems with GetTextExtents, although
>> I haven't had time to try those with extra characters spacing in Vista
>> yet. There will of course be ways of overcoming the problem, but that
>> doesn't help with code that is already out there and I hope that
>> Microsoft fix this bug soon.

>
> Yeah, I agree with that ... if the problem really is pervasive across
> several different APIs, then a fix is probably warranted.
>
> Cheers,
> --
> Andrew McLaren
> amclar (at) optusnet dot com dot au
>
 
Re: Vista and DrawText API

"David DB" <er_fortsatt@hotmail.com> wrote in message
news:uts5%23Py4HHA.5852@TK2MSFTNGP02.phx.gbl...

> I came up with genious quick and dirty solution that takes into
> account the right shift on Vista. This will work until they fix it,
> and then I will make a proper vesion. I shift the left coordinate
> out to the left to cater for the right shift:
> If lWinMajorVer = 6 Then
> ' Special handling for Vista DrawText/SetTextCharExtra bug
> tR.Left = -((Len(sText) * iCharSpacing) * 1)
> End If


Actually, just to be pedantic, I think that would be Len(sText)-1. But I
really wouldn't advise doing it that way anyway, because when (if!)
Microsoft do fix that Vista bug then you'd need to change the code again to
remove the temporary coding fix. Your current requirement seems to involve
drawing centred lines of of text individually (drawing the lines
individually is a very useful technique anyway, even for blocks of text,
because it allows you to more easily perform things like full
justification), so my advice would be to draw them always using DT_LEFT and
set the x coordinate according to the justification you require, taking into
account the width of the drawing rectangle and the width of the line of
text, which is accurately returned by the GetTextExtentPoint32 API in all
cases, even in Vista when you have set TextCharacterExtra to something other
than zero. In that way the exact same code will work in XP and in Vista
(with the bug) and also in Vista after the bug is fixed.

Mike
 
Back
Top