What are the API-calls to get TextHeight/-Width
for a certain control and a certain stdfont
(that is not necessarily yet set to the
control)?
Any help very much appreciated
MfG,
Alex
Have a look at this old post from an example of how to turn a VB StdFont into an API hFont which can be selected into a
DC:
http://groups.google.co.uk/group/microsoft.public.vb.winapi/msg/f88223d73e805be8
Then to get the size of a string, either use the GetTextExtentPoint32() or DrawText() API calls with the DT_CALCRECT
flag.
The code would look something like this:
'*** (Air code..)
Dim hDC As Long
Dim hFont As Long, hOldFont As Long
Dim StringSize As SIZE
Dim StringArea As RECT
hDC = CreateCompatibleDC(0&)
If (hDC) Then
' Assumes your StdFont object is called "YourFont"
hFont = StdFontToAPIFont(YourFont)
If (hFont) Then
hOldFont = SelectObject(hDC, hFont)
' Assumes your string is called "YourString"
Call GetTextExtentPoint32(hDC, YourString, Len(YourString), StringSize)
Call DrawText(hDC, YourString, Len(YourString), StringArea, DT_CALCRECT)
SelectObject(hDC, hOldFont)
DeleteObject(hFont)
End If
Call DeleteDC(hDC)
End If
'***
Hope this helps,
Mike
- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://EDais.mvps.org/
First of all you need to have the handle of the actual Windows GDI font
object wrapped by the OLE (VB) font object. There is the hidden IFont
interface.
A rough sample sketch:
Dim MyFont As IFont
Set MyFont = Me.Font
hGDIFont = MyFont.hFont
After you have retrieved the GDI font handle you can use it for calls to
the respective API functions, e.g.
Dim LF As LOGFONT
Call GetObjectAPI(hGDIFont, Len(LF), LF)
This will fill the given LOGFONT structure fields with information about
the font one of which (lfHeight) holds information about the font height.
Or you may select the font (SelectObject()) into a device context (e.g. the
desktop window device context (GetDesktopWindow(), GetDC(), ReleaseDC()))
and call GetTextMetrics() or GetTextExtentPoint32().
There are lots of API calls providing information about a font.
--
----------------------------------------------------------------------
THORSTEN ALBERS Universität Freiburg
albers@
uni-freiburg.de
----------------------------------------------------------------------
Why not just do
me.Font = blah blah
DrawText(me.hdc, etc)
Michael
Because this changes the font object of the formular - and this maybe is
not always welcome.
--
Thorsten Albers
Albert-Ludwigs-Universität Freiburg
albers@
uni-freiburg.de
Generally you're just about to draw the text so it's unlikely to be a
problem. Even if it is you can put it back when it's finished.
Michael
It doesn't sound to me as if Alexander just want to draw; on the contrary,
he just wants to get some information about the font. Of course you can
restore the original OLE font object; but to do the thing with two simple
SelectObject() calls is much easier and faster. And to do it with the GDI
font handle instead of the OLE font object ensures that there is no
interaction with any existing FontChanged() event procedure.
See his other post, that's exactly what he wants to do. While I can see that
it would be possible that you'd want to measure text but not draw it I think
it would be extremely unlikely. I've done a *lot* of user painted stuff in
my time and not once had to measure text without drawing it.
> on the contrary,
> he just wants to get some information about the font. Of course you can
> restore the original OLE font object; but to do the thing with two simple
> SelectObject() calls is much easier and faster. And to do it with the GDI
> font handle instead of the OLE font object ensures that there is no
> interaction with any existing FontChanged() event procedure.
I don't see anything special about this situation that would warrant using
the API to change the font. What I mean is why not always use the API then
if it's easier? Although it didn't seem easier to me at all.
Michael
Hmm, which one?
> I don't see anything special about this situation that would warrant
using
> the API to change the font. What I mean is why not always use the API
then
> if it's easier? Although it didn't seem easier to me at all.
a)
Set OrgFont = Me.Font
Set Me.Font = ...
...
Set Me.Font = OrgFont
-> Changes the font of the form
-> Executes an existing FontChanged event procedure
-> In case generates a new GDI font, if in "Set Me.Font = ..." "..." isn't
a reference to an existing font
b)
hFontPrev = SelectObject(Me.hDC, hFont)
...
Call SelectObject(Me.hDC, hFontPrev)
-> Never changes the font object of the form
-> Never creates a new font
-> Never causes a FontChanged event procedure to be executed
What?
> a)
> Set OrgFont = Me.Font
> Set Me.Font = ...
> ...
> Set Me.Font = OrgFont
>
> -> Changes the font of the form
> -> Executes an existing FontChanged event procedure
> -> In case generates a new GDI font, if in "Set Me.Font = ..." "..." isn't
> a reference to an existing font
>
> b)
> hFontPrev = SelectObject(Me.hDC, hFont)
> ...
> Call SelectObject(Me.hDC, hFontPrev)
You excluded all the declares.
> -> Never changes the font object of the form
> -> Never creates a new font
> -> Never causes a FontChanged event procedure to be executed
Big deal, this is visual basic. If you want everything to be micro optimised
write it in C.
Michael