LCL/SynEdit: w32 IME improvements

git-svn-id: trunk@35901 -
This commit is contained in:
martin 2012-03-12 14:00:26 +00:00
parent ad8b5a310d
commit 68b6823948
5 changed files with 861 additions and 225 deletions

1
.gitattributes vendored
View File

@ -2388,6 +2388,7 @@ components/synedit/languages/synmacrorecorder.uk.po svneol=native#text/plain
components/synedit/languages/synmacrorecorder.zh_CN.po svneol=native#text/utf8
components/synedit/lazsyneditmousecmdstypes.pp svneol=native#text/pascal
components/synedit/lazsynedittext.pas svneol=native#text/pascal
components/synedit/lazsynimm.pas svneol=native#text/pascal
components/synedit/lazsyntextarea.pp svneol=native#text/pascal
components/synedit/synbeautifier.pas svneol=native#text/plain
components/synedit/syncompletion.pas svneol=native#text/pascal

View File

@ -2,44 +2,40 @@
This source is only used to compile and install the package.
}
unit allsynedit;
unit allsynedit;
interface
uses
SynBeautifier, SynCompletion, SynDesignStringConstants, SynEdit,
SynEditAutoComplete, SynEditExport, SynEditFoldedView, SynEditHighlighter,
SynEditHighlighterFoldBase, SynEditHighlighterXMLBase, SynEditKeyCmds,
SynEditLazDsgn, SynEditLines, SynEditMarks, SynEditMarkup,
SynEditMarkupBracket, SynEditMarkupCtrlMouseLink, SynEditMarkupHighAll,
SynBeautifier, SynCompletion, SynDesignStringConstants, SynEdit, SynEditAutoComplete,
SynEditExport, SynEditFoldedView, SynEditHighlighter, SynEditHighlighterFoldBase,
SynEditHighlighterXMLBase, SynEditKeyCmds, SynEditLazDsgn, SynEditLines, SynEditMarks,
SynEditMarkup, SynEditMarkupBracket, SynEditMarkupCtrlMouseLink, SynEditMarkupHighAll,
SynEditMarkupSelection, SynEditMarkupSpecialLine, SynEditMarkupWordGroup,
SynEditMiscClasses, SynEditMiscProcs, SynEditMouseCmds, SynEditPlugins,
SynEditPointClasses, SynEditRegexSearch, SynEditSearch, SynEditStrConst,
SynEditTextBase, SynEditTextBuffer, SynEditTextDoubleWidthChars,
SynEditTextTabExpander, SynEditTextTrimmer, SynEditTypes, SynExportHTML,
SynGutter, SynGutterBase, SynGutterChanges, SynGutterCodeFolding,
SynGutterLineNumber, SynGutterLineOverview, SynGutterMarks,
SynEditPointClasses, SynEditRegexSearch, SynEditSearch, SynEditStrConst, SynEditTextBase,
SynEditTextBuffer, SynEditTextDoubleWidthChars, SynEditTextTabExpander, SynEditTextTrimmer,
SynEditTypes, SynExportHTML, SynGutter, SynGutterBase, SynGutterChanges,
SynGutterCodeFolding, SynGutterLineNumber, SynGutterLineOverview, SynGutterMarks,
SynHighlighterAny, SynHighlighterCpp, SynHighlighterCss, SynHighlighterDiff,
SynHighlighterHashEntries, SynHighlighterHTML, SynHighlighterJava,
SynHighlighterJScript, SynHighlighterLFM, SynHighlighterMulti,
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP,
SynHighlighterPosition, SynHighlighterPython, SynHighlighterSQL,
SynHighlighterTeX, synhighlighterunixshellscript, SynHighlighterVB,
SynHighlighterXML, SynMacroRecorder, SynMemo, SynPluginSyncroEdit,
SynPluginSyncronizedEditBase, SynPluginTemplateEdit,
SynPropertyEditObjectList, SynRegExpr, SynTextDrawer,
SynEditMarkupGutterMark, SynHighlighterBat, SynHighlighterIni,
SynEditMarkupSpecialChar, LazSynEditText, LazSynTextArea,
LazSynEditMouseCmdsTypes, SynHighlighterPo, LazarusPackageIntf;
SynHighlighterHashEntries, SynHighlighterHTML, SynHighlighterJava, SynHighlighterJScript,
SynHighlighterLFM, SynHighlighterMulti, SynHighlighterPas, SynHighlighterPerl,
SynHighlighterPHP, SynHighlighterPosition, SynHighlighterPython, SynHighlighterSQL,
SynHighlighterTeX, synhighlighterunixshellscript, SynHighlighterVB, SynHighlighterXML,
SynMacroRecorder, SynMemo, SynPluginSyncroEdit, SynPluginSyncronizedEditBase,
SynPluginTemplateEdit, SynPropertyEditObjectList, SynRegExpr, SynTextDrawer,
SynEditMarkupGutterMark, SynHighlighterBat, SynHighlighterIni, SynEditMarkupSpecialChar,
LazSynEditText, LazSynTextArea, LazSynEditMouseCmdsTypes, SynHighlighterPo, LazSynIMM,
LazarusPackageIntf;
implementation
procedure Register;
procedure Register;
begin
RegisterUnit('SynEdit', @SynEdit.Register);
RegisterUnit('SynEditLazDsgn', @SynEditLazDsgn.Register);
end;
RegisterUnit('SynEdit', @SynEdit.Register);
RegisterUnit('SynEditLazDsgn', @SynEditLazDsgn.Register);
end;
initialization
RegisterPackage('SynEdit', @Register);
RegisterPackage('SynEdit', @Register);
end.

View File

@ -0,0 +1,725 @@
unit LazSynIMM;
{$mode objfpc}{$H+}
{off $DEFINE WinIMEDebug}
interface
uses
windows, imm, Classes, SysUtils, LMessages, LazLoggerBase, LCLType, LCLProc, Controls,
Graphics, SynEditMiscClasses, SynTextDrawer, SynEditPointClasses, SynEditMarkupSelection,
SynEditMarkup, SynEditTypes, SynEditKeyCmds, SynEditTextBase, LazSynEditText;
type
{ LazSynIme }
LazSynIme = class(TSynEditFriend)
private
FInvalidateLinesMethod: TInvalidateLines;
protected
FInCompose: Boolean;
procedure InvalidateLines(FirstLine, LastLine: integer);
procedure StopIme(Success: Boolean);
public
constructor Create(AOwner: TSynEditBase); reintroduce;
procedure WMImeRequest(var Msg: TMessage); virtual;
procedure WMImeNotify(var Msg: TMessage); virtual;
procedure WMImeComposition(var Msg: TMessage); virtual;
procedure WMImeStartComposition(var Msg: TMessage); virtual;
procedure WMImeEndComposition(var Msg: TMessage); virtual;
procedure FocusKilled; virtual;
property InvalidateLinesMethod : TInvalidateLines write FInvalidateLinesMethod;
end;
{ LazSynImeSimple }
LazSynImeSimple = class(LazSynIme)
private
FImeBlockSelection: TSynEditSelection;
FImeWinX, FImeWinY: Integer;
FTextDrawer: TheTextDrawer;
procedure SetTextDrawer(AValue: TheTextDrawer);
procedure UpdateImeWinXY(aX, aY: Integer; aImc: HIMC = 0; aForce: Boolean = False);
procedure UpdateImeWinFont(aImc: HIMC = 0);
procedure DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
procedure DoDrawerFontChanged(Sender: TObject);
procedure DoOnCommand(Sender: TObject; AfterProcessing: boolean; var Handled: boolean;
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
procedure DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
public
constructor Create(AOwner: TSynEditBase);
destructor Destroy; override;
procedure WMImeNotify(var Msg: TMessage); override;
procedure WMImeComposition(var Msg: TMessage); override;
procedure WMImeStartComposition(var Msg: TMessage); override;
procedure WMImeEndComposition(var Msg: TMessage); override;
procedure FocusKilled; override;
property TextDrawer: TheTextDrawer read FTextDrawer write SetTextDrawer;
end;
{ LazSynImeFull }
LazSynImeFull = class(LazSynIme)
private
FImeBlockSelection, FImeBlockSelection2: TSynEditSelection;
FImeMarkupSelection, FImeMarkupSelection2: TSynEditMarkupSelection;
FInImeMsg: Boolean;
FRedoList: TSynEditUndoList;
FUndoList: TSynEditUndoList;
procedure SetImeTempText(const s: string);
procedure DoOnCommand(Sender: TObject; AfterProcessing: boolean; var Handled: boolean;
var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
procedure DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
procedure DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
public
constructor Create(AOwner: TSynEditBase);
destructor Destroy; override;
procedure WMImeRequest(var Msg: TMessage); override;
procedure WMImeNotify(var Msg: TMessage); override;
procedure WMImeComposition(var Msg: TMessage); override;
procedure WMImeStartComposition(var Msg: TMessage); override;
procedure WMImeEndComposition(var Msg: TMessage); override;
procedure FocusKilled; override;
property UndoList: TSynEditUndoList read FUndoList write FUndoList;
property RedoList: TSynEditUndoList read FRedoList write FRedoList;
end;
implementation
uses SynEdit;
{ LazSynIme }
procedure LazSynIme.InvalidateLines(FirstLine, LastLine: integer);
begin
FInvalidateLinesMethod(FirstLine, LastLine);
end;
procedure LazSynIme.StopIme(Success: Boolean);
var
imc: HIMC;
begin
if (not FInCompose) or (not FriendEdit.HandleAllocated) then exit;
imc := ImmGetContext(FriendEdit.Handle);
if (imc <> 0) then begin
if Success then
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0)
else
ImmNotifyIME(imc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ImmReleaseContext(FriendEdit.Handle, imc);
end;
end;
constructor LazSynIme.Create(AOwner: TSynEditBase);
begin
FriendEdit := AOwner;
end;
procedure LazSynIme.WMImeRequest(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeNotify(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeStartComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.WMImeEndComposition(var Msg: TMessage);
begin
end;
procedure LazSynIme.FocusKilled;
begin
end;
{ LazSynImeSimple }
procedure LazSynImeSimple.DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
begin
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix);
if Changes * [scCaretX, scCaretY] <> [] then
StopIme(False);
end;
procedure LazSynImeSimple.DoDrawerFontChanged(Sender: TObject);
var
imc: HIMC;
begin
if not FriendEdit.HandleAllocated then
exit;
imc := ImmGetContext(FriendEdit.Handle);
if (imc <> 0) then begin
UpdateImeWinFont(imc);
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix, imc);
ImmReleaseContext(FriendEdit.Handle, imc);
end;
end;
procedure LazSynImeSimple.DoOnCommand(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
begin
StopIme(True);
end;
procedure LazSynImeSimple.DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
StopIme(True);
end;
procedure LazSynImeSimple.UpdateImeWinXY(aX, aY: Integer; aImc: HIMC; aForce: Boolean);
var
cf: CompositionForm;
imc: HIMC;
begin
if not FriendEdit.HandleAllocated then exit;
if (not aForce) and (aX = FImeWinX) and (aY = FImeWinY) then exit;
FImeWinX := aX;
FImeWinY := aY;
cf.dwStyle := CFS_POINT;
cf.ptCurrentPos := Point(aX, aY);
if aImc = 0 then
imc := ImmGetContext(FriendEdit.Handle)
else
imc := aImc;
if (imc <> 0) then begin
ImmSetCompositionWindow(imc, @cf);
if (aImc = 0) then
ImmReleaseContext(FriendEdit.Handle, imc);
end;
end;
procedure LazSynImeSimple.SEtTextDrawer(AValue: TheTextDrawer);
begin
if FTextDrawer = AValue then Exit;
if FTextDrawer <> nil then
FTextDrawer.UnRegisterOnFontChangeHandler(@DoDrawerFontChanged);
FTextDrawer := AValue;
if FTextDrawer <> nil then
FTextDrawer.RegisterOnFontChangeHandler(@DoDrawerFontChanged);
end;
procedure LazSynImeSimple.UpdateImeWinFont(aImc: HIMC);
var
imc: HIMC;
logFont: TLogFont;
begin
if not FriendEdit.HandleAllocated then exit;
if aImc = 0 then
imc := ImmGetContext(FriendEdit.Handle)
else
imc := aImc;
if (imc <> 0) then begin
GetObject(FriendEdit.Font.Handle, SizeOf(TLogFont), @logFont);
ImmSetCompositionFontA(imc, @logFont);
if (aImc = 0) then
ImmReleaseContext(FriendEdit.Handle, imc);
end;
end;
constructor LazSynImeSimple.Create(AOwner: TSynEditBase);
begin
inherited Create(AOwner);
FImeBlockSelection := TSynEditSelection.Create(ViewedTextBuffer, False);
FImeBlockSelection.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
TCustomSynEdit(FriendEdit).RegisterStatusChangedHandler(@DoStatusChanged, [scCaretX, scCaretY, scLeftChar, scTopLine, scModified]);
TCustomSynEdit(FriendEdit).RegisterCommandHandler(@DoOnCommand, nil, [hcfInit]);
TCustomSynEdit(FriendEdit).RegisterBeforeMouseDownHandler(@DoOnMouse);
end;
destructor LazSynImeSimple.Destroy;
begin
TextDrawer := nil;
FreeAndNil(FImeBlockSelection);
TCustomSynEdit(FriendEdit).UnregisterBeforeMouseDownHandler(@DoOnMouse);
TCustomSynEdit(FriendEdit).UnregisterCommandHandler(@DoOnCommand);
TCustomSynEdit(FriendEdit).UnRegisterStatusChangedHandler(@DoStatusChanged);
inherited Destroy;
end;
procedure LazSynImeSimple.WMImeNotify(var Msg: TMessage);
var
imc: HIMC;
{$IFDEF WinIMEDebug}
s: String;
{$ENDIF}
begin
{$IFDEF WinIMEDebug}
case msg.wParam of
IMN_CLOSESTATUSWINDOW: s:= 'IMN_CLOSESTATUSWINDOW, ';
IMN_OPENSTATUSWINDOW: s:= 'IMN_OPENSTATUSWINDOW, ';
IMN_CHANGECANDIDATE: s:= 'IMN_CHANGECANDIDATE, ';
IMN_CLOSECANDIDATE: s:= 'IMN_CLOSECANDIDATE, ';
IMN_OPENCANDIDATE: s:= 'IMN_OPENCANDIDATE, ';
IMN_SETCONVERSIONMODE: s:= 'IMN_SETCONVERSIONMODE, ';
IMN_SETSENTENCEMODE: s:= 'IMN_SETSENTENCEMODE, ';
IMN_SETOPENSTATUS: s:= 'IMN_SETOPENSTATUS, ';
IMN_SETCANDIDATEPOS: s:= 'IMN_SETCANDIDATEPOS, ';
IMN_SETCOMPOSITIONFONT: s:= 'IMN_SETCOMPOSITIONFONT, ';
IMN_SETCOMPOSITIONWINDOW: s:= 'IMN_SETCOMPOSITIONWINDOW, ';
IMN_SETSTATUSWINDOWPOS: s:= 'IMN_SETSTATUSWINDOWPOS, ';
IMN_GUIDELINE: s:= 'IMN_GUIDELINE, ';
IMN_PRIVATE: s:= 'IMN_PRIVATE, ';
end;
debugln(['TCustomSynEdit.WMImeNotify ',s,' ', dbgHex(Msg.lParam), ' , ', dbgHex(Msg.wParam)]);
{$ENDIF}
case Msg.WParam of
IMN_SETOPENSTATUS: begin
imc := ImmGetContext(FriendEdit.Handle);
if (imc <> 0) then begin
UpdateImeWinFont(imc);
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix, imc, True);
ImmReleaseContext(FriendEdit.Handle, imc);
end;
end;
IMN_CLOSESTATUSWINDOW:
StopIme(True);
end;
end;
procedure LazSynImeSimple.WMImeComposition(var Msg: TMessage);
var
imc: HIMC;
ImeCount: LongWord;
p: PChar;
begin
if ((Msg.LParam and GCS_RESULTSTR) <> 0) then begin
imc := ImmGetContext(FriendEdit.Handle);
try
if imc <> 0 then begin
ImeCount := ImmGetCompositionStringW(imc, GCS_RESULTSTR, nil, 0);
{$IFDEF WinIMEDebug}
DebugLn(['--- GCS_RESULTSTR ', dbgHex(ImeCount)]);
{$ENDIF}
if ImeCount > 0 then begin
GetMem(p, ImeCount + 2);
try
TCustomSynEdit(FriendEdit).BeginUpdate;
ImmGetCompositionStringW(imc, GCS_RESULTSTR, p, ImeCount + 2);
p[ImeCount] := #0;
p[ImeCount+1] := #0;
FImeBlockSelection.SelText := UTF16ToUTF8(PWCHAR(p));
FImeBlockSelection.StartLineBytePos := FImeBlockSelection.EndLineBytePos;
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
Msg.Result := 1;
finally
FreeMem(p, ImeCount + 2);
TCustomSynEdit(FriendEdit).EndUpdate;
end;
end;
end;
finally
ImmReleaseContext(FriendEdit.Handle, imc);
end;
end;
end;
procedure LazSynImeSimple.WMImeStartComposition(var Msg: TMessage);
var
imc: HIMC;
begin
//debugln(['TCustomSynEdit.WMImeStartComposition ']);
imc := ImmGetContext(FriendEdit.Handle);
if (imc <> 0) then begin
UpdateImeWinFont(imc);
UpdateImeWinXY(TCustomSynEdit(FriendEdit).CaretXPix, TCustomSynEdit(FriendEdit).CaretYPix, imc, True);
ImmReleaseContext(FriendEdit.Handle, imc);
end;
FInCompose := True;
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
end;
procedure LazSynImeSimple.WMImeEndComposition(var Msg: TMessage);
begin
FInCompose := False;
end;
procedure LazSynImeSimple.FocusKilled;
begin
StopIme(True);
end;
{ LazSynImeFull }
procedure LazSynImeFull.DoOnCommand(Sender: TObject; AfterProcessing: boolean;
var Handled: boolean; var Command: TSynEditorCommand; var AChar: TUTF8Char; Data: pointer;
HandlerData: pointer);
begin
StopIme(True);
end;
procedure LazSynImeFull.DoOnMouse(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
StopIme(True);
end;
procedure LazSynImeFull.DoStatusChanged(Sender: TObject; Changes: TSynStatusChanges);
begin
if FInImeMsg then exit;
StopIme(True);
end;
procedure LazSynImeFull.SetImeTempText(const s: string);
var
p1, p2: TPoint;
f: Boolean;
begin
p1 := FImeBlockSelection.FirstLineBytePos;
f := FInImeMsg;
FInImeMsg := True;
fUndoList.Lock;
fRedoList.Lock;
FImeBlockSelection.SelText := s;
fUndoList.Unlock;
fRedoList.Unlock;
FInImeMsg := f;
p2 := FImeBlockSelection.FirstLineBytePos;
FImeBlockSelection.StartLineBytePos := p1;
FImeBlockSelection.EndLineBytePos := p2;
end;
constructor LazSynImeFull.Create(AOwner: TSynEditBase);
begin
inherited Create(AOwner);
FImeBlockSelection := TSynEditSelection.Create(ViewedTextBuffer, False);
FImeBlockSelection.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
FImeBlockSelection2 := TSynEditSelection.Create(ViewedTextBuffer, False);
FImeBlockSelection2.InvalidateLinesMethod := {$IFDEF FPC}@{$ENDIF}InvalidateLines;
FImeMarkupSelection := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection);
FImeMarkupSelection2 := TSynEditMarkupSelection.Create(FriendEdit, FImeBlockSelection2);
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection);
TSynEditMarkupManager(MarkupMgr).AddMarkUp(FImeMarkupSelection2);
FImeMarkupSelection.MarkupInfo.Clear;
FImeMarkupSelection.MarkupInfo.FramePriority := 999;
FImeMarkupSelection.MarkupInfo.FrameColor := clDefault;
FImeMarkupSelection.MarkupInfo.FrameStyle := slsDotted;
FImeMarkupSelection.MarkupInfo.FrameEdges := sfeAround;
FImeMarkupSelection2.MarkupInfo.Clear;
FImeMarkupSelection2.MarkupInfo.FramePriority := 999+1;
FImeMarkupSelection2.MarkupInfo.FrameColor := clDefault;
FImeMarkupSelection2.MarkupInfo.FrameStyle := slsSolid;
FImeMarkupSelection2.MarkupInfo.FrameEdges := sfeBottom;
TCustomSynEdit(FriendEdit).RegisterStatusChangedHandler(@DoStatusChanged, [scCaretX, scCaretY, scModified]);
TCustomSynEdit(FriendEdit).RegisterCommandHandler(@DoOnCommand, nil, [hcfInit]);
TCustomSynEdit(FriendEdit).RegisterBeforeMouseDownHandler(@DoOnMouse);
end;
destructor LazSynImeFull.Destroy;
begin
TCustomSynEdit(FriendEdit).UnregisterBeforeMouseDownHandler(@DoOnMouse);
TCustomSynEdit(FriendEdit).UnregisterCommandHandler(@DoOnCommand);
TCustomSynEdit(FriendEdit).UnRegisterStatusChangedHandler(@DoStatusChanged);
FreeAndNil(FImeBlockSelection);
FreeAndNil(FImeBlockSelection2);
inherited Destroy;
end;
procedure LazSynImeFull.WMImeRequest(var Msg: TMessage);
var
{$IFDEF WinIMEDebug}
s: String;
{$ENDIF}
cp: PIMECHARPOSITION;
p1: TPoint;
CWidth: TPhysicalCharWidths;
i, x: integer;
begin
{$IFDEF WinIMEDebug}
case msg.wParam of
IMR_COMPOSITIONWINDOW: s:= 'IMR_COMPOSITIONWINDOW, ';
IMR_CANDIDATEWINDOW: s:= 'IMR_CANDIDATEWINDOW, ';
IMR_COMPOSITIONFONT: s:= 'IMR_COMPOSITIONFONT, ';
IMR_RECONVERTSTRING: s:= 'IMR_RECONVERTSTRING, ';
IMR_CONFIRMRECONVERTSTRING: s:= 'IMR_CONFIRMRECONVERTSTRING, ';
IMR_DOCUMENTFEED: s:= 'IMR_DOCUMENTFEED, ';
end;
if s <> '' then debugln(['TCustomSynEdit.WMImeRequest ', s,' ' , dbgHex(Msg.lParam)]);
{$ENDIF}
case msg.wParam of
IMR_QUERYCHARPOSITION: begin
cp := PIMECHARPOSITION(Msg.lParam);
p1 := FImeBlockSelection.StartLineBytePos;
CWidth := ViewedTextBuffer.GetPhysicalCharWidths(FImeBlockSelection.StartLinePos - 1);
x := p1.x - 1;
i := cp^.dwCharPos;
while (i > 0) and (x < length(CWidth)) do begin
inc(x);
while (x < length(CWidth)) and (CWidth[x] = 0) do
inc(x);
dec(i);
end;
p1.x := x + i + 1;
p1 := FriendEdit.ClientToScreen(TCustomSynEdit(FriendEdit).RowColumnToPixels(ViewedTextBuffer.LogicalToPhysicalPos(p1)));
cp^.pt.y := p1.y;
cp^.pt.x := p1.x;
cp^.cLineHeight := TCustomSynEdit(FriendEdit).LineHeight;
cp^.rcDocument.TopLeft := FriendEdit.ClientToScreen(FriendEdit.ClientRect.TopLeft);
cp^.rcDocument.BottomRight := FriendEdit.ClientToScreen(FriendEdit.ClientRect.BottomRight);
{$IFDEF WinIMEDebug}
debugln(['--- TCustomSynEdit.WMImeRequest ** IMR_QUERYCHARPOSITION ', dbgs(cp^.dwCharPos), ' ', dbgs(x),' ', dbgs(p1.x)]);
{$ENDIF}
Msg.Result := 1;
end;
end;
end;
procedure LazSynImeFull.WMImeNotify(var Msg: TMessage);
{$IFDEF WinIMEDebug}
var
s: String;
{$ENDIF}
begin
{$IFDEF WinIMEDebug}
case msg.wParam of
IMN_CLOSESTATUSWINDOW: s:= 'IMN_CLOSESTATUSWINDOW, ';
IMN_OPENSTATUSWINDOW: s:= 'IMN_OPENSTATUSWINDOW, ';
IMN_CHANGECANDIDATE: s:= 'IMN_CHANGECANDIDATE, ';
IMN_CLOSECANDIDATE: s:= 'IMN_CLOSECANDIDATE, ';
IMN_OPENCANDIDATE: s:= 'IMN_OPENCANDIDATE, ';
IMN_SETCONVERSIONMODE: s:= 'IMN_SETCONVERSIONMODE, ';
IMN_SETSENTENCEMODE: s:= 'IMN_SETSENTENCEMODE, ';
IMN_SETOPENSTATUS: s:= 'IMN_SETOPENSTATUS, ';
IMN_SETCANDIDATEPOS: s:= 'IMN_SETCANDIDATEPOS, ';
IMN_SETCOMPOSITIONFONT: s:= 'IMN_SETCOMPOSITIONFONT, ';
IMN_SETCOMPOSITIONWINDOW: s:= 'IMN_SETCOMPOSITIONWINDOW, ';
IMN_SETSTATUSWINDOWPOS: s:= 'IMN_SETSTATUSWINDOWPOS, ';
IMN_GUIDELINE: s:= 'IMN_GUIDELINE, ';
IMN_PRIVATE: s:= 'IMN_PRIVATE, ';
end;
debugln(['TCustomSynEdit.WMImeNotify ',s,' ', dbgHex(Msg.lParam), ' , ', dbgHex(Msg.wParam)]);
{$ENDIF}
end;
procedure LazSynImeFull.WMImeComposition(var Msg: TMessage);
var
CWidth: TPhysicalCharWidths;
function CharToByte(AStart, AChars: integer): integer;
begin
if length(CWidth) = 0 then
CWidth := ViewedTextBuffer.GetPhysicalCharWidths(FImeBlockSelection.StartLinePos - 1);
dec(AStart);
Result := AStart;
while (AChars > 0) and (Result < length(CWidth)) do begin
inc(Result);
while (Result < length(CWidth)) and (CWidth[Result] = 0) do
inc(Result);
dec(AChars);
end;
Result := Result - AStart + AChars;
end;
var
{$IFDEF WinIMEDebug}
s: String;
{$ENDIF}
imc: HIMC;
p: PChar;
ImeCount: LongWord;
x, i: Integer;
xy: TPoint;
begin
{$IFDEF WinIMEDebug}
s := '';
if (Msg.lparam and GCS_COMPREADSTR)<>0 then s := s + 'GCS_COMPREADSTR, ';
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_COMPSTR)<>0 then s := s + 'GCS_COMPSTR, ';
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_CURSORPOS)<>0 then s := s + 'GCS_CURSORPOS, ';
//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_RESULTREADCLAUSE)<>0 then s := s + 'GCS_RESULTREADCLAUSE, ';
//if (Msg.lparam and GCS_RESULTSTR)<>0 then s := s + 'GCS_RESULTSTR, ';
if (Msg.lparam and GCS_RESULTCLAUSE)<>0 then s := s + 'GCS_RESULTCLAUSE, ';
if (Msg.lparam and CS_INSERTCHAR)<>0 then s := s + ' ** CS_INSERTCHAR, ';
if (Msg.lparam and CS_NOMOVECARET)<>0 then s := s + ' ** CS_NOMOVECARET, ';
if s <> '' then debugln(['TCustomSynEdit.WMImeComposition ', s]);
{$ENDIF}
if ((Msg.LParam and (GCS_RESULTSTR or GCS_COMPSTR or GCS_CURSORPOS or GCS_COMPATTR)) = 0) then
exit;
imc := 0;
FInImeMsg := True;
SetLength(CWidth, 0);
try
if ((Msg.LParam and GCS_RESULTSTR) <> 0) then begin
if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle);
ImeCount := ImmGetCompositionStringW(imc, GCS_RESULTSTR, nil, 0);
{$IFDEF WinIMEDebug}
DebugLn(['--- GCS_RESULTSTR ', dbgHex(ImeCount)]);
{$ENDIF}
if ImeCount > 0 then begin
GetMem(p, ImeCount + 2);
try
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
TCustomSynEdit(FriendEdit).BeginUpdate;
ImmGetCompositionStringW(imc, GCS_RESULTSTR, p, ImeCount + 2);
p[ImeCount] := #0;
p[ImeCount+1] := #0;
SetImeTempText('');
FImeBlockSelection.SelText := UTF16ToUTF8(PWCHAR(p));
FImeBlockSelection.StartLineBytePos := FImeBlockSelection.EndLineBytePos;
CaretObj.LineBytePos := FImeBlockSelection.StartLineBytePos;
Msg.Result := 1;
finally
TCustomSynEdit(FriendEdit).EndUpdate;
FreeMem(p, ImeCount + 2);
end;
end;
end;
if ((Msg.LParam and GCS_COMPSTR) <> 0) then begin
if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle);
ImeCount := ImmGetCompositionStringW(imc, GCS_COMPSTR, nil, 0);
{$IFDEF WinIMEDebug}
DebugLn(['--- GCS_COMPSTR ', dbgHex(ImeCount)]);
{$ENDIF}
if ImeCount > 0 then begin
GetMem(p, ImeCount + 2);
try
ImmGetCompositionStringW(imc, GCS_COMPSTR, p, ImeCount + 2);
p[ImeCount] := #0;
p[ImeCount+1] := #0;
SetImeTempText(UTF16ToUTF8(PWCHAR(p)));
Msg.Result := 1;
finally
FreeMem(p, ImeCount + 2);
end;
end;
end;
if ((Msg.LParam and GCS_COMPATTR) <> 0) then begin
if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle);
ImeCount := ImmGetCompositionStringW(imc, GCS_COMPATTR, nil, 0);
{$IFDEF WinIMEDebug}
DebugLn(['***** GCS_COMPATTR ', dbgHex(ImeCount)]);
{$ENDIF}
if ImeCount > 0 then begin
xy := FImeBlockSelection.StartLineBytePos;
FImeBlockSelection2.StartLineBytePos := xy;
FImeBlockSelection2.EndLineBytePos := xy;
GetMem(p, ImeCount + 2);
try
ImmGetCompositionStringW(imc, GCS_COMPATTR, p, ImeCount + 2);
//DebugLn(dbgMemRange(PByte( p), ImeCount));
i := 0;
while i < ImeCount do begin
if ord(p[i]) = ATTR_TARGET_CONVERTED then begin
x := FImeBlockSelection.StartBytePos;
xy.x := x + CharToByte(x, i);
FImeBlockSelection2.StartLineBytePos := xy;
inc(i);
while i < ImeCount do begin
if (ord(p[i]) <> ATTR_TARGET_CONVERTED) or (i = ImeCount-1) then begin
if (ord(p[i]) = ATTR_TARGET_CONVERTED) then
inc(i);
xy.x := x + CharToByte(x, i);
FImeBlockSelection2.EndLineBytePos := xy;
break;
end;
inc(i);
end;
break;
end;
inc(i);
end;
Msg.Result := 1;
finally
FreeMem(p, ImeCount + 2);
end;
end;
end;
if ((Msg.LParam and GCS_CURSORPOS) <> 0) then begin
if imc = 0 then
imc := ImmGetContext(FriendEdit.Handle);
ImeCount := ImmGetCompositionStringW(imc, GCS_CURSORPOS, nil, 0);
{$IFDEF WinIMEDebug}
DebugLn(['--- GCS_CURSORPOS ', dbgs(ImeCount)]);
{$ENDIF}
if ImeCount >= 0 then begin
ImeCount := ImeCount and $ffff;
x := FImeBlockSelection.StartBytePos;
x := x + CharToByte(x, ImeCount);
CaretObj.CharPos := ViewedTextBuffer.LogicalToPhysicalPos(Point(x, FImeBlockSelection.StartLinePos)).x;
end;
end;
finally
if imc <> 0 then
ImmReleaseContext(FriendEdit.Handle, imc);
FInImeMsg := False;
end;
inherited;
end;
procedure LazSynImeFull.WMImeStartComposition(var Msg: TMessage);
var
imc: HIMC;
begin
//debugln(['TCustomSynEdit.WMImeStartComposition ']);
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
FInCompose := True;
Msg.Result := 1;
end;
procedure LazSynImeFull.WMImeEndComposition(var Msg: TMessage);
begin
//debugln(['TCustomSynEdit.WMImeEndComposition ']);
SetImeTempText('');
CaretObj.LineBytePos := FImeBlockSelection.LastLineBytePos;
FImeBlockSelection.StartLineBytePos := CaretObj.LineBytePos;
FImeBlockSelection2.StartLineBytePos := CaretObj.LineBytePos;
FInCompose := False;
Msg.Result := 1;
end;
procedure LazSynImeFull.FocusKilled;
begin
StopIme(True);
end;
end.

View File

@ -38,7 +38,6 @@ Known Issues:
-Font.CharSet
-THintWindow
-DragAcceptFiles
-Font DBCS / MBCS double, multi byte character set
-------------------------------------------------------------------------------}
@ -46,6 +45,7 @@ unit SynEdit;
{$IFDEF Windows}
{$IFnDEF WithoutWinIME}
{$DEFINE WinIME}
{$DEFINE WinIMEFull}
{$ENDIF}
{$ENDIF}
@ -73,16 +73,13 @@ interface
uses
{$IFDEF WinIME}
windows, imm,
LazSynIMM,
{$ENDIF}
{$IFDEF USE_UTF8BIDI_LCL}
FreeBIDI, utf8bidi,
{$ENDIF}
Types, LCLIntf, LCLType, LMessages, LazUTF8, LCLProc,
SysUtils, Classes, Messages, Controls, Graphics, Forms, StdCtrls, ExtCtrls, Menus,
{$IFDEF SYN_MBCSSUPPORT}
Imm,
{$ENDIF}
SynEditTypes, SynEditSearch, SynEditKeyCmds, SynEditMouseCmds, SynEditMiscProcs,
SynEditPointClasses, SynBeautifier, SynEditMarks,
// Markup
@ -121,26 +118,6 @@ const
// maximum scroll range
MAX_SCROLL = 32767;
{$IFDEF SYN_MBCSSUPPORT}
{$IFNDEF SYN_COMPILER_4_UP}
{Windows.pas in D4}
const
C3_NONSPACING = 1; { nonspacing character }
C3_DIACRITIC = 2; { diacritic mark }
C3_VOWELMARK = 4; { vowel mark }
C3_SYMBOL = 8; { symbols }
C3_KATAKANA = $0010; { katakana character }
C3_HIRAGANA = $0020; { hiragana character }
C3_HALFWIDTH = $0040; { half width character }
C3_FULLWIDTH = $0080; { full width character }
C3_IDEOGRAPH = $0100; { ideographic character }
C3_KASHIDA = $0200; { Arabic kashida character }
C3_LEXICAL = $0400; { lexical character }
C3_ALPHA = $8000; { any linguistic char (C1_ALPHA) }
C3_NOTAPPLICABLE = 0; { ctype 3 is not applicable }
{$ENDIF}
{$ENDIF}
type
TSynEditMarkupClass = SynEditMarkup.TSynEditMarkupClass;
TSynReplaceAction = (raCancel, raSkip, raReplace, raReplaceAll);
@ -395,6 +372,16 @@ type
{ TLazSynKeyDownEventList }
{ TLazSynMouseDownEventList }
TLazSynMouseDownEventList = Class(TMethodList)
public
procedure CallMouseDownHandlers(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;
{ TLazSynKeyDownEventList }
TLazSynKeyDownEventList = Class(TMethodList)
public
procedure CallKeyDownHandlers(Sender: TObject; var Key: Word; Shift: TShiftState);
@ -437,11 +424,12 @@ type
procedure SelAvailChange(Sender: TObject);
private
{$IFDEF WinIME}
FImeWinX, FImeWinY: Integer;
procedure UpdateImeWinXY(aX, aY: Integer; aImc: HIMC = 0; aForce: Boolean = False);
procedure UpdateImeWinFont(aImc: HIMC = 0);
//procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
FImeHandler: LazSynIme;
procedure WMImeRequest(var Msg: TMessage); message WM_IME_REQUEST;
procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY;
procedure WMImeStartComposition(var Msg: TMessage); message WM_IME_STARTCOMPOSITION;
procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
procedure WMImeEndComposition(var Msg: TMessage); message WM_IME_ENDCOMPOSITION;
{$ENDIF}
procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;
procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
@ -473,10 +461,6 @@ type
fMarkupSpecialChar : TSynEditMarkupSpecialChar;
fFontDummy: TFont;
FLastSetFontSize: Integer;
{$IFDEF SYN_MBCSSUPPORT}
fImeCount: Integer;
fMBCSStepAside: Boolean;
{$ENDIF}
fInserting: Boolean;
fLastMouseCaret: TPoint; // Char; physical (screen)
FLastMousePoint: TPoint; // Pixel
@ -543,6 +527,7 @@ type
fTSearch: TSynEditSearch;
fHookedCommandHandlers: TList;
FHookedKeyTranslationList: TSynHookedKeyTranslationList;
FMouseDownEventList: TLazSynMouseDownEventList;
FKeyDownEventList: TLazSynKeyDownEventList;
FKeyPressEventList: TLazSynKeyPressEventList;
FUtf8KeyPressEventList: TLazSynUtf8KeyPressEventList;
@ -813,10 +798,6 @@ type
function GetTopView : Integer;
procedure SetTopView(AValue : Integer);
procedure MarkListChange(Sender: TSynEditMark; Changes: TSynEditMarkChangeReasons);
{$IFDEF SYN_MBCSSUPPORT}
procedure MBCSGetSelRangeInLineWhenColumnSelectionMode(const s: string;
var ColFrom, ColTo: Integer);
{$ENDIF}
procedure NotifyHookedCommandHandlers(var Command: TSynEditorCommand;
var AChar: TUTF8Char; Data: pointer; ATime: THookedCommandFlag); virtual;
function NextWordLogicalPos(ABoundary: TLazSynWordBoundary = swbWordBegin; WordEndForDelete : Boolean = false): TPoint;
@ -1000,6 +981,9 @@ type
procedure RegisterStatusChangedHandler(AStatusChangeProc: TStatusChangeEvent; AChanges: TSynStatusChanges);
procedure UnRegisterStatusChangedHandler(AStatusChangeProc: TStatusChangeEvent);
procedure RegisterBeforeMouseDownHandler(AHandlerProc: TMouseEvent);
procedure UnregisterBeforeMouseDownHandler(AHandlerProc: TMouseEvent);
procedure RegisterBeforeKeyDownHandler(AHandlerProc: TKeyEvent);
procedure UnregisterBeforeKeyDownHandler(AHandlerProc: TKeyEvent);
procedure RegisterBeforeKeyPressHandler(AHandlerProc: TKeyPressEvent);
@ -1373,7 +1357,6 @@ type
constructor Create(AEvent: THookedCommandEvent; AData: pointer; AFlags: THookedCommandFlags);
end;
{ TSynEditUndoCaret }
function TSynEditUndoCaret.IsEqualContent(AnItem: TSynEditUndoItem): Boolean;
@ -1989,6 +1972,18 @@ begin
fMarkupManager.Caret := FCaret;
fMarkupManager.InvalidateLinesMethod := @InvalidateLines;
{$IFDEF WinIME}
{$IFDEF WinIMEFull}
FImeHandler := LazSynImeFull.Create(Self);
LazSynImeFull(FImeHandler).UndoList := fUndoList;
LazSynImeFull(FImeHandler).RedoList := fRedoList;
{$ELSE}
FImeHandler := LazSynImeSimple.Create(Self);
LazSynImeSimple(FImeHandler).TextDrawer := FTextDrawer;
{$ENDIF}
{$ENDIF}
FImeHandler.InvalidateLinesMethod := @InvalidateLines;
fFontDummy.Name := SynDefaultFontName;
fFontDummy.Height := SynDefaultFontHeight;
fFontDummy.Pitch := SynDefaultFontPitch;
@ -2045,10 +2040,6 @@ begin
FMouseActionSearchHandlerList := TSynEditMouseActionSearchList.Create;
FMouseActionExecHandlerList := TSynEditMouseActionExecList.Create;
{$IFDEF SYN_MBCSSUPPORT}
fImeCount := 0;
fMBCSStepAside := False;
{$ENDIF}
fWantTabs := False;
fTabWidth := 8;
FOldTopView := 1;
@ -2302,6 +2293,9 @@ begin
FreeAndNil(FRightGutter);
FreeAndNil(FPaintLineColor);
FreeAndNil(FPaintLineColor2);
{$IFDEF WinIME}
FreeAndNil(FImeHandler);
{$ENDIF}
FreeAndNil(fTextDrawer);
FreeAndNil(fFontDummy);
DestroyMarkList; // before detach from FLines
@ -2323,6 +2317,7 @@ begin
FBeautifier := nil;
FreeAndNil(FDefaultBeautifier);
FreeAndNil(FKeyDownEventList);
FreeAndNil(FMouseDownEventList);
FreeAndNil(FKeyPressEventList);
FreeAndNil(FUtf8KeyPressEventList);
inherited Destroy;
@ -2519,91 +2514,29 @@ begin
end;
{$IFDEF WinIME}
procedure TCustomSynEdit.UpdateImeWinXY(aX, aY: Integer; aImc: HIMC; aForce: Boolean);
var
cf: CompositionForm;
imc: HIMC;
procedure TCustomSynEdit.WMImeRequest(var Msg: TMessage);
begin
if not HandleAllocated then exit;
if (not aForce) and (aX = FImeWinX) and (aY = FImeWinY) then exit;
FImeWinX := aX;
FImeWinY := aY;
cf.dwStyle := CFS_POINT;
cf.ptCurrentPos := Point(aX, aY);
if aImc = 0 then
imc := ImmGetContext(Handle)
else
imc := aImc;
if (imc <> 0) then begin
ImmSetCompositionWindow(imc, @cf);
if (aImc = 0) then
ImmReleaseContext(Handle, imc);
end;
FImeHandler.WMImeRequest(Msg);
end;
procedure TCustomSynEdit.UpdateImeWinFont(aImc: HIMC);
var
imc: HIMC;
logFont: TLogFont;
begin
if not HandleAllocated then exit;
if aImc = 0 then
imc := ImmGetContext(Handle)
else
imc := aImc;
if (imc <> 0) then begin
GetObject(Font.Handle, SizeOf(TLogFont), @logFont);
ImmSetCompositionFontW(imc, @logFont);
if (aImc = 0) then
ImmReleaseContext(Handle, imc);
end;
end;
(*
procedure TCustomSynEdit.WMImeComposition(var Msg: TMessage);
var
imc: HIMC;
p: PChar;
begin
if ((Msg.LParam and GCS_RESULTSTR) <> 0) then begin
imc := ImmGetContext(Handle);
try
fImeCount := ImmGetCompositionString(imc, GCS_RESULTSTR, nil, 0);
GetMem(p, fImeCount + 1);
try
ImmGetCompositionString(imc, GCS_RESULTSTR, p, fImeCount + 1);
p[fImeCount] := #0;
CommandProcessor(ecImeStr, #0, p);
finally
FreeMem(p, fImeCount + 1);
end;
finally
ImmReleaseContext(Handle, imc);
end;
end;
inherited;
end;
*)
procedure TCustomSynEdit.WMImeNotify(var Msg: TMessage);
var
imc: HIMC;
logFont: TLogFont;
begin
debugln(['TCustomSynEdit.WMImeNotify ', dbgHex(Msg.lParam), ' , ', dbgHex(Msg.wParam)]);
FImeHandler.WMImeNotify(Msg);
end;
case Msg.WParam of
IMN_SETOPENSTATUS: begin
imc := ImmGetContext(Handle);
if (imc <> 0) then begin
UpdateImeWinFont(imc);
UpdateImeWinXY(CaretXPix, CaretYPix, imc, True);
ImmReleaseContext(Handle, imc);
end;
end;
end;
inherited;
procedure TCustomSynEdit.WMImeComposition(var Msg: TMessage);
begin
FImeHandler.WMImeComposition(Msg);
end;
procedure TCustomSynEdit.WMImeStartComposition(var Msg: TMessage);
begin
FImeHandler.WMImeStartComposition(Msg);
end;
procedure TCustomSynEdit.WMImeEndComposition(var Msg: TMessage);
begin
FImeHandler.WMImeEndComposition(Msg);
end;
{$ENDIF}
@ -3199,6 +3132,10 @@ begin
//DebugLn(['TCustomSynEdit.MouseDown START Mouse=',X,',',Y,' Caret=',CaretX,',',CaretY,', BlockBegin=',BlockBegin.X,',',BlockBegin.Y,' BlockEnd=',BlockEnd.X,',',BlockEnd.Y]);
Exclude(FStateFlags, sfHideCursor);
FInMouseClickEvent := True;
if FMouseDownEventList <> nil then
FMouseDownEventList.CallMouseDownHandlers(Self, Button, Shift, X, Y);
if (X>=ClientWidth-ScrollBarWidth) or (Y>=ClientHeight-ScrollBarWidth) then
begin
inherited MouseDown(Button, Shift, X, Y);
@ -4307,9 +4244,6 @@ begin
x := CaretXPix;
y := CaretYPix;
FScreenCaret.DisplayPos := Point(x, y);
{$IFDEF WinIME}
UpdateImeWinXY(x, y);
{$ENDIF}
end;
end;
@ -4484,6 +4418,9 @@ begin
end;
if FHideSelection and SelAvail then
Invalidate;
{$IFDEF WinIME}
FImeHandler.FocusKilled;
{$ENDIF}
inherited;
end;
@ -6000,11 +5937,6 @@ var
WP: TPoint;
Caret: TPoint;
CaretNew: TPoint;
{$IFDEF SYN_MBCSSUPPORT}
StartOfBlock: TPoint;
i: integer;
s: string;
{$ENDIF}
counter: Integer;
LogCounter: integer;
LogCaretXY: TPoint;
@ -6511,47 +6443,6 @@ begin
begin
DefaultSelectionMode := SEL_MODE[Command];
end;
{$IFDEF SYN_MBCSSUPPORT}
ecImeStr:
if not ReadOnly then begin
SetString(s, PChar(Data), StrLen(Data));
if SelAvail then begin
SetSelTextExternal(s);
end else begin
Temp := LineText;
Len := Length(Temp);
if Len < CaretX then
Temp := Temp + StringOfChar(' ', CaretX - Len);
try
FCaret.IncForcePastEOL;
StartOfBlock := CaretXY;
// Processing of case character covers on LeadByte.
Len := Length(s);
if not fInserting then begin
i := (CaretX + Len);
if (ByteType(Temp, i) = mbTrailByte) then begin
s := s + Temp[i - 1];
Helper := Copy(Temp, CaretX, Len - 1);
end else
Helper := Copy(Temp, CaretX, Len);
Delete(Temp, CaretX, Len);
end;
Insert(s, Temp, CaretX);
CaretX := (CaretX + Len);
FTheLinesView[CaretY - 1] := Temp;
if fInserting then
Helper := '';
fUndoList.AddChange(crInsert, StartOfBlock,
LogicalCaretXY,
Helper, smNormal);
if CaretX >= LeftChar + CharsInWindow then
LeftChar := LeftChar + min(25, CharsInWindow - 1);
finally
FCaret.DecForcePastEOL;
end;
end;
end;
{$ENDIF}
EcFoldLevel1..EcFoldLevel9:
FoldAll(Command - EcFoldLevel1);
EcFoldLevel0:
@ -7185,28 +7076,6 @@ begin
end;
end;
{$IFDEF SYN_MBCSSUPPORT}
procedure TCustomSynEdit.MBCSGetSelRangeInLineWhenColumnSelectionMode(
const s: string; var ColFrom, ColTo: Integer);
// --ColFrom and ColTo are in/out parameter. their range
// will be from 1 to MaxInt.
// --a range of selection means: Copy(s, ColFrom, ColTo - ColFrom);
// be careful what ColTo means.
var
Len: Integer;
begin
Len := Length(s);
if (0 < ColFrom) and (ColFrom <= Len) then
if mbTrailByte = ByteType(s, ColFrom) then
Inc(ColFrom);
if (0 < ColTo) and (ColTo <= Len) then
if mbTrailByte = ByteType(s, ColTo) then
Inc(ColTo);
end;
{$ENDIF}
function TCustomSynEdit.IsPointInSelection(Value: TPoint): boolean;
var
ptBegin, ptEnd: TPoint;
@ -7590,10 +7459,6 @@ begin
FScreenCaret.UnLock;
end;
UpdateScrollBars;
{$IFDEF WinIME}
UpdateImeWinFont;
{$ENDIF}
//debugln('TCustomSynEdit.RecalcCharExtent UseUTF8=',dbgs(UseUTF8),' Font.CanUTF8=',dbgs(Font.CanUTF8));
end;
@ -8627,6 +8492,19 @@ begin
TSynStatusChangedHandlerList(FStatusChangedList).Remove(AStatusChangeProc);
end;
procedure TCustomSynEdit.RegisterBeforeMouseDownHandler(AHandlerProc: TMouseEvent);
begin
if FMouseDownEventList = nil then
FMouseDownEventList := TLazSynMouseDownEventList.Create;
FMouseDownEventList.Add(TMethod(AHandlerProc));
end;
procedure TCustomSynEdit.UnregisterBeforeMouseDownHandler(AHandlerProc: TMouseEvent);
begin
if FMouseDownEventList <> nil then
FMouseDownEventList.Remove(TMethod(AHandlerProc));
end;
procedure TCustomSynEdit.RegisterBeforeKeyDownHandler(AHandlerProc: TKeyEvent);
begin
if FKeyDownEventList = nil then
@ -8953,6 +8831,18 @@ begin
TKeyPressEvent(Items[i])(Sender, Key);
end;
{ TLazSynMouseDownEventList }
procedure TLazSynMouseDownEventList.CallMouseDownHandlers(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i: LongInt;
begin
i:=Count;
while NextDownIndex(i) do
TMouseEvent(Items[i])(Sender, Button, Shift, X, Y);
end;
{ TLazSynKeyDownEventList }
procedure TLazSynKeyDownEventList.CallKeyDownHandlers(Sender: TObject; var Key: Word;

View File

@ -1095,6 +1095,10 @@ begin
begin
{IME Windows the composition has finished}
WindowInfo^.IMEComposed:=True;
LMessage.Msg := Msg;
LMessage.WParam := WParam;
LMessage.LParam := LParam;
//WinProcess := False;
end;
WM_CANCELMODE:
begin
@ -2184,12 +2188,20 @@ begin
Assigned(Win32WidgetSet.FOnAsyncSocketMsg) then
Exit(Win32WidgetSet.FOnAsyncSocketMsg(WParam, LParam))
end;
WM_IME_NOTIFY:
WM_IME_COMPOSITION,
WM_IME_COMPOSITIONFULL,
WM_IME_CONTROL,
//WM_IME_ENDCOMPOSITION,
WM_IME_NOTIFY,
WM_IME_REQUEST,
WM_IME_SELECT,
WM_IME_SETCONTEXT,
WM_IME_STARTCOMPOSITION:
begin
LMessage.Msg := Msg;
LMessage.WParam := WParam;
LMessage.LParam := LParam;
//WinProcess := False;
WinProcess := False;
end;
else
// pass along user defined messages
@ -2446,6 +2458,18 @@ begin
WinProcess := LMKey.Result = 0;
WParam := LMKey.CharCode;
end;
WM_IME_COMPOSITION,
WM_IME_COMPOSITIONFULL,
WM_IME_CONTROL,
WM_IME_ENDCOMPOSITION,
WM_IME_NOTIFY,
WM_IME_REQUEST,
WM_IME_SELECT,
WM_IME_SETCONTEXT,
WM_IME_STARTCOMPOSITION:
begin
WinProcess := LMessage.Result = 0;
end;
else
case Msg of
WM_LBUTTONDOWN, WM_LBUTTONUP: