You've already forked lazarus-ccr
richmemo: win32 + holding selection direction for GetXXX operations (that are strictly selection based).
reduce the number of redundant OnChange events, only call them on real event happening. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5117 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -250,9 +250,25 @@ begin
|
|||||||
Result:=false; // we need to catch just notifications,
|
Result:=false; // we need to catch just notifications,
|
||||||
// any other message should be handled in a "Default" manner
|
// any other message should be handled in a "Default" manner
|
||||||
// So, default result is false;
|
// So, default result is false;
|
||||||
hdr:=PNMHDR(LParam);
|
|
||||||
case Msg of
|
case Msg of
|
||||||
|
WM_COMMAND: begin
|
||||||
|
case HIWORD(WParam) of
|
||||||
|
EN_UPDATE: begin
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/bb761687(v=vs.85).aspx
|
||||||
|
// EN_UPDATE is just a notification, that the edit is to be redrawn
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
EN_CHANGE: begin
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/hh768384(v=vs.85).aspx
|
||||||
|
// Despite of what documentation claims (WM_NOTIFY), EN_CHANGE is notified by WM_COMMAND
|
||||||
|
if Assigned(AWinControl) and (AWinControl is TCustomRichMemo) then
|
||||||
|
TIntCustomRichMemo(AWinControl).Change;
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
WM_NOTIFY: begin
|
WM_NOTIFY: begin
|
||||||
|
hdr:=PNMHDR(LParam);
|
||||||
case hdr^.code of
|
case hdr^.code of
|
||||||
EN_SELCHANGE:
|
EN_SELCHANGE:
|
||||||
begin
|
begin
|
||||||
@ -539,7 +555,7 @@ begin
|
|||||||
FinishCreateWindow(AWinControl, Params, false);
|
FinishCreateWindow(AWinControl, Params, false);
|
||||||
|
|
||||||
eventmask := SendMessage(AWinControl.Handle, EM_GETEVENTMASK, 0, 0);
|
eventmask := SendMessage(AWinControl.Handle, EM_GETEVENTMASK, 0, 0);
|
||||||
eventmask := eventmask or ENM_SELCHANGE or ENM_LINK;
|
eventmask := eventmask or ENM_SELCHANGE or ENM_LINK or ENM_CHANGE;
|
||||||
SendMessage(AWinControl.Handle, EM_SETEVENTMASK, 0, eventmask);
|
SendMessage(AWinControl.Handle, EM_SETEVENTMASK, 0, eventmask);
|
||||||
|
|
||||||
// Limitless text. However, the value would be overwritten by a consequent
|
// Limitless text. However, the value would be overwritten by a consequent
|
||||||
@ -581,8 +597,7 @@ end;
|
|||||||
class function TWin32WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl;
|
class function TWin32WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl;
|
||||||
TextStart: Integer; var Params: TIntFontParams): Boolean;
|
TextStart: Integer; var Params: TIntFontParams): Boolean;
|
||||||
var
|
var
|
||||||
OrigStart : Integer;
|
Orig : TCHARRANGE;
|
||||||
OrigLen : Integer;
|
|
||||||
eventmask : LongWord;
|
eventmask : LongWord;
|
||||||
begin
|
begin
|
||||||
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
||||||
@ -592,12 +607,14 @@ begin
|
|||||||
InitFontParams(Params);
|
InitFontParams(Params);
|
||||||
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
|
|
||||||
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
||||||
|
|
||||||
LockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle);
|
LockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||||
|
|
||||||
|
RichEditManager.GetSelRange(AWinControl.Handle, Orig);
|
||||||
|
|
||||||
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
||||||
Result := RichEditManager.GetSelectedTextStyle(AWinControl.Handle, Params );
|
Result := RichEditManager.GetSelectedTextStyle(AWinControl.Handle, Params );
|
||||||
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
||||||
|
RichEditManager.SetSelRange(AWinControl.Handle, Orig);
|
||||||
UnlockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle, false);
|
UnlockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle, false);
|
||||||
|
|
||||||
RichEditManager.SetEventMask(AWinControl.Handle,eventmask);
|
RichEditManager.SetEventMask(AWinControl.Handle,eventmask);
|
||||||
@ -669,8 +686,7 @@ class function TWin32WSCustomRichMemo.GetStyleRange(
|
|||||||
const AWinControl: TWinControl; TextStart: Integer; var RangeStart,
|
const AWinControl: TWinControl; TextStart: Integer; var RangeStart,
|
||||||
RangeLen: Integer): Boolean;
|
RangeLen: Integer): Boolean;
|
||||||
var
|
var
|
||||||
OrigStart : Integer;
|
Orig : TCharRange;
|
||||||
OrigLen : Integer;
|
|
||||||
eventmask : longword;
|
eventmask : longword;
|
||||||
begin
|
begin
|
||||||
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
||||||
@ -679,17 +695,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
|
|
||||||
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
||||||
LockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle);
|
LockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||||
|
|
||||||
|
RichEditManager.GetSelRange(AWinControl.Handle, Orig);
|
||||||
|
|
||||||
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
||||||
try
|
try
|
||||||
Result := RichEditManager.GetStyleRange(AWinControl.Handle, TextStart, RangeStart, RangeLen);
|
Result := RichEditManager.GetStyleRange(AWinControl.Handle, TextStart, RangeStart, RangeLen);
|
||||||
except
|
except
|
||||||
end;
|
end;
|
||||||
|
|
||||||
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
RichEditManager.SetSelRange(AWinControl.Handle, Orig);
|
||||||
UnlockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle, false);
|
UnlockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle, false);
|
||||||
|
|
||||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||||
@ -724,8 +740,7 @@ end;
|
|||||||
class function TWin32WSCustomRichMemo.GetTextUIParams(const AWinControl: TWinControl; TextStart: Integer;
|
class function TWin32WSCustomRichMemo.GetTextUIParams(const AWinControl: TWinControl; TextStart: Integer;
|
||||||
var ui: TTextUIParam): Boolean;
|
var ui: TTextUIParam): Boolean;
|
||||||
var
|
var
|
||||||
OrigStart : Integer;
|
Orig : TCHARRANGE;
|
||||||
OrigLen : Integer;
|
|
||||||
eventmask : Integer;
|
eventmask : Integer;
|
||||||
begin
|
begin
|
||||||
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
||||||
@ -734,12 +749,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
||||||
|
|
||||||
LockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
LockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||||
|
|
||||||
|
RichEditManager.GetSelRange(AWinControl.Handle, Orig);
|
||||||
|
|
||||||
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
||||||
RichEditManager.GetTextUIStyle(AWinControl.Handle, ui);
|
RichEditManager.GetTextUIStyle(AWinControl.Handle, ui);
|
||||||
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
||||||
|
RichEditManager.SetSelRange(AWinControl.Handle, Orig);
|
||||||
UnlockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
UnlockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||||
|
|
||||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||||
@ -774,6 +791,8 @@ begin
|
|||||||
|
|
||||||
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||||
|
|
||||||
|
LockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||||
|
|
||||||
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
||||||
case para.wAlignment of
|
case para.wAlignment of
|
||||||
PFA_CENTER: AAlign:=paCenter;
|
PFA_CENTER: AAlign:=paCenter;
|
||||||
@ -782,6 +801,7 @@ begin
|
|||||||
else
|
else
|
||||||
AAlign:=paLeft;
|
AAlign:=paLeft;
|
||||||
end;
|
end;
|
||||||
|
UnlockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle );
|
||||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||||
|
|
||||||
Result:=true;
|
Result:=true;
|
||||||
@ -1063,6 +1083,7 @@ class function TWin32WSCustomRichMemo.GetSubText(
|
|||||||
var utxt: UnicodeString): Boolean;
|
var utxt: UnicodeString): Boolean;
|
||||||
var
|
var
|
||||||
eventmask : Integer;
|
eventmask : Integer;
|
||||||
|
Orig : TCharRange;
|
||||||
OrigStart : Integer;
|
OrigStart : Integer;
|
||||||
OrigLen : Integer;
|
OrigLen : Integer;
|
||||||
NeedLock : Boolean;
|
NeedLock : Boolean;
|
||||||
@ -1078,7 +1099,7 @@ begin
|
|||||||
NeedLock := (OrigStart <> TextStart) or (OrigLen <> TextLen);
|
NeedLock := (OrigStart <> TextStart) or (OrigLen <> TextLen);
|
||||||
if NeedLock then begin
|
if NeedLock then begin
|
||||||
LockRedraw( TCustomRichMemo(AWinControl), Hnd);
|
LockRedraw( TCustomRichMemo(AWinControl), Hnd);
|
||||||
RichEditManager.SetSelection(Hnd, TextStart, TextLen);
|
RichEditManager.GetSelRange(Hnd, Orig);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
isUnicode:=AsUnicode;
|
isUnicode:=AsUnicode;
|
||||||
@ -1089,7 +1110,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if NeedLock then begin
|
if NeedLock then begin
|
||||||
RichEditManager.SetSelection(Hnd, OrigStart, OrigLen);
|
RichEditManager.SetSelRange(Hnd, Orig);
|
||||||
UnlockRedraw( TCustomRichMemo(AWinControl), Hnd);
|
UnlockRedraw( TCustomRichMemo(AWinControl), Hnd);
|
||||||
end;
|
end;
|
||||||
RichEditManager.SetEventMask(Hnd, eventmask);
|
RichEditManager.SetEventMask(Hnd, eventmask);
|
||||||
|
@ -173,6 +173,11 @@ type
|
|||||||
class function GetStyleRange(RichEditWnd: Handle; TextStart: Integer; var RangeStart, RangeLen: Integer): Boolean; virtual;
|
class function GetStyleRange(RichEditWnd: Handle; TextStart: Integer; var RangeStart, RangeLen: Integer): Boolean; virtual;
|
||||||
class procedure GetSelection(RichEditWnd: Handle; var TextStart, TextLen: Integer); virtual;
|
class procedure GetSelection(RichEditWnd: Handle; var TextStart, TextLen: Integer); virtual;
|
||||||
class procedure SetSelection(RichEditWnd: Handle; TextStart, TextLen: Integer); virtual;
|
class procedure SetSelection(RichEditWnd: Handle; TextStart, TextLen: Integer); virtual;
|
||||||
|
|
||||||
|
// WARNING: GetSelRange, is causing changes in Selection!
|
||||||
|
class procedure GetSelRange(RichEditWnd: Handle; var sr: TCHARRANGE); virtual;
|
||||||
|
class procedure SetSelRange(RichEditWnd: Handle; const sr: TCHARRANGE); virtual;
|
||||||
|
|
||||||
class procedure SetHideSelection(RichEditWnd: Handle; AValue: Boolean); virtual;
|
class procedure SetHideSelection(RichEditWnd: Handle; AValue: Boolean); virtual;
|
||||||
class function LoadRichText(RichEditWnd: Handle; ASrc: TStream): Boolean; virtual;
|
class function LoadRichText(RichEditWnd: Handle; ASrc: TStream): Boolean; virtual;
|
||||||
class function SaveRichText(RichEditWnd: Handle; ADst: TStream): Boolean; virtual;
|
class function SaveRichText(RichEditWnd: Handle; ADst: TStream): Boolean; virtual;
|
||||||
@ -647,6 +652,38 @@ begin
|
|||||||
SendMessage(RichEditWnd, EM_EXSETSEL, 0, PtrInt(@Range));
|
SendMessage(RichEditWnd, EM_EXSETSEL, 0, PtrInt(@Range));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class procedure TRichEditManager.GetSelRange(RichEditWnd: Handle; var sr: TCHARRANGE);
|
||||||
|
var
|
||||||
|
st: Integer;
|
||||||
|
begin
|
||||||
|
sr.cpMax := 0;
|
||||||
|
sr.cpMin := 0;
|
||||||
|
st:=0;
|
||||||
|
SendMessage(RichEditWnd, EM_EXGETSEL, 0, PtrInt(@sr));
|
||||||
|
// EM_EXGETSEL - always returns min and max, in the math order
|
||||||
|
// (where math is lower, than max)
|
||||||
|
// This, however, doesn't match the seletion direction.
|
||||||
|
// Selection direction is done by either mouse (right to left) and (left to right)
|
||||||
|
// or by holding SHIFT key and moving left to right.
|
||||||
|
// EM_EXSETSEL - repsects the specified sr.cpMax and sr.cpMin order
|
||||||
|
|
||||||
|
// Resetting the selection.
|
||||||
|
// This is a bit hacky, BUT the selection would be reset
|
||||||
|
// towards the direction of the selection
|
||||||
|
SendMessage(RichEditWnd, EM_SETSEL, -1, 0);
|
||||||
|
SendMessage(RichEditWnd, EM_GETSEL, WPARAM(@st), 0);
|
||||||
|
|
||||||
|
if st=sr.cpMin then begin // right-to-left selection
|
||||||
|
sr.cpMin:=sr.cpMax;
|
||||||
|
sr.cpMax:=st;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TRichEditManager.SetSelRange(RichEditWnd: Handle; const sr: TCHARRANGE);
|
||||||
|
begin
|
||||||
|
SendMessage(RichEditWnd, EM_EXSETSEL, 0, PtrInt(@sr));
|
||||||
|
end;
|
||||||
|
|
||||||
class procedure TRichEditManager.SetHideSelection(RichEditWnd: Handle; AValue: Boolean);
|
class procedure TRichEditManager.SetHideSelection(RichEditWnd: Handle; AValue: Boolean);
|
||||||
var
|
var
|
||||||
style : LResult;
|
style : LResult;
|
||||||
@ -720,9 +757,9 @@ class procedure TRichEditManager.SetText(RichEditWnd:Handle;
|
|||||||
var
|
var
|
||||||
AnsiText : AnsiString;
|
AnsiText : AnsiString;
|
||||||
txt : PChar;
|
txt : PChar;
|
||||||
s, l : Integer;
|
sr : TCHARRANGE;
|
||||||
begin
|
begin
|
||||||
GetSelection(RichEditWnd, s, l);
|
GetSelRange(RichEditWnd, sr);
|
||||||
SetSelection(RichEditWnd, TextStart, ReplaceLength);
|
SetSelection(RichEditWnd, TextStart, ReplaceLength);
|
||||||
|
|
||||||
txt:=nil;
|
txt:=nil;
|
||||||
@ -735,7 +772,7 @@ begin
|
|||||||
SendMessageA(RichEditWnd, EM_REPLACESEL, 0, LPARAM(txt));
|
SendMessageA(RichEditWnd, EM_REPLACESEL, 0, LPARAM(txt));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
SetSelection(RichEditWnd, s, l);
|
SetSelRange(RichEditWnd, sr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TRichEditManager.GetTextW(RichEditWnd: Handle;
|
class function TRichEditManager.GetTextW(RichEditWnd: Handle;
|
||||||
@ -801,9 +838,9 @@ end;
|
|||||||
class procedure TRichEditManager.GetPara2(RichEditWnd: Handle; TextStart: Integer;
|
class procedure TRichEditManager.GetPara2(RichEditWnd: Handle; TextStart: Integer;
|
||||||
var para: PARAFORMAT2);
|
var para: PARAFORMAT2);
|
||||||
var
|
var
|
||||||
s, l : Integer;
|
sr : TCHARRANGE;
|
||||||
begin
|
begin
|
||||||
GetSelection(RichEditWnd, s, l);
|
GetSelRange(RichEditWnd, sr);
|
||||||
|
|
||||||
SetSelection(RichEditWnd, TextStart, 0);
|
SetSelection(RichEditWnd, TextStart, 0);
|
||||||
|
|
||||||
@ -811,18 +848,20 @@ begin
|
|||||||
para.cbSize:=sizeof(para);
|
para.cbSize:=sizeof(para);
|
||||||
SendMessagea(RichEditWnd, EM_GETPARAFORMAT, 0, LPARAM(@para));
|
SendMessagea(RichEditWnd, EM_GETPARAFORMAT, 0, LPARAM(@para));
|
||||||
|
|
||||||
SetSelection(RichEditWnd, s, l);
|
SetSelRange(RichEditWnd, sr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class procedure TRichEditManager.SetPara2(RichEditWnd: Handle;
|
class procedure TRichEditManager.SetPara2(RichEditWnd: Handle;
|
||||||
TextStart, TextLen: Integer; const para: PARAFORMAT2);
|
TextStart, TextLen: Integer; const para: PARAFORMAT2);
|
||||||
var
|
var
|
||||||
s, l : Integer;
|
sr : TCHARRANGE;
|
||||||
begin
|
begin
|
||||||
GetSelection(RichEditWnd, s, l);
|
GetSelRange(RichEditWnd, sr);
|
||||||
|
|
||||||
SetSelection(RichEditWnd, TextStart, TextLen);
|
SetSelection(RichEditWnd, TextStart, TextLen);
|
||||||
SendMessagea(RichEditWnd, EM_SETPARAFORMAT, 0, LPARAM(@para));
|
SendMessagea(RichEditWnd, EM_SETPARAFORMAT, 0, LPARAM(@para));
|
||||||
SetSelection(RichEditWnd, s, l);
|
|
||||||
|
SetSelRange(RichEditWnd, sr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TRichEditManager.Find(RichEditWnd: THandle; const ANiddle: WideString; const ASearch: TIntSearchOpt): Integer; overload;
|
class function TRichEditManager.Find(RichEditWnd: THandle; const ANiddle: WideString; const ASearch: TIntSearchOpt): Integer; overload;
|
||||||
|
Reference in New Issue
Block a user