get the OTMEMsquare for the selected font. This requires calling
GetOutlineTextMetrics. However, you have to call GetOutlineTextMetrics
twice really, once for the size of the structure, and the second time to
fill it.
However, the second call crashes VB. There must be some trick.
Below is the code that should work...but you get a big VB crash on the
second call to GetoutlineTextMetric.
PS...a valid otmemsquare value will typically be 2000, or some large number,
not -21 or something, as is returned if the return code of
GetOutlineTextMetric is 0 (which indicates an error occurred).
You'll be a VB super hero if you can retrieve the proper otmemSQuare result
for the selected font!!!!!!
Eric Robishaw
Here's the sample code:
Public Type POINTAPI '4 Bytes - Synonymous with LONG
x As Long
y As Long
Col As Long
End Type
Public Type TEXTMETRIC
tmHeight As Long
tmAscent As Long
tmDescent As Long
tmInternalLeading As Long
tmExternalLeading As Long
tmAveCharWidth As Long
tmMaxCharWidth As Long
tmWeight As Long
tmOverhang As Long
tmDigitizedAspectX As Long
tmDigitizedAspectY As Long
tmFirstChar As Byte
tmLastChar As Byte
tmDefaultChar As Byte
tmBreakChar As Byte
tmItalic As Byte
tmUnderlined As Byte
tmStruckOut As Byte
tmPitchAndFamily As Byte
tmCharSet As Byte
End Type
Public Type PANOSE
ulculture As Long
bFamilyType As Byte
bSerifStyle As Byte
bWeight As Byte
bProportion As Byte
bContrast As Byte
bStrokeVariation As Byte
bArmStyle As Byte
bLetterform As Byte
bMidline As Byte
bXHeight As Byte
End Type
Public Type OUTLINETEXTMETRIC
otmSize As Long
otmTextMetrics As TEXTMETRIC
otmFiller As Byte
otmPanoseNumber As PANOSE
otmfsSelection As Long
otmfsType As Long
otmsCharSlopeRise As Long
otmsCharSlopeRun As Long
otmItalicAngle As Long
otmEMSquare As Long
otmAscent As Long
otmDescent As Long
otmLineGap As Long
otmsCapEmHeight As Long
otmsXHeight As Long
otmrcFontBox As RECT
otmMacAscent As Long
otmMacDescent As Long
otmMacLineGap As Long
otmusMinimumPPEM As Long
otmptSubscriptSize As POINTAPI
otmptSubscriptOffset As POINTAPI
otmptSuperscriptSize As POINTAPI
otmptSuperscriptOffset As POINTAPI
otmsStrikeoutSize As Long
otmsStrikeoutPosition As Long
otmsUnderscorePosition As Long
otmsUnderscoreSize As Long
otmpFamilyName As String
otmpFaceName As String
otmpStyleName As String
otmpFullName As String
End Type
Public Declare Function GetOutlineTextMetrics_1 Lib "gdi32" _
Alias "GetOutlineTextMetricsA" _
(ByVal hdc As Long, ByVal cbData As Long, ByVal lpotm As Long) As Long
Public Declare Function GetOutlineTextMetrics Lib "gdi32" Alias
"GetOutlineTextMetricsA" (ByVal hdc As Long, ByVal cbData As Long, lpotm As
Any) As Long
Private function get OtmemSq (hdc) as long
dim size as long, otm as outlinetextmetric
size=GetOutlineTextMetric_1(hdc,0,0)
otm.otmsize = size
getoutlinetextmetric (hdc, size, otm) 'this will crash vb
'and getoutlinetextmetric (hdc, lenb(otm), otm) returns a 0, and a
bogus value in the otmemsqure
otmEmsq = otm.otmemsquare
end function
This way, the same API function can deal with mutiliple verions of the
parameterized type.
Try this....
Private function get OtmemSq (hdc) as long
dim size as long, otm as outlinetextmetric
size=GetOutlineTextMetric_1(hdc,0,0)
' otm.otmsize = size
otm.otmsize = len(otm)
getoutlinetextmetric (hdc, size, otm) 'this will crash vb
'and getoutlinetextmetric (hdc, lenb(otm), otm) returns a 0, and a
'bogus value in the otmemsqure
otmEmsq = otm.otmemsquare
end function
"Flash" <ERob...@bigfoot.com> wrote in message
news:udWTZzt6AHA.1756@tkmsftngp07...
Granted most are sloppy hacks, but the again, the winapi IS a sloppy hack in
and of itself.
-Tom
(please post replies to the newsgroup)
2) Your POINTAPI declare has an extra member in it somehow. Should be
just:
Public Type POINTAPI
X As Long
Y As Long
End Type
3) Both TEXTMETRIC and PANOSE structs break dword alignment, which is
a ~big~ problem with VB and pretty much altogether hoses being able to
use an OUTLINETEXTMETRIC struct in the call. Essentially you have to
obtain the size, use it to allocate a byte array, and pass a pointer
to the byte array. Then of course, ferret out the pieces you need.
(FWIW whenever I get into one of these situations where things are all
whored up because some lame-ass MS coder broke the dword rule, I find
it's sometimes helpful to dump the byte array to a file and look at it
with a hex viewer.)
4) Also in case you intend to use them, the last 4 members of the
OUTLINETEXTMETRIC struct aren't really strings, but rather ~byte
offsets~ (As Longs) to the actual null-terminated string data, which
gets tacked on to the end of the data block.
Public Declare Function GetOutlineTextMetricsAny Lib "gdi32" Alias
"GetOutlineTextMetricsA" (ByVal hdc As Long, ByVal cbData As Long,
lpOTM As Any) As Long
Public Declare Sub MemCopy Lib "kernel32" Alias "RtlMoveMemory"
(lpDest As Any, lpSource As Any, ByVal dwBytes As Long)
Public Function OtmemSq(hdc) As Long
Dim Size As Long
Dim Buf() As Byte
Size = GetOutlineTextMetricsAny(hdc, 0&, ByVal 0&)
If Size > 0& Then
ReDim Buf(0 To Size - 1)
'set the .otmSize member...
MemCopy Buf(0), Size, 4&
If GetOutlineTextMetricsAny(hdc, Size, Buf(0)) <> 0& Then
'A careful look at the structs shows .otmEMSquare will be
'at byte offset# 92...
MemCopy OtmemSq, ByVal VarPtr(Buf(92)), 4&
End If
End If
End Function
-HTH
Thanks a million!
"Tom Esh" <tjeshGi...@earthlink.net> wrote in message
news:3b1866fd...@msnews.microsoft.com...
Sould like you should find another way if that API is that poorly designed.
"Tom Esh" <tjeshGi...@earthlink.net> wrote in message
news:3b18681b...@msnews.microsoft.com...
On Mon, 4 Jun 2001 12:40:18 -0700, "schunkenstein"
<mi...@starstream.net> wrote:
>My modo is, "If the API sucks, shit-can it"
>
>Sould like you should find another way if that API is that poorly designed.
-Tom