Merged revision(s) 48463 #0f8ef5d6fc, 48465 #6f0657736a, 48486 #56a9ba3535, 48498 #5fd753e72e from trunk:

SynEdit: win, IME Handler: Fixed more overwrite selection. Issue #0027712
........
SynEdit: win, IME Handler: markup, underline only
........
SynEdit: win, IME Handler: added markup for ATTR_TARGET_NOTCONVERTED
........
SynEdit: win, IME Handler: added started/ended events
........

git-svn-id: branches/fixes_1_4@48500 -
This commit is contained in:
martin 2015-03-24 23:55:46 +00:00
parent d71675e64f
commit d22c751a83
2 changed files with 197 additions and 13 deletions

View File

@ -3,13 +3,16 @@ unit LazSynIMM;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{off $DEFINE WinIMEDebug} {off $DEFINE WinIMEDebug}
{off $DEFINE WinIMEFullDeferOverwrite} // In Full IME do "overwrite selecton" when IME finishes (normally done at start)
{off $DEFINE WinIMEFullOverwriteSkipUndo} // In Full IME undo "overwrite selecton", if IME cancelled
interface interface
uses uses
windows, imm, Classes, SysUtils, LazLoggerBase, LCLType, LCLProc, Controls, windows, imm, Classes, SysUtils, LazLoggerBase, LCLType, LCLProc, Controls,
Graphics, SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection, Graphics, SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection,
SynEditMarkup, SynEditTypes, SynEditKeyCmds, LazSynEditText; SynEditMarkup, SynEditTypes, SynEditKeyCmds, LazSynEditText, SynEditTextBase,
SynEditMiscProcs;
{$IFDEF WINCE} {$IF (FPC_FULLVERSION < 20700)} {$IFDEF WINCE} {$IF (FPC_FULLVERSION < 20700)}
function ImmSetCompositionFontA(_himc:HIMC; lplf:LPLOGFONT):BOOL; external ImmDLL name 'ImmSetCompositionFontA'; function ImmSetCompositionFontA(_himc:HIMC; lplf:LPLOGFONT):BOOL; external ImmDLL name 'ImmSetCompositionFontA';
@ -23,10 +26,15 @@ type
LazSynIme = class(TSynEditFriend) LazSynIme = class(TSynEditFriend)
private private
FInvalidateLinesMethod: TInvalidateLines; FInvalidateLinesMethod: TInvalidateLines;
FOnIMEEnd: TNotifyEvent;
FOnIMEStart: TNotifyEvent;
FIMEActive: Boolean;
protected protected
FInCompose: Boolean; FInCompose: Boolean;
procedure InvalidateLines(FirstLine, LastLine: integer); procedure InvalidateLines(FirstLine, LastLine: integer);
procedure StopIme(Success: Boolean); procedure StopIme(Success: Boolean); virtual;
procedure DoIMEStarted;
procedure DoIMEEnded;
public public
constructor Create(AOwner: TSynEditBase); reintroduce; constructor Create(AOwner: TSynEditBase); reintroduce;
procedure WMImeRequest(var Msg: TMessage); virtual; procedure WMImeRequest(var Msg: TMessage); virtual;
@ -36,6 +44,8 @@ type
procedure WMImeEndComposition(var Msg: TMessage); virtual; procedure WMImeEndComposition(var Msg: TMessage); virtual;
procedure FocusKilled; virtual; procedure FocusKilled; virtual;
property InvalidateLinesMethod : TInvalidateLines write FInvalidateLinesMethod; property InvalidateLinesMethod : TInvalidateLines write FInvalidateLinesMethod;
property OnIMEStart: TNotifyEvent read FOnIMEStart write FOnIMEStart;
property OnIMEEnd: TNotifyEvent read FOnIMEEnd write FOnIMEEnd;
end; end;
{ LazSynImeSimple } { LazSynImeSimple }
@ -70,9 +80,16 @@ type
LazSynImeFull = class(LazSynIme) LazSynImeFull = class(LazSynIme)
private private
FImeBlockSelection, FImeBlockSelection2: TSynEditSelection; FImeBlockSelection, FImeBlockSelection2, FImeBlockSelection3: TSynEditSelection; // TODO: create a custom markup
FImeMarkupSelection, FImeMarkupSelection2: TSynEditMarkupSelection; FImeMarkupSelection, FImeMarkupSelection2, FImeMarkupSelection3: TSynEditMarkupSelection;
FInImeMsg: Boolean; FInImeMsg: Boolean;
{$IFnDEF WinIMEFullOverwriteSkipUndo}
FUndoStamp1, FUndoStamp2: TSynEditUndoGroup;
FNeedUndoOnCancel: Boolean;
{$ENDIF}
{$IFDEF WinIMEFullDeferOverwrite}
FHasPersistLock: Boolean;
{$ENDIF}
procedure SetImeTempText(const s: string); procedure SetImeTempText(const s: string);
procedure DoOnCommand(Sender: TObject; AfterProcessing: boolean; var Handled: boolean; procedure DoOnCommand(Sender: TObject; AfterProcessing: boolean; var Handled: boolean;
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
@ -80,6 +97,8 @@ type
procedure DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, procedure DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer); Y: Integer);
procedure DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges); procedure DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
protected
procedure StopIme(Success: Boolean); override;
public public
constructor Create(AOwner: TSynEditBase); constructor Create(AOwner: TSynEditBase);
destructor Destroy; override; destructor Destroy; override;
@ -115,6 +134,25 @@ begin
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ImmReleaseContext(FriendEdit.Handle, imc); ImmReleaseContext(FriendEdit.Handle, imc);
end; end;
DoIMEEnded;
end;
procedure LazSynIme.DoIMEStarted;
begin
if FIMEActive then
exit;
FIMEActive := True;
if FOnIMEStart <> nil then
FOnIMEStart(FriendEdit);
end;
procedure LazSynIme.DoIMEEnded;
begin
if not FIMEActive then
exit;
FIMEActive := False;
if FOnIMEEnd <> nil then
FOnIMEEnd(FriendEdit);
end; end;
constructor LazSynIme.Create(AOwner: TSynEditBase); constructor LazSynIme.Create(AOwner: TSynEditBase);
@ -350,11 +388,13 @@ begin
end; end;
FInCompose := True; FInCompose := True;
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos; FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
DoIMEStarted;
end; end;
procedure LazSynImeSimple.WMImeEndComposition(var Msg: TMessage); procedure LazSynImeSimple.WMImeEndComposition(var Msg: TMessage);
begin begin
FInCompose := False; FInCompose := False;
DoIMEEnded;
end; end;
procedure LazSynImeSimple.FocusKilled; procedure LazSynImeSimple.FocusKilled;
@ -383,6 +423,16 @@ begin
StopIme(True); StopIme(True);
end; end;
procedure LazSynImeFull.StopIme(Success: Boolean);
begin
inherited StopIme(Success);
{$IFDEF WinIMEFullDeferOverwrite}
if FHasPersistLock then
SelectionObj.DecPersistentLock;
FHasPersistLock := False;
{$ENDIF}
end;
procedure LazSynImeFull.SetImeTempText(const s: string); procedure LazSynImeFull.SetImeTempText(const s: string);
var var
p1, p2: TPoint; p1, p2: TPoint;
@ -412,18 +462,22 @@ begin
FImeBlockSelection.InvalidateLinesMethod := @InvalidateLines; FImeBlockSelection.InvalidateLinesMethod := @InvalidateLines;
FImeBlockSelection2 := TSynEditSelection.Create(ViewedTextBuffer, False); FImeBlockSelection2 := TSynEditSelection.Create(ViewedTextBuffer, False);
FImeBlockSelection2.InvalidateLinesMethod := @InvalidateLines; FImeBlockSelection2.InvalidateLinesMethod := @InvalidateLines;
FImeBlockSelection3 := TSynEditSelection.Create(ViewedTextBuffer, False);
FImeBlockSelection3.InvalidateLinesMethod := @InvalidateLines;
FImeMarkupSelection := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection); FImeMarkupSelection := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection);
FImeMarkupSelection2 := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection2); FImeMarkupSelection2 := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection2);
FImeMarkupSelection3 := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection3);
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection); TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection);
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection2); TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection2);
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection3);
FImeMarkupSelection.MarkupInfo.Clear; FImeMarkupSelection.MarkupInfo.Clear;
FImeMarkupSelection.MarkupInfo.FramePriority := 999; FImeMarkupSelection.MarkupInfo.FramePriority := 999;
FImeMarkupSelection.MarkupInfo.FrameColor := clDefault; FImeMarkupSelection.MarkupInfo.FrameColor := clDefault;
FImeMarkupSelection.MarkupInfo.FrameStyle := slsDotted; FImeMarkupSelection.MarkupInfo.FrameStyle := slsDotted;
FImeMarkupSelection.MarkupInfo.FrameEdges := sfeAround; FImeMarkupSelection.MarkupInfo.FrameEdges := sfeBottom;
FImeMarkupSelection2.MarkupInfo.Clear; FImeMarkupSelection2.MarkupInfo.Clear;
FImeMarkupSelection2.MarkupInfo.FramePriority := 999+1; FImeMarkupSelection2.MarkupInfo.FramePriority := 999+1;
@ -431,6 +485,8 @@ begin
FImeMarkupSelection2.MarkupInfo.FrameStyle := slsSolid; FImeMarkupSelection2.MarkupInfo.FrameStyle := slsSolid;
FImeMarkupSelection2.MarkupInfo.FrameEdges := sfeBottom; FImeMarkupSelection2.MarkupInfo.FrameEdges := sfeBottom;
FImeMarkupSelection3.MarkupInfo.Assign(TSynEdit(FriendEdit).SelectedColor);
TCustomSynEdit(FriendEdit).RegisterStatusChangedHandler(@DoStatusChanged, [scCaretX, scCaretY, scModified]); TCustomSynEdit(FriendEdit).RegisterStatusChangedHandler(@DoStatusChanged, [scCaretX, scCaretY, scModified]);
TCustomSynEdit(FriendEdit).RegisterCommandHandler(@DoOnCommand, nil, [hcfInit]); TCustomSynEdit(FriendEdit).RegisterCommandHandler(@DoOnCommand, nil, [hcfInit]);
TCustomSynEdit(FriendEdit).RegisterBeforeMouseDownHandler(@DoOnMouse); TCustomSynEdit(FriendEdit).RegisterBeforeMouseDownHandler(@DoOnMouse);
@ -444,11 +500,14 @@ begin
TCustomSynEdit(FriendEdit).UnRegisterStatusChangedHandler(@DoStatusChanged); TCustomSynEdit(FriendEdit).UnRegisterStatusChangedHandler(@DoStatusChanged);
TSynEditMarkupManager(MarkupMgr).RemoveMarkUp(FImeMarkupSelection); TSynEditMarkupManager(MarkupMgr).RemoveMarkUp(FImeMarkupSelection);
TSynEditMarkupManager(MarkupMgr).RemoveMarkUp(FImeMarkupSelection2); TSynEditMarkupManager(MarkupMgr).RemoveMarkUp(FImeMarkupSelection2);
TSynEditMarkupManager(MarkupMgr).RemoveMarkUp(FImeMarkupSelection3);
FreeAndNil(FImeMarkupSelection); FreeAndNil(FImeMarkupSelection);
FreeAndNil(FImeMarkupSelection2); FreeAndNil(FImeMarkupSelection2);
FreeAndNil(FImeMarkupSelection3);
FreeAndNil(FImeBlockSelection); FreeAndNil(FImeBlockSelection);
FreeAndNil(FImeBlockSelection2); FreeAndNil(FImeBlockSelection2);
FreeAndNil(FImeBlockSelection3);
inherited Destroy; inherited Destroy;
end; end;
@ -558,6 +617,10 @@ var
ImeCount: LongWord; ImeCount: LongWord;
x, i: Integer; x, i: Integer;
xy: TPoint; xy: TPoint;
grp: Boolean;
{$IFDEF WinIMEFullDeferOverwrite}
sel, sel2: Boolean;
{$ENDIF}
begin begin
{$IFDEF WinIMEDebug} {$IFDEF WinIMEDebug}
s := ''; s := '';
@ -565,10 +628,10 @@ begin
if (Msg.lparam and GCS_COMPREADATTR)<>0 then s := s + 'GCS_COMPREADATTR, '; if (Msg.lparam and GCS_COMPREADATTR)<>0 then s := s + 'GCS_COMPREADATTR, ';
if (Msg.lparam and GCS_COMPREADCLAUSE)<>0 then s := s + 'GCS_COMPREADCLAUSE, '; if (Msg.lparam and GCS_COMPREADCLAUSE)<>0 then s := s + 'GCS_COMPREADCLAUSE, ';
//if (Msg.lparam and GCS_COMPSTR)<>0 then s := s + 'GCS_COMPSTR, '; //if (Msg.lparam and GCS_COMPSTR)<>0 then s := s + 'GCS_COMPSTR, ';
if (Msg.lparam and GCS_COMPATTR)<>0 then s := s + 'GCS_COMPATTR, '; //if (Msg.lparam and GCS_COMPATTR)<>0 then s := s + 'GCS_COMPATTR, ';
if (Msg.lparam and GCS_COMPCLAUSE)<>0 then s := s + 'GCS_COMPCLAUSE, '; //if (Msg.lparam and GCS_COMPCLAUSE)<>0 then s := s + 'GCS_COMPCLAUSE, ';
//if (Msg.lparam and GCS_CURSORPOS)<>0 then s := s + 'GCS_CURSORPOS, '; //if (Msg.lparam and GCS_CURSORPOS)<>0 then s := s + 'GCS_CURSORPOS, ';
//if (Msg.lparam and GCS_DELTASTART)<>0 then s := s + 'GCS_DELTASTART, '; if (Msg.lparam and GCS_DELTASTART)<>0 then s := s + 'GCS_DELTASTART, ';
if (Msg.lparam and GCS_RESULTREADSTR)<>0 then s := s + 'GCS_RESULTREADSTR, '; if (Msg.lparam and GCS_RESULTREADSTR)<>0 then s := s + 'GCS_RESULTREADSTR, ';
if (Msg.lparam and GCS_RESULTREADCLAUSE)<>0 then s := s + 'GCS_RESULTREADCLAUSE, '; if (Msg.lparam and GCS_RESULTREADCLAUSE)<>0 then s := s + 'GCS_RESULTREADCLAUSE, ';
//if (Msg.lparam and GCS_RESULTSTR)<>0 then s := s + 'GCS_RESULTSTR, '; //if (Msg.lparam and GCS_RESULTSTR)<>0 then s := s + 'GCS_RESULTSTR, ';
@ -578,7 +641,7 @@ begin
if s <> '' then debugln(['TCustomSynEdit.WMImeComposition ', s]); if s <> '' then debugln(['TCustomSynEdit.WMImeComposition ', s]);
{$ENDIF} {$ENDIF}
if ((Msg.LParam and (GCS_RESULTSTR or GCS_COMPSTR or GCS_CURSORPOS or GCS_COMPATTR)) = 0) then if (Msg.LParam and (GCS_RESULTSTR or GCS_COMPSTR or GCS_CURSORPOS or GCS_COMPATTR {or GCS_COMPCLAUSE})) = 0 then
exit; exit;
imc := 0; imc := 0;
@ -596,18 +659,36 @@ begin
if ImeCount > 0 then begin if ImeCount > 0 then begin
GetMem(p, ImeCount + 2); GetMem(p, ImeCount + 2);
try try
SetImeTempText('');
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos; CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
grp := ViewedTextBuffer.UndoList.GroupUndo;
ViewedTextBuffer.UndoList.GroupUndo := True;
TCustomSynEdit(FriendEdit).BeginUpdate; TCustomSynEdit(FriendEdit).BeginUpdate;
ViewedTextBuffer.UndoList.CurrentReason := ecImeStr;
{$IFDEF WinIMEFullDeferOverwrite}
if FHasPersistLock then
SelectionObj.DecPersistentLock;
FHasPersistLock := False;
if SelectionObj.SelAvail and (not SelectionObj.Persistent) and (eoOverwriteBlock in TSynEdit(FriendEdit).Options2)
then begin
SelectionObj.SelText := '';
FImeBlockSelection.StartLineBytePos := SelectionObj.StartLineBytePos;
end;
{$ENDIF}
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
ImmGetCompositionStringW(imc, GCS_RESULTSTR, p, ImeCount + 2); ImmGetCompositionStringW(imc, GCS_RESULTSTR, p, ImeCount + 2);
p[ImeCount] := #0; p[ImeCount] := #0;
p[ImeCount+1] := #0; p[ImeCount+1] := #0;
SetImeTempText('');
FImeBlockSelection.SelText := UTF16ToUTF8(PWCHAR(p)); FImeBlockSelection.SelText := UTF16ToUTF8(PWCHAR(p));
FImeBlockSelection.StartLineBytePos := FImeBlockSelection.EndLineBytePos; FImeBlockSelection.StartLineBytePos := FImeBlockSelection.EndLineBytePos;
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos; CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
{$IFnDEF WinIMEFullOverwriteSkipUndo}
FNeedUndoOnCancel := False;
{$ENDIF}
Msg.Result := 1; Msg.Result := 1;
finally finally
TCustomSynEdit(FriendEdit).EndUpdate; TCustomSynEdit(FriendEdit).EndUpdate;
ViewedTextBuffer.UndoList.GroupUndo := grp;
FreeMem(p, ImeCount + 2); FreeMem(p, ImeCount + 2);
end; end;
end; end;
@ -626,7 +707,15 @@ begin
ImmGetCompositionStringW(imc, GCS_COMPSTR, p, ImeCount + 2); ImmGetCompositionStringW(imc, GCS_COMPSTR, p, ImeCount + 2);
p[ImeCount] := #0; p[ImeCount] := #0;
p[ImeCount+1] := #0; p[ImeCount+1] := #0;
{$IFDEF WinIMEFullDeferOverwrite}
sel := (not SelectionObj.IsBackwardSel) and (CompareCarets(SelectionObj.EndLineBytePos, FImeBlockSelection.StartLineBytePos) = 0);
sel2 := SelectionObj.IsBackwardSel and (CompareCarets(SelectionObj.EndLineBytePos, FImeBlockSelection.EndLineBytePos) = 0);
{$ENDIF}
SetImeTempText(UTF16ToUTF8(PWCHAR(p))); SetImeTempText(UTF16ToUTF8(PWCHAR(p)));
{$IFDEF WinIMEFullDeferOverwrite}
if sel then SelectionObj.EndLineBytePos := FImeBlockSelection.StartLineBytePos;
if sel2 then SelectionObj.EndLineBytePos := FImeBlockSelection.EndLineBytePos;
{$ENDIF}
Msg.Result := 1; Msg.Result := 1;
finally finally
FreeMem(p, ImeCount + 2); FreeMem(p, ImeCount + 2);
@ -635,6 +724,12 @@ begin
end; end;
if ((Msg.LParam and GCS_COMPATTR) <> 0) then begin if ((Msg.LParam and GCS_COMPATTR) <> 0) then begin
//ATTR_INPUT = $00; // dotted undurline
//ATTR_TARGET_CONVERTED = $01; // full underline
//ATTR_CONVERTED = $02; // light underline
//ATTR_TARGET_NOTCONVERTED = $03; // Show as selected ?
//ATTR_INPUT_ERROR = $04; // ? none
//ATTR_FIXEDCONVERTED = $05; // ? none
if imc = 0 then if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle); imc := ImmGetContext(FriendEdit.Handle);
ImeCount := ImmGetCompositionStringW(imc, GCS_COMPATTR, nil, 0); ImeCount := ImmGetCompositionStringW(imc, GCS_COMPATTR, nil, 0);
@ -645,10 +740,12 @@ begin
xy := FImeBlockSelection.StartLineBytePos; xy := FImeBlockSelection.StartLineBytePos;
FImeBlockSelection2.StartLineBytePos := xy; FImeBlockSelection2.StartLineBytePos := xy;
FImeBlockSelection2.EndLineBytePos := xy; FImeBlockSelection2.EndLineBytePos := xy;
FImeBlockSelection3.StartLineBytePos := xy;
FImeBlockSelection3.EndLineBytePos := xy;
GetMem(p, ImeCount + 2); GetMem(p, ImeCount + 2);
try try
ImmGetCompositionStringW(imc, GCS_COMPATTR, p, ImeCount + 2); ImmGetCompositionStringW(imc, GCS_COMPATTR, p, ImeCount + 2);
//DebugLn(dbgMemRange(PByte( p), ImeCount)); DebugLn(dbgMemRange(PByte( p), ImeCount));
i := 0; i := 0;
while {%H-}i < ImeCount do begin while {%H-}i < ImeCount do begin
if ord(p[i]) = ATTR_TARGET_CONVERTED then begin if ord(p[i]) = ATTR_TARGET_CONVERTED then begin
@ -666,8 +763,27 @@ begin
end; end;
inc(i); inc(i);
end; end;
break; //break;
end; end;
if ord(p[i]) = ATTR_TARGET_NOTCONVERTED then begin
x := FImeBlockSelection.StartBytePos;
xy.x := x + CharToByte(x, i);
FImeBlockSelection3.StartLineBytePos := xy;
inc(i);
while longword(i) < ImeCount do begin
if (ord(p[i]) <> ATTR_TARGET_NOTCONVERTED) or (i = ImeCount-1) then begin
if (ord(p[i]) = ATTR_TARGET_NOTCONVERTED) then
inc(i);
xy.x := x + CharToByte(x, i);
FImeBlockSelection3.EndLineBytePos := xy;
break;
end;
inc(i);
end;
//break;
end;
inc(i); inc(i);
end; end;
@ -678,6 +794,28 @@ begin
end; end;
end; end;
(*
if ((Msg.LParam and GCS_COMPCLAUSE) <> 0) then begin
// attributes for all chars in any one clause should be the equal.
if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle);
ImeCount := ImmGetCompositionStringW(imc, GCS_COMPCLAUSE, nil, 0);
{$IFDEF WinIMEDebug}
DebugLn(['***** GCS_COMPCLAUSE ', dbgHex(ImeCount)]);
{$ENDIF}
if ImeCount > 0 then begin
GetMem(p, ImeCount + 2);
try
ImmGetCompositionStringW(imc, GCS_COMPCLAUSE, p, ImeCount + 2);
DebugLn(dbgMemRange(PByte( p), ImeCount));
finally
FreeMem(p, ImeCount + 2);
end;
end;
end;
*)
if ((Msg.LParam and GCS_CURSORPOS) <> 0) then begin if ((Msg.LParam and GCS_CURSORPOS) <> 0) then begin
if imc = 0 then if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle); imc := ImmGetContext(FriendEdit.Handle);
@ -705,12 +843,37 @@ end;
procedure LazSynImeFull.WMImeStartComposition(var Msg: TMessage); procedure LazSynImeFull.WMImeStartComposition(var Msg: TMessage);
begin begin
//debugln(['TCustomSynEdit.WMImeStartComposition ']); //debugln(['TCustomSynEdit.WMImeStartComposition ']);
if SelectionObj.SelAvail and (not SelectionObj.Persistent) and (eoOverwriteBlock in TSynEdit(FriendEdit).Options2) then {$IFnDEF WinIMEFullDeferOverwrite}
if SelectionObj.SelAvail and (not SelectionObj.Persistent) and (eoOverwriteBlock in TSynEdit(FriendEdit).Options2)
then begin
{$IFnDEF WinIMEFullOverwriteSkipUndo}
ViewedTextBuffer.UndoList.ForceGroupEnd;
FUndoStamp1 := ViewedTextBuffer.UndoList.PeekItem;
{$ENDIF}
TCustomSynEdit(FriendEdit).BeginUpdate;
ViewedTextBuffer.UndoList.CurrentReason := ecImeStr;
SelectionObj.SelText := ''; SelectionObj.SelText := '';
TCustomSynEdit(FriendEdit).EndUpdate;
{$IFnDEF WinIMEFullOverwriteSkipUndo}
FUndoStamp2 := ViewedTextBuffer.UndoList.PeekItem;
FNeedUndoOnCancel := FUndoStamp1 <> FUndoStamp2;
end
else begin
FNeedUndoOnCancel := False
{$ENDIF}
end;
{$ENDIF}
{$IFDEF WinIMEFullDeferOverwrite}
if not FHasPersistLock then
SelectionObj.IncPersistentLock;
FHasPersistLock := True;
{$ENDIF}
FImeMarkupSelection3.MarkupInfo.Assign(TSynEdit(FriendEdit).SelectedColor);
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos; FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
FInCompose := True; FInCompose := True;
Msg.Result := 1; Msg.Result := 1;
DoIMEStarted;
end; end;
procedure LazSynImeFull.WMImeEndComposition(var Msg: TMessage); procedure LazSynImeFull.WMImeEndComposition(var Msg: TMessage);
@ -718,10 +881,23 @@ begin
//debugln(['TCustomSynEdit.WMImeEndComposition ']); //debugln(['TCustomSynEdit.WMImeEndComposition ']);
SetImeTempText(''); SetImeTempText('');
CaretObj.LineBytePos := FImeBlockSelection.LastLineBytePos; CaretObj.LineBytePos := FImeBlockSelection.LastLineBytePos;
{$IFnDEF WinIMEFullDeferOverwrite}
{$IFnDEF WinIMEFullOverwriteSkipUndo}
if FNeedUndoOnCancel and (ViewedTextBuffer.UndoList.PeekItem = FUndoStamp2) then
TSynEdit(FriendEdit).Undo;
{$ENDIF}
{$ENDIF}
{$IFDEF WinIMEFullDeferOverwrite}
if FHasPersistLock then
SelectionObj.DecPersistentLock;
FHasPersistLock := False;
{$ENDIF}
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos; FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
FImeBlockSelection2.StartLineBytePos := CaretObj.LineBytePos; FImeBlockSelection2.StartLineBytePos := CaretObj.LineBytePos;
FInCompose := False; FInCompose := False;
Msg.Result := 1; Msg.Result := 1;
DoIMEEnded;
end; end;
procedure LazSynImeFull.FocusKilled; procedure LazSynImeFull.FocusKilled;

View File

@ -208,6 +208,7 @@ type
procedure Clear; procedure Clear;
procedure Lock; procedure Lock;
function PopItem: TSynEditUndoGroup; function PopItem: TSynEditUndoGroup;
function PeekItem: TSynEditUndoGroup;
procedure Unlock; procedure Unlock;
function IsLocked: Boolean; function IsLocked: Boolean;
procedure MarkTopAsUnmodified; procedure MarkTopAsUnmodified;
@ -469,6 +470,13 @@ begin
end; end;
end; end;
function TSynEditUndoList.PeekItem: TSynEditUndoGroup;
begin
Result := nil;
if fItems.Count > 0 then
Result := TSynEditUndoGroup(fItems[fItems.Count - 1]);
end;
procedure TSynEditUndoList.SetMaxUndoActions(Value: integer); procedure TSynEditUndoList.SetMaxUndoActions(Value: integer);
begin begin
if Value < 0 then if Value < 0 then