-
Notifications
You must be signed in to change notification settings - Fork 0
/
unit1.pas
208 lines (181 loc) · 5.43 KB
/
unit1.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
unit Unit1;
{$mode delphi}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
Messages, ExtCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Label1: TLabel;
ListBox1: TListBox;
PaintBox1: TPaintBox;
procedure FormCreate(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: char);
procedure FormShow(Sender: TObject);
procedure Label1Click(Sender: TObject);
private
{ private declarations }
buf : Unicodestring;
LastImeLen : Integer;
procedure WMIMENotify(var Msg: TMessage); message WM_IME_NOTIFY;
procedure WMIMEComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
procedure WMIMEStartComposition(var Msg: TMessage); message WM_IME_STARTCOMPOSITION;
//
procedure WMIMEEndComposition(var Msg: TMessage); message WM_IME_ENDCOMPOSITION;
procedure AddMessages(const Msg: TMessage);
public
{ public declarations }
end;
var
Form1: TForm1;
buffer: array[0..200] of WideChar;
implementation
{$R *.lfm}
uses Windows, imm, Lazutf8, fileutil;
const
limitchar = 30;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin
if Key=#8 then begin
Delete(buf,Length(buf),1);
end else
buf := buf + Key;
PaintBox1.Canvas.TextOut(1,1,UTF8Encode(buf+' '));
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Label1Click(nil);
end;
procedure TForm1.Label1Click(Sender: TObject);
begin
buf := '';
PaintBox1.Canvas.Rectangle(PaintBox1.ClientRect);
PaintBox1.Update;
ListBox1.Clear;
ActiveControl:=nil;
end;
procedure TForm1.WMIMENotify(var Msg: TMessage);
const
IMN_OPENCANDIDATE_CH = 269;
IMN_CLOSECANDIDATE_CH = 270;
var
candiform: CANDIDATEFORM;
imc: HIMC;
cPos: TPoint;
begin
case Msg.WParam of
//IMN_SETOPENSTATUS:
// UpdateImeWindow(Sender);
{ show candidate window. it need japanese and chinese input method }
IMN_OPENCANDIDATE_CH,
IMN_OPENCANDIDATE:
begin
imc:=ImmGetContext(Form1.Handle);
try
if imc<>0 then
begin
if GetCaretPos(cPos) then
begin
candiform.dwIndex:=0;
candiform.dwStyle:=CFS_FORCE_POSITION;
candiform.ptCurrentPos.X:=cPos.X;
candiform.ptCurrentPos.Y:=cPos.Y+Form1.Canvas.TextHeight('g')+1;
ImmSetCandidateWindow(imc,@candiform);
end;
end;
finally
ImmReleaseContext(Form1.Handle,imc);
end;
end;
end;
end;
procedure TForm1.WMIMEComposition(var Msg: TMessage);
const
IME_COMPFLAG = GCS_COMPSTR or GCS_COMPATTR or GCS_CURSORPOS;
IME_RESULTFLAG = GCS_RESULTCLAUSE or GCS_RESULTSTR;
var
IMC: HIMC;
imeCode, imeReadCode, len, ImmGCode, astart, alen: Integer;
begin
AddMessages(Msg);
imeCode:=Msg.lParam and (IME_COMPFLAG or IME_RESULTFLAG);
{ check compositon state }
if imeCode<>0 then
begin
IMC := ImmGetContext(Form1.Handle);
try
ImmGCode:=Msg.wParam;
{ check escape key code }
if ImmGCode<>$1b then
begin
{ for janpanese IME, process result and composition separately.
It comes together. Caret position doesn't implemented.
Candidate window need caret position for showing window. }
{ delete last char in buffer }
if LastImeLen>0 then
if Length(buf)>0 then
Delete(buf,Length(buf)-LastImeLen+1,LastImeLen);
{ insert result string }
if imecode and IME_RESULTFLAG<>0 then
begin
len:=ImmGetCompositionStringW(IMC,GCS_RESULTSTR,@buffer[0],sizeof(buffer)-sizeof(WideChar));
if len>0 then
len := len shr 1;
buffer[len]:=#0;
buf:=buf+buffer;
LastImeLen:=0;
end;
{ insert composition string }
if imeCode and IME_COMPFLAG<>0 then begin
len:=ImmGetCompositionStringW(IMC,GCS_COMPSTR,@buffer[0],sizeof(buffer)-sizeof(WideChar));
if len>0 then
len := len shr 1;
buffer[len]:=#0;
buf:=buf+buffer;
LastImeLen:=len;
end;
{ print string }
PaintBox1.Canvas.TextOut(1,1,UTF8Encode(buf+' '));
end;
finally
ImmReleaseContext(Form1.Handle,IMC);
end;
end;
Msg.Result:= -1;
end;
procedure TForm1.WMIMEStartComposition(var Msg: TMessage);
begin
LastImeLen:=0;
AddMessages(Msg);
end;
procedure TForm1.WMIMEEndComposition(var Msg: TMessage);
begin
AddMessages(Msg);
end;
procedure TForm1.AddMessages(const Msg: TMessage);
var
swork : string;
begin
case Msg.msg of
WM_IME_STARTCOMPOSITION : ListBox1.AddItem('WM_IME_STARTCOMPOSITION',nil);
WM_IME_COMPOSITION : begin
swork := '';
if Msg.lParam and GCS_RESULTSTR <> 0 then
swork:=swork+' GCS_RESULTSTR';
if Msg.lParam and GCS_COMPSTR <> 0 then
swork:=swork+' GCS_COMPSTR';
if Msg.lParam and GCS_COMPATTR <> 0 then
swork:=swork+' GCS_COMPATTR';
ListBox1.AddItem(Format('WM_IME_COMPOSITION %x %s',[Msg.lParam,swork]),nil);
end;
WM_IME_ENDCOMPOSITION : ListBox1.AddItem('WM_IME_ENDCOMPOSITION',nil);
end;
if ListBox1.Count>0 then;
ListBox1.ItemIndex:=ListBox1.Count-1;
end;
end.