How to draw a chinese (Unicode)  text on a window?

Posted on 2008-11-10
Last Modified: 2012-05-05
Hi experts,

I have a VB form that calls a "C" function (implemented in a DLL) to draw the text on the VB form. The VB form sends the window hDC, text position, font name, font size and the chinese text

The "C" code appears to draw something but the content is not correct. It looks like a wrong chinese is getting displayed.

I am providing the sample code.

VB project needs a text box and form_load needs to initialize a font. After entering the text in the text box, click enter so that it calls the "C" function to draw the text

Could you please help?

C code


#include <windows.h>

#include <stdio.h>

#include <tchar.h>

HFONT m_hFont;

LOGFONT m_LogFont;

_TCHAR m_szSection[256];

_TCHAR m_szEntry[256];

void DefaultFontInit();

HFONT CreateFontLocal();




long lWindowDC,

_TCHAR *lpszFontName,

long lFontSize,

_TCHAR *lpszMultiByteText,

long X,

long Y)


long nFontHeight = 0;

long nLen = 0;

long nStatus = 0;

_tcscpy(m_szSection, _T("Settings"));

_tcscpy(m_szEntry, _T("Font"));

nFontHeight = - MulDiv (lFontSize, GetDeviceCaps (GetDC (0), LOGPIXELSY), 72);

DefaultFontInit(lpszFontName, nFontHeight);


nLen = _tcslen(lpszMultiByteText);

nStatus = TextOut(lWindowDC, X, Y, &lpszMultiByteText, nLen);

return (0);


void DefaultFontInit(_TCHAR *lpszFontName, long nFontHeight)


HFONT hFont;

// define the logical parameters for the default font

//m_LogFont.lfHeight = -11; // size 8

m_LogFont.lfHeight = nFontHeight;

m_LogFont.lfWidth = 0;

m_LogFont.lfEscapement = 0;

m_LogFont.lfOrientation = 0;

m_LogFont.lfWeight = FW_NORMAL;

m_LogFont.lfItalic = 0;

m_LogFont.lfUnderline = 0;

m_LogFont.lfStrikeOut = 0;

m_LogFont.lfCharSet = 0;

m_LogFont.lfOutPrecision = OUT_STRING_PRECIS;

m_LogFont.lfClipPrecision = CLIP_STROKE_PRECIS;

m_LogFont.lfQuality = DEFAULT_QUALITY;

m_LogFont.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH;

//_tcscpy(m_LogFont.lfFaceName, _T("Lucida Sans Unicode"));

_tcscpy(m_LogFont.lfFaceName, lpszFontName);

// create the associated font 

hFont = CreateFontLocal();


HFONT CreateFontLocal()


HFONT hFont = CreateFontIndirect(&m_LogFont);

if (hFont == NULL)


// GetLastError(); can be used to understand why the font was not created

MessageBox(0, _T("Impossible to create font\n"), _T("My Sample"), 0);


// don't forget to delete the current font

if (m_hFont != NULL)




// store the font (event if the creation has failed)

m_hFont = hFont;

return hFont;


VB code


Private Const FW_NORMAL = 400

Private Const DEFAULT_CHARSET = 1

Private Const OUT_DEFAULT_PRECIS = 0


Private Const DEFAULT_QUALITY = 0

Private Const VARIABLE_PITCH = 2

Private Const FF_SWISS = 32 ' Variable stroke width, sans-serifed.

Private Const GCS_RESULTSTR = &H800

Private Const GCS_RESULTREADSTR = &H200

Private Const GCS_COMPSTR = &H8

Private Const GCS_COMPREADSTR = &H1


Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function MyProjectDrawText Lib "CodeProjectSample.dll" ( _

ByVal lWindowDc As Long, _

ByVal szFontName As String, _

ByVal szFontSize As Long, _

ByVal lstrText As String, _

ByVal x As Long, _

ByVal y As Long) _

As Long

Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long

Private Declare Function ImmGetContext Lib "imm32.dll" (ByVal hwnd As Long) As Long

Private Declare Function ImmGetOpenStatus Lib "imm32.dll" (ByVal himc As Long) As Long

Private Declare Function ImmGetCompositionString Lib "imm32.dll" Alias "ImmGetCompositionStringA" (ByVal himc As Long, ByVal dw As Long, lpv As Any, ByVal dw2 As Long) As Long

Private Declare Function ImmReleaseContext Lib "imm32.dll" (ByVal hwnd As Long, ByVal himc As Long) As Long

Private Declare Function MulDiv Lib "kernel32" (ByVal nNumber As Long, ByVal nNumerator As Long, ByVal nDenominator As Long) As Long

Private Declare Function CreateFont Lib "gdi32" Alias "CreateFontA" (ByVal H As Long, ByVal W As Long, ByVal E As Long, ByVal O As Long, ByVal W As Long, ByVal I As Long, ByVal u As Long, ByVal S As Long, ByVal C As Long, ByVal OP As Long, ByVal CP As Long, ByVal Q As Long, ByVal PAF As Long, ByVal F As String) As Long

Private Declare Function TextOutW Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As Long, ByVal nCount As Long) As Long

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long

Private lngMouseDownX As Long

Private lngMouseDownY As Long

Private strFontName As String

Private lngFontSize As Long

Private mstrMarkupText As String

Private Sub Form_Load()

lngFontSize = 20

strFontName = "ËÎÌå"

lngMouseDownX = 50

lngMouseDownY = 150

End Sub

Private Sub Text1_Change()

Dim hct As Long

Dim ll As Long

Dim len5 As Long

Dim str5() As Byte

Dim hwnd As Long

Dim GetCompositionResult As String

hwnd = Screen.ActiveForm.hwnd

GetCompositionResult = ""

hct = ImmGetContext(hwnd)

If hct = 0 Then

Exit Sub

End If

'Get the size of the result string

ll = ImmGetCompositionString(hct, GCS_RESULTSTR, vbNullString, 0)

If ll > 0 Then

'lstrText = ""

ReDim str5(0 To ll - 1)

len5 = ImmGetCompositionString(hct, GCS_RESULTSTR, str5(0), ll)

GetCompositionResult = StrConv(str5, vbUnicode)

End If

ImmReleaseContext hwnd, hct

Debug.Print "'" & GetCompositionResult & "'"

Call MyDrawText(Me.hdc, strFontName, lngFontSize, GetCompositionResult, lngMouseDownX, lngMouseDownY)

End Sub

Open in new window

Question by:nsanga
    LVL 22

    Expert Comment

    Try this:
    Change your Declare to:

    Private Declare Function MyProjectDrawText Lib "CodeProjectSample.dll" ( _
    ByVal lWindowDc As Long, _
    ByVal szFontName As Long, _
    ByVal szFontSize As Long, _
    ByVal lstrText As Long, _
    ByVal x As Long, _
    ByVal y As Long) _
    As Long

    Use StrPtr:
    Call MyDrawText(Me.hdc, StrPtr(strFontName), lngFontSize, StrPtr(GetCompositionResult), lngMouseDownX, lngMouseDownY)

    Suggest you test first with a known Chinese string, then try with actual value of GetCompositionResult.

    GetCompositionResult = "CHS: " & ChrW$(&H6B22) & ChrW$(&H8FCE)
    LVL 7

    Author Comment


    Thank you. I tried your suggestion. However, it didnt solve the problem.

    Could you please let me know if you have some additional comments?

    Thanks & regards,
    LVL 22

    Expert Comment

    I think you will need to change the C code to accept a BSTR pointer for the 2 strings that are being passed.
    LVL 7

    Accepted Solution

    OK, thank you.

    I just changed my ".c" extension to ".cpp" and it started showing up the Chinese text properly.

    I am still not sure what is going wrong with .c file


    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Suggested Solutions

    Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
    Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
    The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
    The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

    732 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now