Link to home
Start Free TrialLog in
Avatar of nsanga
nsanga

asked on

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?

Regards,
Narahari
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
__stdcall
MyDrawText(
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);
 
SelectObject(lWindowDC,m_hFont); 
 
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)
{
DeleteObject(m_hFont);
}
 
// 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 CLIP_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 Const SCS_SETSTR = (GCS_COMPREADSTR Or GCS_COMPSTR)
 
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

Avatar of Dana Seaman
Dana Seaman
Flag of Brazil image

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)
Avatar of nsanga
nsanga

ASKER

danaseaman,

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,
Narahari
I think you will need to change the C code to accept a BSTR pointer for the 2 strings that are being passed.
ASKER CERTIFIED SOLUTION
Avatar of nsanga
nsanga

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial