• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 813
  • Last Modified:

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

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

  • 2
  • 2
1 Solution
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)
nsangaAuthor Commented:

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,
I think you will need to change the C code to accept a BSTR pointer for the 2 strings that are being passed.
nsangaAuthor Commented:
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

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now