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,
|
||||
// any other message should be handled in a "Default" manner
|
||||
// So, default result is false;
|
||||
hdr:=PNMHDR(LParam);
|
||||
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
|
||||
hdr:=PNMHDR(LParam);
|
||||
case hdr^.code of
|
||||
EN_SELCHANGE:
|
||||
begin
|
||||
@ -539,7 +555,7 @@ begin
|
||||
FinishCreateWindow(AWinControl, Params, false);
|
||||
|
||||
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);
|
||||
|
||||
// Limitless text. However, the value would be overwritten by a consequent
|
||||
@ -581,8 +597,7 @@ end;
|
||||
class function TWin32WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl;
|
||||
TextStart: Integer; var Params: TIntFontParams): Boolean;
|
||||
var
|
||||
OrigStart : Integer;
|
||||
OrigLen : Integer;
|
||||
Orig : TCHARRANGE;
|
||||
eventmask : LongWord;
|
||||
begin
|
||||
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
||||
@ -591,13 +606,15 @@ begin
|
||||
end;
|
||||
InitFontParams(Params);
|
||||
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||
|
||||
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
||||
|
||||
LockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||
|
||||
RichEditManager.GetSelRange(AWinControl.Handle, Orig);
|
||||
|
||||
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
||||
Result := RichEditManager.GetSelectedTextStyle(AWinControl.Handle, Params );
|
||||
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
||||
|
||||
RichEditManager.SetSelRange(AWinControl.Handle, Orig);
|
||||
UnlockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle, false);
|
||||
|
||||
RichEditManager.SetEventMask(AWinControl.Handle,eventmask);
|
||||
@ -669,8 +686,7 @@ class function TWin32WSCustomRichMemo.GetStyleRange(
|
||||
const AWinControl: TWinControl; TextStart: Integer; var RangeStart,
|
||||
RangeLen: Integer): Boolean;
|
||||
var
|
||||
OrigStart : Integer;
|
||||
OrigLen : Integer;
|
||||
Orig : TCharRange;
|
||||
eventmask : longword;
|
||||
begin
|
||||
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
||||
@ -679,17 +695,17 @@ begin
|
||||
end;
|
||||
|
||||
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||
|
||||
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
||||
LockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||
|
||||
RichEditManager.GetSelRange(AWinControl.Handle, Orig);
|
||||
|
||||
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
||||
try
|
||||
Result := RichEditManager.GetStyleRange(AWinControl.Handle, TextStart, RangeStart, RangeLen);
|
||||
except
|
||||
end;
|
||||
|
||||
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
||||
RichEditManager.SetSelRange(AWinControl.Handle, Orig);
|
||||
UnlockRedraw(TCustomRichMemo(AWinControl), AWinControl.Handle, false);
|
||||
|
||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||
@ -724,8 +740,7 @@ end;
|
||||
class function TWin32WSCustomRichMemo.GetTextUIParams(const AWinControl: TWinControl; TextStart: Integer;
|
||||
var ui: TTextUIParam): Boolean;
|
||||
var
|
||||
OrigStart : Integer;
|
||||
OrigLen : Integer;
|
||||
Orig : TCHARRANGE;
|
||||
eventmask : Integer;
|
||||
begin
|
||||
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
||||
@ -734,12 +749,14 @@ begin
|
||||
end;
|
||||
|
||||
eventmask := RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
||||
|
||||
LockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||
|
||||
RichEditManager.GetSelRange(AWinControl.Handle, Orig);
|
||||
|
||||
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
||||
RichEditManager.GetTextUIStyle(AWinControl.Handle, ui);
|
||||
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
||||
|
||||
RichEditManager.SetSelRange(AWinControl.Handle, Orig);
|
||||
UnlockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||
|
||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||
@ -774,6 +791,8 @@ begin
|
||||
|
||||
eventmask:=RichEditManager.SetEventMask(AWinControl.Handle, 0);
|
||||
|
||||
LockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle);
|
||||
|
||||
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
||||
case para.wAlignment of
|
||||
PFA_CENTER: AAlign:=paCenter;
|
||||
@ -782,6 +801,7 @@ begin
|
||||
else
|
||||
AAlign:=paLeft;
|
||||
end;
|
||||
UnlockRedraw( TCustomRichMemo(AWinControl), AWinControl.Handle );
|
||||
RichEditManager.SetEventMask(AWinControl.Handle, eventmask);
|
||||
|
||||
Result:=true;
|
||||
@ -1063,6 +1083,7 @@ class function TWin32WSCustomRichMemo.GetSubText(
|
||||
var utxt: UnicodeString): Boolean;
|
||||
var
|
||||
eventmask : Integer;
|
||||
Orig : TCharRange;
|
||||
OrigStart : Integer;
|
||||
OrigLen : Integer;
|
||||
NeedLock : Boolean;
|
||||
@ -1078,7 +1099,7 @@ begin
|
||||
NeedLock := (OrigStart <> TextStart) or (OrigLen <> TextLen);
|
||||
if NeedLock then begin
|
||||
LockRedraw( TCustomRichMemo(AWinControl), Hnd);
|
||||
RichEditManager.SetSelection(Hnd, TextStart, TextLen);
|
||||
RichEditManager.GetSelRange(Hnd, Orig);
|
||||
end;
|
||||
|
||||
isUnicode:=AsUnicode;
|
||||
@ -1089,7 +1110,7 @@ begin
|
||||
end;
|
||||
|
||||
if NeedLock then begin
|
||||
RichEditManager.SetSelection(Hnd, OrigStart, OrigLen);
|
||||
RichEditManager.SetSelRange(Hnd, Orig);
|
||||
UnlockRedraw( TCustomRichMemo(AWinControl), Hnd);
|
||||
end;
|
||||
RichEditManager.SetEventMask(Hnd, eventmask);
|
||||
|
@ -172,7 +172,12 @@ type
|
||||
|
||||
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 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 function LoadRichText(RichEditWnd: Handle; ASrc: TStream): Boolean; virtual;
|
||||
class function SaveRichText(RichEditWnd: Handle; ADst: TStream): Boolean; virtual;
|
||||
@ -647,6 +652,38 @@ begin
|
||||
SendMessage(RichEditWnd, EM_EXSETSEL, 0, PtrInt(@Range));
|
||||
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);
|
||||
var
|
||||
style : LResult;
|
||||
@ -720,9 +757,9 @@ class procedure TRichEditManager.SetText(RichEditWnd:Handle;
|
||||
var
|
||||
AnsiText : AnsiString;
|
||||
txt : PChar;
|
||||
s, l : Integer;
|
||||
sr : TCHARRANGE;
|
||||
begin
|
||||
GetSelection(RichEditWnd, s, l);
|
||||
GetSelRange(RichEditWnd, sr);
|
||||
SetSelection(RichEditWnd, TextStart, ReplaceLength);
|
||||
|
||||
txt:=nil;
|
||||
@ -735,7 +772,7 @@ begin
|
||||
SendMessageA(RichEditWnd, EM_REPLACESEL, 0, LPARAM(txt));
|
||||
end;
|
||||
|
||||
SetSelection(RichEditWnd, s, l);
|
||||
SetSelRange(RichEditWnd, sr);
|
||||
end;
|
||||
|
||||
class function TRichEditManager.GetTextW(RichEditWnd: Handle;
|
||||
@ -801,9 +838,9 @@ end;
|
||||
class procedure TRichEditManager.GetPara2(RichEditWnd: Handle; TextStart: Integer;
|
||||
var para: PARAFORMAT2);
|
||||
var
|
||||
s, l : Integer;
|
||||
sr : TCHARRANGE;
|
||||
begin
|
||||
GetSelection(RichEditWnd, s, l);
|
||||
GetSelRange(RichEditWnd, sr);
|
||||
|
||||
SetSelection(RichEditWnd, TextStart, 0);
|
||||
|
||||
@ -811,18 +848,20 @@ begin
|
||||
para.cbSize:=sizeof(para);
|
||||
SendMessagea(RichEditWnd, EM_GETPARAFORMAT, 0, LPARAM(@para));
|
||||
|
||||
SetSelection(RichEditWnd, s, l);
|
||||
SetSelRange(RichEditWnd, sr);
|
||||
end;
|
||||
|
||||
class procedure TRichEditManager.SetPara2(RichEditWnd: Handle;
|
||||
TextStart, TextLen: Integer; const para: PARAFORMAT2);
|
||||
var
|
||||
s, l : Integer;
|
||||
sr : TCHARRANGE;
|
||||
begin
|
||||
GetSelection(RichEditWnd, s, l);
|
||||
GetSelRange(RichEditWnd, sr);
|
||||
|
||||
SetSelection(RichEditWnd, TextStart, TextLen);
|
||||
SendMessagea(RichEditWnd, EM_SETPARAFORMAT, 0, LPARAM(@para));
|
||||
SetSelection(RichEditWnd, s, l);
|
||||
|
||||
SetSelRange(RichEditWnd, sr);
|
||||
end;
|
||||
|
||||
class function TRichEditManager.Find(RichEditWnd: THandle; const ANiddle: WideString; const ASearch: TIntSearchOpt): Integer; overload;
|
||||
|
Reference in New Issue
Block a user