5
{off $DEFINE WinIMEDebug}
10
windows, imm, Classes, SysUtils, LazLoggerBase, LCLType, LCLProc, Controls,
11
Graphics, SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection,
12
SynEditMarkup, SynEditTypes, SynEditKeyCmds, LazSynEditText;
18
LazSynIme = class(TSynEditFriend)
20
FInvalidateLinesMethod: TInvalidateLines;
23
procedure InvalidateLines(FirstLine, LastLine: integer);
24
procedure StopIme(Success: Boolean);
26
constructor Create(AOwner: TSynEditBase); reintroduce;
27
procedure WMImeRequest(var Msg: TMessage); virtual;
28
procedure WMImeNotify(var Msg: TMessage); virtual;
29
procedure WMImeComposition(var Msg: TMessage); virtual;
30
procedure WMImeStartComposition(var Msg: TMessage); virtual;
31
procedure WMImeEndComposition(var Msg: TMessage); virtual;
32
procedure FocusKilled; virtual;
33
property InvalidateLinesMethod : TInvalidateLines write FInvalidateLinesMethod;
38
LazSynImeSimple = class(LazSynIme)
40
FImeBlockSelection: TSynEditSelection;
41
FImeWinX, FImeWinY: Integer;
42
FTextDrawer: TheTextDrawer;
43
procedure SetTextDrawer(AValue: TheTextDrawer);
44
procedure UpdateImeWinXY(aX, aY: Integer; aImc: HIMC = 0; aForce: Boolean = False);
45
procedure UpdateImeWinFont(aImc: HIMC = 0);
46
procedure DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
47
procedure DoDrawerFontChanged(Sender: TObject);
48
procedure DoOnCommand(Sender: TObject; AfterProcessing: boolean; var Handled: boolean;
49
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
50
HandlerData: pointer);
51
procedure DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
54
constructor Create(AOwner: TSynEditBase);
55
destructor Destroy; override;
56
procedure WMImeNotify(var Msg: TMessage); override;
57
procedure WMImeComposition(var Msg: TMessage); override;
58
procedure WMImeStartComposition(var Msg: TMessage); override;
59
procedure WMImeEndComposition(var Msg: TMessage); override;
60
procedure FocusKilled; override;
61
property TextDrawer: TheTextDrawer read FTextDrawer write SetTextDrawer;
66
LazSynImeFull = class(LazSynIme)
68
FImeBlockSelection, FImeBlockSelection2: TSynEditSelection;
69
FImeMarkupSelection, FImeMarkupSelection2: TSynEditMarkupSelection;
71
procedure SetImeTempText(const s: string);
72
procedure DoOnCommand(Sender: TObject; AfterProcessing: boolean; var Handled: boolean;
73
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
74
HandlerData: pointer);
75
procedure DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
77
procedure DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
79
constructor Create(AOwner: TSynEditBase);
80
destructor Destroy; override;
81
procedure WMImeRequest(var Msg: TMessage); override;
82
procedure WMImeNotify(var Msg: TMessage); override;
83
procedure WMImeComposition(var Msg: TMessage); override;
84
procedure WMImeStartComposition(var Msg: TMessage); override;
85
procedure WMImeEndComposition(var Msg: TMessage); override;
86
procedure FocusKilled; override;
94
procedure LazSynIme.InvalidateLines(FirstLine, LastLine: integer);
96
FInvalidateLinesMethod(FirstLine, LastLine);
99
procedure LazSynIme.StopIme(Success: Boolean);
103
if (not FInCompose) or (not FriendEdit.HandleAllocated) then exit;
105
imc := ImmGetContext(FriendEdit.Handle);
106
if (imc <> 0) then begin
108
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0)
110
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
111
ImmReleaseContext(FriendEdit.Handle, imc);
115
constructor LazSynIme.Create(AOwner: TSynEditBase);
117
FriendEdit := AOwner;
120
procedure LazSynIme.WMImeRequest(var Msg: TMessage);
124
procedure LazSynIme.WMImeComposition(var Msg: TMessage);
128
procedure LazSynIme.WMImeNotify(var Msg: TMessage);
132
procedure LazSynIme.WMImeStartComposition(var Msg: TMessage);
136
procedure LazSynIme.WMImeEndComposition(var Msg: TMessage);
140
procedure LazSynIme.FocusKilled;
146
procedure LazSynImeSimple.DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
148
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix);
149
if Changes * [scCaretX, scCaretY] <> [] then
153
procedure LazSynImeSimple.DoDrawerFontChanged(Sender: TObject);
157
if not FriendEdit.HandleAllocated then
159
imc := ImmGetContext(FriendEdit.Handle);
160
if (imc <> 0) then begin
161
UpdateImeWinFont(imc);
162
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix, imc);
163
ImmReleaseContext(FriendEdit.Handle, imc);
167
procedure LazSynImeSimple.DoOnCommand(Sender: TObject; AfterProcessing: boolean;
168
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
169
HandlerData: pointer);
174
procedure LazSynImeSimple.DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
180
procedure LazSynImeSimple.UpdateImeWinXY(aX, aY: Integer; aImc: HIMC; aForce: Boolean);
185
if not FriendEdit.HandleAllocated then exit;
186
if (not aForce) and (aX = FImeWinX) and (aY = FImeWinY) then exit;
190
cf.dwStyle := CFS_POINT;
191
cf.ptCurrentPos := Point(aX, aY);
193
imc := ImmGetContext(FriendEdit.Handle)
196
if (imc <> 0) then begin
197
ImmSetCompositionWindow(imc, @cf);
199
ImmReleaseContext(FriendEdit.Handle, imc);
203
procedure LazSynImeSimple.SEtTextDrawer(AValue: TheTextDrawer);
205
if FTextDrawer = AValue then Exit;
206
if FTextDrawer <> nil then
207
FTextDrawer.UnRegisterOnFontChangeHandler(@DoDrawerFontChanged);
208
FTextDrawer := AValue;
209
if FTextDrawer <> nil then
210
FTextDrawer.RegisterOnFontChangeHandler(@DoDrawerFontChanged);
213
procedure LazSynImeSimple.UpdateImeWinFont(aImc: HIMC);
218
if not FriendEdit.HandleAllocated then exit;
220
imc := ImmGetContext(FriendEdit.Handle)
223
if (imc <> 0) then begin
224
GetObject(FriendEdit.Font.Handle, SizeOf(TLogFont), @logFont);
225
ImmSetCompositionFontA(imc, @logFont);
227
ImmReleaseContext(FriendEdit.Handle, imc);
231
constructor LazSynImeSimple.Create(AOwner: TSynEditBase);
233
inherited Create(AOwner);
234
FImeBlockSelection := TSynEditSelection.Create(ViewedTextBuffer, False);
235
FImeBlockSelection.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
237
TCustomSynEdit(FriendEdit).RegisterStatusChangedHandler(@DoStatusChanged, [scCaretX, scCaretY, scLeftChar, scTopLine, scModified]);
238
TCustomSynEdit(FriendEdit).RegisterCommandHandler(@DoOnCommand, nil, [hcfInit]);
239
TCustomSynEdit(FriendEdit).RegisterBeforeMouseDownHandler(@DoOnMouse);
242
destructor LazSynImeSimple.Destroy;
245
FreeAndNil(FImeBlockSelection);
246
TCustomSynEdit(FriendEdit).UnregisterBeforeMouseDownHandler(@DoOnMouse);
247
TCustomSynEdit(FriendEdit).UnregisterCommandHandler(@DoOnCommand);
248
TCustomSynEdit(FriendEdit).UnRegisterStatusChangedHandler(@DoStatusChanged);
252
procedure LazSynImeSimple.WMImeNotify(var Msg: TMessage);
261
IMN_CLOSESTATUSWINDOW: s:= 'IMN_CLOSESTATUSWINDOW, ';
262
IMN_OPENSTATUSWINDOW: s:= 'IMN_OPENSTATUSWINDOW, ';
263
IMN_CHANGECANDIDATE: s:= 'IMN_CHANGECANDIDATE, ';
264
IMN_CLOSECANDIDATE: s:= 'IMN_CLOSECANDIDATE, ';
265
IMN_OPENCANDIDATE: s:= 'IMN_OPENCANDIDATE, ';
266
IMN_SETCONVERSIONMODE: s:= 'IMN_SETCONVERSIONMODE, ';
267
IMN_SETSENTENCEMODE: s:= 'IMN_SETSENTENCEMODE, ';
268
IMN_SETOPENSTATUS: s:= 'IMN_SETOPENSTATUS, ';
269
IMN_SETCANDIDATEPOS: s:= 'IMN_SETCANDIDATEPOS, ';
270
IMN_SETCOMPOSITIONFONT: s:= 'IMN_SETCOMPOSITIONFONT, ';
271
IMN_SETCOMPOSITIONWINDOW: s:= 'IMN_SETCOMPOSITIONWINDOW, ';
272
IMN_SETSTATUSWINDOWPOS: s:= 'IMN_SETSTATUSWINDOWPOS, ';
273
IMN_GUIDELINE: s:= 'IMN_GUIDELINE, ';
274
IMN_PRIVATE: s:= 'IMN_PRIVATE, ';
276
debugln(['TCustomSynEdit.WMImeNotify ',s,' ', dbgHex(Msg.lParam), ' , ', dbgHex(Msg.wParam)]);
280
IMN_SETOPENSTATUS: begin
281
imc := ImmGetContext(FriendEdit.Handle);
282
if (imc <> 0) then begin
283
UpdateImeWinFont(imc);
284
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix, imc, True);
285
ImmReleaseContext(FriendEdit.Handle, imc);
288
IMN_CLOSESTATUSWINDOW:
293
procedure LazSynImeSimple.WMImeComposition(var Msg: TMessage);
299
if ((Msg.LParam and GCS_RESULTSTR) <> 0) then begin
300
imc := ImmGetContext(FriendEdit.Handle);
302
if imc <> 0 then begin
303
ImeCount := ImmGetCompositionStringW(imc, GCS_RESULTSTR, nil, 0);
305
DebugLn(['--- GCS_RESULTSTR ', dbgHex(ImeCount)]);
307
if ImeCount > 0 then begin
308
GetMem(p, ImeCount + 2);
310
TCustomSynEdit(FriendEdit).BeginUpdate;
311
ImmGetCompositionStringW(imc, GCS_RESULTSTR, p, ImeCount + 2);
314
FImeBlockSelection.SelText := UTF16ToUTF8(PWCHAR(p));
315
FImeBlockSelection.StartLineBytePos := FImeBlockSelection.EndLineBytePos;
316
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
319
FreeMem(p, ImeCount + 2);
320
TCustomSynEdit(FriendEdit).EndUpdate;
325
ImmReleaseContext(FriendEdit.Handle, imc);
332
procedure LazSynImeSimple.WMImeStartComposition(var Msg: TMessage);
336
//debugln(['TCustomSynEdit.WMImeStartComposition ']);
337
imc := ImmGetContext(FriendEdit.Handle);
338
if (imc <> 0) then begin
339
UpdateImeWinFont(imc);
340
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix, imc, True);
341
ImmReleaseContext(FriendEdit.Handle, imc);
344
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
347
procedure LazSynImeSimple.WMImeEndComposition(var Msg: TMessage);
352
procedure LazSynImeSimple.FocusKilled;
359
procedure LazSynImeFull.DoOnCommand(Sender: TObject; AfterProcessing: boolean;
360
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
361
HandlerData: pointer);
366
procedure LazSynImeFull.DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
372
procedure LazSynImeFull.DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
374
if FInImeMsg then exit;
378
procedure LazSynImeFull.SetImeTempText(const s: string);
383
p1 := FImeBlockSelection.FirstLineBytePos;
387
ViewedTextBuffer.UndoList.Lock;
388
ViewedTextBuffer.RedoList.Lock;
389
FImeBlockSelection.SelText := s;
390
ViewedTextBuffer.UndoList.Unlock;
391
ViewedTextBuffer.RedoList.Unlock;
394
p2 := FImeBlockSelection.FirstLineBytePos;
395
FImeBlockSelection.StartLineBytePos := p1;
396
FImeBlockSelection.EndLineBytePos := p2;
399
constructor LazSynImeFull.Create(AOwner: TSynEditBase);
401
inherited Create(AOwner);
403
FImeBlockSelection := TSynEditSelection.Create(ViewedTextBuffer, False);
404
FImeBlockSelection.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
405
FImeBlockSelection2 := TSynEditSelection.Create(ViewedTextBuffer, False);
406
FImeBlockSelection2.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
408
FImeMarkupSelection := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection);
409
FImeMarkupSelection2 := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection2);
411
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection);
412
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection2);
414
FImeMarkupSelection.MarkupInfo.Clear;
415
FImeMarkupSelection.MarkupInfo.FramePriority := 999;
416
FImeMarkupSelection.MarkupInfo.FrameColor := clDefault;
417
FImeMarkupSelection.MarkupInfo.FrameStyle := slsDotted;
418
FImeMarkupSelection.MarkupInfo.FrameEdges := sfeAround;
420
FImeMarkupSelection2.MarkupInfo.Clear;
421
FImeMarkupSelection2.MarkupInfo.FramePriority := 999+1;
422
FImeMarkupSelection2.MarkupInfo.FrameColor := clDefault;
423
FImeMarkupSelection2.MarkupInfo.FrameStyle := slsSolid;
424
FImeMarkupSelection2.MarkupInfo.FrameEdges := sfeBottom;
426
TCustomSynEdit(FriendEdit).RegisterStatusChangedHandler(@DoStatusChanged, [scCaretX, scCaretY, scModified]);
427
TCustomSynEdit(FriendEdit).RegisterCommandHandler(@DoOnCommand, nil, [hcfInit]);
428
TCustomSynEdit(FriendEdit).RegisterBeforeMouseDownHandler(@DoOnMouse);
432
destructor LazSynImeFull.Destroy;
434
TCustomSynEdit(FriendEdit).UnregisterBeforeMouseDownHandler(@DoOnMouse);
435
TCustomSynEdit(FriendEdit).UnregisterCommandHandler(@DoOnCommand);
436
TCustomSynEdit(FriendEdit).UnRegisterStatusChangedHandler(@DoStatusChanged);
438
FreeAndNil(FImeBlockSelection);
439
FreeAndNil(FImeBlockSelection2);
443
procedure LazSynImeFull.WMImeRequest(var Msg: TMessage);
448
cp: PIMECHARPOSITION;
450
CWidth: TPhysicalCharWidths;
455
IMR_COMPOSITIONWINDOW: s:= 'IMR_COMPOSITIONWINDOW, ';
456
IMR_CANDIDATEWINDOW: s:= 'IMR_CANDIDATEWINDOW, ';
457
IMR_COMPOSITIONFONT: s:= 'IMR_COMPOSITIONFONT, ';
458
IMR_RECONVERTSTRING: s:= 'IMR_RECONVERTSTRING, ';
459
IMR_CONFIRMRECONVERTSTRING: s:= 'IMR_CONFIRMRECONVERTSTRING, ';
460
IMR_DOCUMENTFEED: s:= 'IMR_DOCUMENTFEED, ';
462
if s <> '' then debugln(['TCustomSynEdit.WMImeRequest ', s,' ' , dbgHex(Msg.lParam)]);
466
IMR_QUERYCHARPOSITION: begin
467
cp := PIMECHARPOSITION(Msg.lParam);
468
p1 := FImeBlockSelection.StartLineBytePos;
470
CWidth := ViewedTextBuffer.GetPhysicalCharWidths(FImeBlockSelection.StartLinePos - 1);
473
while (i > 0) and (x < length(CWidth)) do begin
475
while (x < length(CWidth)) and (CWidth[x] = 0) do
480
p1 := FriendEdit.ClientToScreen(TCustomSynEdit(FriendEdit).RowColumnToPixels(ViewedTextBuffer.LogicalToPhysicalPos(p1)));
484
cp^.cLineHeight := TCustomSynEdit(FriendEdit).LineHeight;
485
cp^.rcDocument.TopLeft := FriendEdit.ClientToScreen(FriendEdit.ClientRect.TopLeft);
486
cp^.rcDocument.BottomRight := FriendEdit.ClientToScreen(FriendEdit.ClientRect.BottomRight);
488
debugln(['--- TCustomSynEdit.WMImeRequest ** IMR_QUERYCHARPOSITION ', dbgs(cp^.dwCharPos), ' ', dbgs(x),' ', dbgs(p1.x)]);
495
procedure LazSynImeFull.WMImeNotify(var Msg: TMessage);
503
IMN_CLOSESTATUSWINDOW: s:= 'IMN_CLOSESTATUSWINDOW, ';
504
IMN_OPENSTATUSWINDOW: s:= 'IMN_OPENSTATUSWINDOW, ';
505
IMN_CHANGECANDIDATE: s:= 'IMN_CHANGECANDIDATE, ';
506
IMN_CLOSECANDIDATE: s:= 'IMN_CLOSECANDIDATE, ';
507
IMN_OPENCANDIDATE: s:= 'IMN_OPENCANDIDATE, ';
508
IMN_SETCONVERSIONMODE: s:= 'IMN_SETCONVERSIONMODE, ';
509
IMN_SETSENTENCEMODE: s:= 'IMN_SETSENTENCEMODE, ';
510
IMN_SETOPENSTATUS: s:= 'IMN_SETOPENSTATUS, ';
511
IMN_SETCANDIDATEPOS: s:= 'IMN_SETCANDIDATEPOS, ';
512
IMN_SETCOMPOSITIONFONT: s:= 'IMN_SETCOMPOSITIONFONT, ';
513
IMN_SETCOMPOSITIONWINDOW: s:= 'IMN_SETCOMPOSITIONWINDOW, ';
514
IMN_SETSTATUSWINDOWPOS: s:= 'IMN_SETSTATUSWINDOWPOS, ';
515
IMN_GUIDELINE: s:= 'IMN_GUIDELINE, ';
516
IMN_PRIVATE: s:= 'IMN_PRIVATE, ';
518
debugln(['TCustomSynEdit.WMImeNotify ',s,' ', dbgHex(Msg.lParam), ' , ', dbgHex(Msg.wParam)]);
522
procedure LazSynImeFull.WMImeComposition(var Msg: TMessage);
524
CWidth: TPhysicalCharWidths;
526
function CharToByte(AStart, AChars: integer): integer;
528
if length(CWidth) = 0 then
529
CWidth := ViewedTextBuffer.GetPhysicalCharWidths(FImeBlockSelection.StartLinePos - 1);
532
while (AChars > 0) and (Result < length(CWidth)) do begin
534
while (Result < length(CWidth)) and (CWidth[Result] = 0) do
538
Result := Result - AStart + AChars;
552
if (Msg.lparam and GCS_COMPREADSTR)<>0 then s := s + 'GCS_COMPREADSTR, ';
553
if (Msg.lparam and GCS_COMPREADATTR)<>0 then s := s + 'GCS_COMPREADATTR, ';
554
if (Msg.lparam and GCS_COMPREADCLAUSE)<>0 then s := s + 'GCS_COMPREADCLAUSE, ';
555
//if (Msg.lparam and GCS_COMPSTR)<>0 then s := s + 'GCS_COMPSTR, ';
556
if (Msg.lparam and GCS_COMPATTR)<>0 then s := s + 'GCS_COMPATTR, ';
557
if (Msg.lparam and GCS_COMPCLAUSE)<>0 then s := s + 'GCS_COMPCLAUSE, ';
558
//if (Msg.lparam and GCS_CURSORPOS)<>0 then s := s + 'GCS_CURSORPOS, ';
559
//if (Msg.lparam and GCS_DELTASTART)<>0 then s := s + 'GCS_DELTASTART, ';
560
if (Msg.lparam and GCS_RESULTREADSTR)<>0 then s := s + 'GCS_RESULTREADSTR, ';
561
if (Msg.lparam and GCS_RESULTREADCLAUSE)<>0 then s := s + 'GCS_RESULTREADCLAUSE, ';
562
//if (Msg.lparam and GCS_RESULTSTR)<>0 then s := s + 'GCS_RESULTSTR, ';
563
if (Msg.lparam and GCS_RESULTCLAUSE)<>0 then s := s + 'GCS_RESULTCLAUSE, ';
564
if (Msg.lparam and CS_INSERTCHAR)<>0 then s := s + ' ** CS_INSERTCHAR, ';
565
if (Msg.lparam and CS_NOMOVECARET)<>0 then s := s + ' ** CS_NOMOVECARET, ';
566
if s <> '' then debugln(['TCustomSynEdit.WMImeComposition ', s]);
569
if ((Msg.LParam and (GCS_RESULTSTR or GCS_COMPSTR or GCS_CURSORPOS or GCS_COMPATTR)) = 0) then
574
SetLength(CWidth, 0);
577
if ((Msg.LParam and GCS_RESULTSTR) <> 0) then begin
579
imc := ImmGetContext(FriendEdit.Handle);
580
ImeCount := ImmGetCompositionStringW(imc, GCS_RESULTSTR, nil, 0);
582
DebugLn(['--- GCS_RESULTSTR ', dbgHex(ImeCount)]);
584
if ImeCount > 0 then begin
585
GetMem(p, ImeCount + 2);
587
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
588
TCustomSynEdit(FriendEdit).BeginUpdate;
589
ImmGetCompositionStringW(imc, GCS_RESULTSTR, p, ImeCount + 2);
593
FImeBlockSelection.SelText := UTF16ToUTF8(PWCHAR(p));
594
FImeBlockSelection.StartLineBytePos := FImeBlockSelection.EndLineBytePos;
595
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
598
TCustomSynEdit(FriendEdit).EndUpdate;
599
FreeMem(p, ImeCount + 2);
604
if ((Msg.LParam and GCS_COMPSTR) <> 0) then begin
606
imc := ImmGetContext(FriendEdit.Handle);
607
ImeCount := ImmGetCompositionStringW(imc, GCS_COMPSTR, nil, 0);
609
DebugLn(['--- GCS_COMPSTR ', dbgHex(ImeCount)]);
611
if ImeCount > 0 then begin
612
GetMem(p, ImeCount + 2);
614
ImmGetCompositionStringW(imc, GCS_COMPSTR, p, ImeCount + 2);
617
SetImeTempText(UTF16ToUTF8(PWCHAR(p)));
620
FreeMem(p, ImeCount + 2);
625
if ((Msg.LParam and GCS_COMPATTR) <> 0) then begin
627
imc := ImmGetContext(FriendEdit.Handle);
628
ImeCount := ImmGetCompositionStringW(imc, GCS_COMPATTR, nil, 0);
630
DebugLn(['***** GCS_COMPATTR ', dbgHex(ImeCount)]);
632
if ImeCount > 0 then begin
633
xy := FImeBlockSelection.StartLineBytePos;
634
FImeBlockSelection2.StartLineBytePos := xy;
635
FImeBlockSelection2.EndLineBytePos := xy;
636
GetMem(p, ImeCount + 2);
638
ImmGetCompositionStringW(imc, GCS_COMPATTR, p, ImeCount + 2);
639
//DebugLn(dbgMemRange(PByte( p), ImeCount));
641
while i < ImeCount do begin
642
if ord(p[i]) = ATTR_TARGET_CONVERTED then begin
643
x := FImeBlockSelection.StartBytePos;
644
xy.x := x + CharToByte(x, i);
645
FImeBlockSelection2.StartLineBytePos := xy;
647
while i < ImeCount do begin
648
if (ord(p[i]) <> ATTR_TARGET_CONVERTED) or (i = ImeCount-1) then begin
649
if (ord(p[i]) = ATTR_TARGET_CONVERTED) then
651
xy.x := x + CharToByte(x, i);
652
FImeBlockSelection2.EndLineBytePos := xy;
664
FreeMem(p, ImeCount + 2);
669
if ((Msg.LParam and GCS_CURSORPOS) <> 0) then begin
671
imc := ImmGetContext(FriendEdit.Handle);
673
ImeCount := ImmGetCompositionStringW(imc, GCS_CURSORPOS, nil, 0);
675
DebugLn(['--- GCS_CURSORPOS ', dbgs(ImeCount)]);
677
if ImeCount >= 0 then begin
678
ImeCount := ImeCount and $ffff;
679
x := FImeBlockSelection.StartBytePos;
680
x := x + CharToByte(x, ImeCount);
681
CaretObj.CharPos := ViewedTextBuffer.LogicalToPhysicalPos(Point(x, FImeBlockSelection.StartLinePos)).x;
687
ImmReleaseContext(FriendEdit.Handle, imc);
693
procedure LazSynImeFull.WMImeStartComposition(var Msg: TMessage);
695
//debugln(['TCustomSynEdit.WMImeStartComposition ']);
696
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
701
procedure LazSynImeFull.WMImeEndComposition(var Msg: TMessage);
703
//debugln(['TCustomSynEdit.WMImeEndComposition ']);
705
CaretObj.LineBytePos := FImeBlockSelection.LastLineBytePos;
706
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
707
FImeBlockSelection2.StartLineBytePos := CaretObj.LineBytePos;
712
procedure LazSynImeFull.FocusKilled;