Home All Groups Group Topic Archive Search About

How to cast a ref to one type to another?

Author
24 Mar 2006 6:40 PM
Gary
I am using GetFontUnicodeRanges() function in VB. This function needs to get
the size of a structure first, then allocate memory for this structure, and
call that function again to get needed information. Following is the
equivalent in C++
-------------------------------------------------------------------------
GLYPHSET *gs;
DWORD GlyphSize = GetFontUnicodeRanges(dc, NULL);
gs = (GLYPHSET *)new unsigned char[ GlyphSize ];

GetFontUnicodeRanges(dc, gs);
--------------------------------------------------------------------------

Following is my declaration for this function and the code to use it
--------------------------------------------------------------------------
Public Type WCRANGE
        wcLow As Integer
        cGlyphs As Integer
End Type

Public Type GLYPHSET
        cbThis As Integer
        flAccel As Integer
        cGlyphsSupported As Integer
        cRanges As Integer
        ranges() As WCRANGE
End Type

Public Declare Function GetFontUnicodeRanges Lib _
"gdi32.dll" (ByVal hdc As Long, ByRef LPGLYPHSET As GLYPHSET) As Long

        Dim intCnt As Integer

        Dim glyind As GLYPHSET

        intCnt = GetFontUnicodeRanges(hdc, glyind)

        Dim glyind1() As Byte

        ReDim glyind1(1 To intCnt)

        'error
        'Set glyind = glyind1
        'error in compile time
        intCnt = GetFontUnicodeRanges(hdc, glyind)
--------------------------------------------------------------------------------
In this case, is it possible to use this API function?

I am relatively new to VBA. Please help me in this issue.

Author
24 Mar 2006 7:14 PM
Veign
You have multiposted this question across several newsgroups and threads.
Keep the questions in the same thread since it seems to be inline with the
original post.  You would be far better off to stay with the original thread
and poster that has started to help you already.

--
Chris Hanscom - Microsoft MVP (VB)
Veign's Resource Center
http://www.veign.com/vrc_main.asp
Veign's Blog
http://www.veign.com/blog
--


Show quoteHide quote
"Gary" <G***@discussions.microsoft.com> wrote in message
news:A7B573E7-5253-453D-9B54-894DAA3FA7CE@microsoft.com...
>I am using GetFontUnicodeRanges() function in VB. This function needs to
>get
> the size of a structure first, then allocate memory for this structure,
> and
> call that function again to get needed information. Following is the
> equivalent in C++
> -------------------------------------------------------------------------
> GLYPHSET *gs;
> DWORD GlyphSize = GetFontUnicodeRanges(dc, NULL);
> gs = (GLYPHSET *)new unsigned char[ GlyphSize ];
>
> GetFontUnicodeRanges(dc, gs);
> --------------------------------------------------------------------------
>
> Following is my declaration for this function and the code to use it
> --------------------------------------------------------------------------
> Public Type WCRANGE
>        wcLow As Integer
>        cGlyphs As Integer
> End Type
>
> Public Type GLYPHSET
>        cbThis As Integer
>        flAccel As Integer
>        cGlyphsSupported As Integer
>        cRanges As Integer
>        ranges() As WCRANGE
> End Type
>
> Public Declare Function GetFontUnicodeRanges Lib _
> "gdi32.dll" (ByVal hdc As Long, ByRef LPGLYPHSET As GLYPHSET) As Long
>
>        Dim intCnt As Integer
>
>        Dim glyind As GLYPHSET
>
>        intCnt = GetFontUnicodeRanges(hdc, glyind)
>
>        Dim glyind1() As Byte
>
>        ReDim glyind1(1 To intCnt)
>
>        'error
>        'Set glyind = glyind1
>        'error in compile time
>        intCnt = GetFontUnicodeRanges(hdc, glyind)
>
> --------------------------------------------------------------------------------
> In this case, is it possible to use this API function?
>
> I am relatively new to VBA. Please help me in this issue.
>
Author
24 Mar 2006 11:28 PM
Mike D Sutton
> I am using GetFontUnicodeRanges() function in VB. This function needs to
get
> the size of a structure first, then allocate memory for this structure,
and
> call that function again to get needed information. Following is the
> equivalent in C++

Since the GlyphSet structure uses a dynamic array as part of the structure
and VB's arrays are SAFEARRAY prefixed in memory, you have to wrap this call
to use it in the same way from VB.  The following code pulls the buffer back
into a large byte array, then steps through that array in chunks pulling off
GlyphSet structures with the appropriate ranges set:

'***
Private Declare Function GetFontUnicodeRanges Lib "GDI32.dll" ( _
    ByVal hDC As Long, ByRef lpgs As Any) As Long
Private Declare Sub RtlMoveMemory Lib "Kernel32.dll" ( _
    ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Private Type WCRange
    wcLow As Integer
    cGlyphs As Integer
End Type

Private Type GlyphSet
    cbThis As Long
    flAccel As Long
    cGlyphsSupported As Long
    cRanges As Long
    ranges() As WCRange
End Type

Private Const GS_8BIT_INDICES As Long = &H1

Private Sub Form_Load()
    Dim RangeBuf() As Byte, BufLen As Long
    Dim CurPos As Long
    Dim LoopRanges As Long

    ' Call the function once to get the required buffer size
    BufLen = GetFontUnicodeRanges(Me.hDC, ByVal 0&)

    If (BufLen > 0) Then
        ' Allocate buffer and call again to fill it
        ReDim RangeBuf(0 To BufLen - 1) As Byte
        Call GetFontUnicodeRanges(Me.hDC, RangeBuf(0))

        Do ' Iterate through return buffer extracting glyph sets
            With ExtractGlyphsetFromBuffer(RangeBuf, CurPos)
                Debug.Print "cbThis: " & CStr(.cbThis)
                Debug.Print "flAccel: " & CStr(.flAccel) ' GS_8BIT_INDICES
                Debug.Print "cGlyphsSupported: " & CStr(.cGlyphsSupported)
                Debug.Print "cRanges: " & CStr(.cRanges)

                For LoopRanges = 0 To .cRanges - 1
                    Debug.Print "Range " & CStr(LoopRanges + 1) & ":"

                    With .ranges(LoopRanges)
                        Debug.Print vbTab & "wcLow : " & CStr(.wcLow)
                        Debug.Print vbTab & "cGlyphs: " & CStr(.cGlyphs)
                    End With
                Next LoopRanges
            End With
        Loop While CurPos < BufLen
    End If
End Sub

Private Function ExtractGlyphsetFromBuffer( _
    ByRef inBuffer() As Byte, ByRef Offset As Long) As GlyphSet
    Dim RetStruct As GlyphSet
    Dim RangeSize As Long

    ' Size of the fixed part of the structure
    Const SizeOfGlyphSet As Long = 16

    With RetStruct ' Copy header into structure
        Call RtlMoveMemory(.cbThis, inBuffer(Offset), SizeOfGlyphSet)

        If (.cRanges > 0) Then ' Copy ranges into structure
            ReDim .ranges(0 To .cRanges - 1) As WCRange
            RangeSize = .cRanges * Len(.ranges(0))

            Call RtlMoveMemory(.ranges(0).wcLow, _
                inBuffer(Offset + SizeOfGlyphSet), RangeSize)
        End If

        ' Append offset based on size of this structure
        Offset = Offset + SizeOfGlyphSet + RangeSize
    End With

    ' Return final structure
    ExtractGlyphsetFromBuffer = RetStruct
End Function
'***

Hope this helps,

    Mike


- Microsoft Visual Basic MVP -
E-Mail: ED***@mvps.org
WWW: Http://EDais.mvps.org/