Author: Daniel Wischnewski
Recently I ran into the problem of converting text for the Shift-JIS (Japanese
Idioms) code pages when creating an i-mode interface for my companies Content
Management System. But before I was about to start writing all by myself I checked
into the tool Microsoft gave us.
Answer:
All Systems (Win 95+ and WinNT4+) with MS Internet Explorer 4 and newer have a
library named mlang.dll in the Winnt\System32 directory. Usually you can tell
Delphi to simply import these COM Libraries. This one however, Delphi did not. I
started to convert the "most wanted" interface for myself. The results I present
you here.
First I give you the code for the conversion unit, that allows you simply convert
any text from code page interpretation into another one. Following I will shortly
discuss the code and give you a sample of how to use it.
uCodePageConverter
1
2 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3 *
4 * Unit Name : uCodePageConverter
5 * Autor : Daniel Wischnewski
6 * Copyright : Copyright © 2002 by gate(n)etwork. All Right Reserved.
7 * Urheber : Daniel Wischnewski
8 *
9 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
10
11 unit uCodePageConverter;
12
13 interface
14
15 uses
16 Windows;
17
18 const
19 IID_MLangConvertCharset: TGUID = '{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}';
20 CLASS_MLangConvertCharset: TGUID = '{D66D6F99-CDAA-11D0-B822-00C04FC9B31F}';
21
22 type
23 tagMLCONVCHARF = DWORD;
24
25 const
26 MLCONVCHARF_AUTODETECT: tagMLCONVCHARF = 1;
27 MLCONVCHARF_ENTITIZE: tagMLCONVCHARF = 2;
28
29 type
30 tagCODEPAGE = UINT;
31
32 const
33 CODEPAGE_Thai: tagCODEPAGE = 0874;
34 CODEPAGE_Japanese: tagCODEPAGE = 0932;
35 CODEPAGE_Chinese_PRC: tagCODEPAGE = 0936;
36 CODEPAGE_Korean: tagCODEPAGE = 0949;
37 CODEPAGE_Chinese_Taiwan: tagCODEPAGE = 0950;
38 CODEPAGE_UniCode: tagCODEPAGE = 1200;
39 CODEPAGE_Windows_31_EastEurope: tagCODEPAGE = 1250;
40 CODEPAGE_Windows_31_Cyrillic: tagCODEPAGE = 1251;
41 CODEPAGE_Windows_31_Latin1: tagCODEPAGE = 1252;
42 CODEPAGE_Windows_31_Greek: tagCODEPAGE = 1253;
43 CODEPAGE_Windows_31_Turkish: tagCODEPAGE = 1254;
44 CODEPAGE_Hebrew: tagCODEPAGE = 1255;
45 CODEPAGE_Arabic: tagCODEPAGE = 1256;
46 CODEPAGE_Baltic: tagCODEPAGE = 1257;
47
48 type
49 IMLangConvertCharset = interface
50 ['{D66D6F98-CDAA-11D0-B822-00C04FC9B31F}']
51 function Initialize(
52 uiSrcCodePage: tagCODEPAGE; uiDstCodePage: tagCODEPAGE;
53 dwProperty: tagMLCONVCHARF
54 ): HResult; stdcall;
55 function GetSourceCodePage(
56 out puiSrcCodePage: tagCODEPAGE
57 ): HResult; stdcall;
58 function GetDestinationCodePage(
59 out puiDstCodePage: tagCODEPAGE
60 ): HResult; stdcall;
61 function GetProperty(out pdwProperty: tagMLCONVCHARF): HResult; stdcall;
62 function DoConversion(
63 pSrcStr: PChar; pcSrcSize: PUINT; pDstStr: PChar; pcDstSize: PUINT
64 ): HResult; stdcall;
65 function DoConversionToUnicode(
66 pSrcStr: PChar; pcSrcSize: PUINT; pDstStr: PWChar; pcDstSize: PUINT
67 ): HResult; stdcall;
68 function DoConversionFromUnicode(
69 pSrcStr: PWChar; pcSrcSize: PUINT; pDstStr: PChar; pcDstSize: PUINT
70 ): HResult; stdcall;
71 end;
72
73 CoMLangConvertCharset = class
74 class function Create: IMLangConvertCharset;
75 class function CreateRemote(const MachineName: string): IMLangConvertCharset;
76 end;
77
78 implementation
79
80 uses
81 ComObj;
82
83 { CoMLangConvertCharset }
84
85 class function CoMLangConvertCharset.Create: IMLangConvertCharset;
86 begin
87 Result := CreateComObject(CLASS_MLangConvertCharset) as IMLangConvertCharset;
88 end;
89
90 class function CoMLangConvertCharset.CreateRemote(
91 const MachineName: string
92 ): IMLangConvertCharset;
93 begin
94 Result := CreateRemoteComObject(
95 MachineName, CLASS_MLangConvertCharset
96 ) as IMLangConvertCharset;
97 end;
98
99 end.
As you can see, I did translate only one of the many interfaces, however this one
is the most efficient (according to Microsoft) and will do the job. Further I added
some constants to simplify the task of finding the most important values.
When using this unit to do any code page conersions you must not forget, that the
both code pages (source and destination) must be installed and supported on the
computer that does the translation. OIn the computer that is going to show the
result only the destination code page must be installed and supported.
To test the unit simple create a form with a memo and a button. Add the following
code to the buttons OnClick event. (Do not forget to add the conversion unit to the
uses clause!)
SAMPLE
100 procedure TForm1.Button1Click(Sender: TObject);
101 var
102 Conv: IMLangConvertCharset;
103 Source: PWChar;
104 Dest: PChar;
105 SourceSize, DestSize: UINT;
106 begin
107 // connect to MS multi-language lib
108 Conv := CoMLangConvertCharset.Create;
109 // initialize UniCode Translation to Japanese
110 Conv.Initialize(CODEPAGE_UniCode, CODEPAGE_Japanese, MLCONVCHARF_ENTITIZE);
111 // load source (from memo)
112 Source := PWChar(WideString(Memo1.Text));
113 SourceSize := Succ(Length(Memo1.Text));
114 // prepare destination
115 DestSize := 0;
116 // lets calculate size needed
117 Conv.DoConversionFromUnicode(Source, @SourceSize, nil, @DestSize);
118 // reserve memory
119 GetMem(Dest, DestSize);
120 try
121 // convert
122 Conv.DoConversionFromUnicode(Source, @SourceSize, Dest, @DestSize);
123 // show
124 Memo1.Text := Dest;
125 finally
126 // free memory
127 FreeMem(Dest);
128 end;
129 end;
Further Information regarding code page translations you will find at MSDN - IMLangConvertCharset http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceielng/htm/cerefIMLangConvertCharsetIUnknown.asp
|