tags:

views:

112

answers:

3

I am calling GetGlyphIndices from Vb.Net. I am using a single character string. I get the correct value in the indices array for the character '6' but not for characters requiring 2 bytes to be returned.

Does anyone have any experience with this API call? My next step is to write the C equivalent and make sure I can get it working without interop.

My pinvoke declaration is:

<DllImport("gdi32.dll", EntryPoint:="GetGlyphIndicesW")> _
Private Shared Function GetGlyphIndices(ByVal hDC As IntPtr, 
                                        ByVal Text As String, 
                                        ByVal Count As Int32, 
     <MarshalAs(UnmanagedType.LPArray)> ByVal Indices() As UInt16, 
                                        ByVal Mode As Int32) As Int32

End Function

I have tried variations on this to no avail.

A: 

Could you try this ?

<DllImportAttribute("gdi32.dll", EntryPoint:="GetGlyphIndicesW")> _
Public Shared Function GetGlyphIndicesW( _
    <InAttribute()> ByVal hdc As System.IntPtr, _
    <InAttribute(), MarshalAsAttribute(UnmanagedType.LPTStr)> ByVal lpstr As String, _
    ByVal c As Integer, _
    <OutAttribute()> ByRef pgi As UShort, _
    ByVal fl As UInteger) As UInteger
DevByDefault
Bit late at night here but a quick test confirms this is returning correct result. Thank you very much!I guess the question is why the original is incorrect. The purpose of this call is to look up glyph index for use in creating a PDF. Looks as though it may be a slow process if I cannot get multi-character version working!
A: 

Further tests show that

_ Private Shared Function GetGlyphIndices(ByVal hdc As System.IntPtr, _ ByVal lpstr As String, _ ByVal c As UInteger, _ ByVal Indices() As UInt16, ByVal Mode As UInteger) As UInteger

End Function

Works to return array of glyph indices for a string. The key attribute to getting this working is MarshalAsAttribute(UnmanagedType.LPTStr on the string. My own stupidity in thinking that strings were marshalled automatically (throwback to VB6?).

Note that GetGlyphIndices only works with Unicode returning 1-2 bytes. Fortunately Chinese/Japanese can be handled using built-in CMAP in PDF.

A: 

The original declaration was incorrect because you explicitly targeted the Unicode version of the API by setting EntryPoint="GetGlyphIndicesW", while not specifying a character encoding and therefore using the default which is ANSI. So you get a Unicode/ANSI mismatch.

The easiest way to fix the problem would be to change your DllImport attribute to

<DllImport("gdi32.dll", CharSet:=CharSet.Auto)> _
Mattias S