2009-06-20 20:54:09 +00:00
|
|
|
{
|
|
|
|
win32richmemo.pas
|
|
|
|
|
|
|
|
Author: Dmitry 'skalogryz' Boyarintsev
|
|
|
|
|
|
|
|
*****************************************************************************
|
|
|
|
* *
|
|
|
|
* This file is part of the Lazarus Component Library (LCL) *
|
|
|
|
* *
|
|
|
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
|
|
|
* for details about the copyright. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
|
|
* *
|
|
|
|
*****************************************************************************
|
|
|
|
}
|
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
unit Win32RichMemo;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
// Win32 headers
|
2014-11-12 04:38:24 +00:00
|
|
|
Windows, RichEdit,
|
2009-06-04 19:38:39 +00:00
|
|
|
// RTL headers
|
|
|
|
Classes, SysUtils,
|
|
|
|
// LCL headers
|
|
|
|
LCLType, LCLIntf, LCLProc, WSLCLClasses,
|
2010-01-24 12:45:21 +00:00
|
|
|
Graphics, Controls, StdCtrls,
|
2010-05-20 12:21:17 +00:00
|
|
|
// Win32WidgetSet
|
2014-11-20 23:46:38 +00:00
|
|
|
Win32WSControls, Win32Int, Win32WSStdCtrls, win32proc,
|
2009-06-04 19:38:39 +00:00
|
|
|
// RichMemo headers
|
2014-11-19 03:58:06 +00:00
|
|
|
RichMemo, WSRichMemo, Win32RichMemoProc;
|
2009-06-04 19:38:39 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
|
2014-11-20 23:46:38 +00:00
|
|
|
{ TWin32RichMemoStringsW }
|
|
|
|
|
|
|
|
TWin32RichMemoStringsW = class(TWin32MemoStrings)
|
|
|
|
protected
|
|
|
|
fHandle : HWND;
|
|
|
|
function GetTextStr: string; override;
|
|
|
|
public
|
|
|
|
constructor Create(AHandle: HWND; TheOwner: TWinControl);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ TWin32RichMemoStringsA }
|
|
|
|
|
|
|
|
TWin32RichMemoStringsA = class(TWin32MemoStrings)
|
|
|
|
protected
|
|
|
|
fHandle : HWND;
|
|
|
|
function GetTextStr: string; override;
|
|
|
|
public
|
|
|
|
constructor Create(AHandle: HWND; TheOwner: TWinControl);
|
|
|
|
end;
|
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
{ TWin32WSCustomRichMemo }
|
|
|
|
|
|
|
|
TWin32WSCustomRichMemo = class(TWSCustomRichMemo)
|
|
|
|
published
|
2014-11-20 23:46:38 +00:00
|
|
|
class function GetStrings(const ACustomMemo: TCustomMemo): TStrings; override;
|
2009-07-21 22:40:13 +00:00
|
|
|
class procedure SetColor(const AWinControl: TWinControl); override;
|
|
|
|
|
2009-07-04 21:57:50 +00:00
|
|
|
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;
|
|
|
|
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override;
|
2010-05-01 21:04:43 +00:00
|
|
|
|
|
|
|
class procedure CutToClipboard(const AWinControl: TWinControl); override;
|
|
|
|
class procedure CopyToClipboard(const AWinControl: TWinControl); override;
|
|
|
|
class procedure PasteFromClipboard(const AWinControl: TWinControl); override;
|
2009-07-04 21:57:50 +00:00
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): HWND; override;
|
2009-06-14 09:18:53 +00:00
|
|
|
class function GetTextAttributes(const AWinControl: TWinControl; TextStart: Integer;
|
2009-06-14 17:33:35 +00:00
|
|
|
var Params: TIntFontParams): Boolean; override;
|
2010-05-20 12:21:17 +00:00
|
|
|
class procedure SetTextAttributes(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
2009-06-14 09:18:53 +00:00
|
|
|
const Params: TIntFontParams); override;
|
2010-05-01 21:04:43 +00:00
|
|
|
class procedure SetHideSelection(const ACustomEdit: TCustomEdit; AHideSelection: Boolean); override;
|
2009-06-14 09:18:53 +00:00
|
|
|
class function GetStyleRange(const AWinControl: TWinControl; TextStart: Integer; var RangeStart, RangeLen: Integer): Boolean; override;
|
2009-06-15 20:40:16 +00:00
|
|
|
class function LoadRichText(const AWinControl: TWinControl; Source: TStream): Boolean; override;
|
|
|
|
class function SaveRichText(const AWinControl: TWinControl; Dst: TStream): Boolean; override;
|
2010-05-20 12:21:17 +00:00
|
|
|
|
2014-11-12 04:38:24 +00:00
|
|
|
class function GetParaAlignment(const AWinControl: TWinControl; TextStart: Integer;
|
2014-11-19 03:58:06 +00:00
|
|
|
var AAlign: TParaAlignment): Boolean; override;
|
2014-11-12 04:38:24 +00:00
|
|
|
class procedure SetParaAlignment(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
2014-11-19 03:58:06 +00:00
|
|
|
const AAlign: TIntParaAlignment); override;
|
2014-11-12 04:38:24 +00:00
|
|
|
|
2014-11-13 23:35:45 +00:00
|
|
|
class function GetParaMetric(const AWinControl: TWinControl; TextStart: Integer;
|
2014-11-12 04:38:24 +00:00
|
|
|
var AMetrics: TIntParaMetric): Boolean; override;
|
2014-11-13 23:35:45 +00:00
|
|
|
class procedure SetParaMetric(const AWinControl: TWinControl; TextStart, TextLength: Integer;
|
|
|
|
const AMetrics: TIntParaMetric); override;
|
2014-11-26 16:16:54 +00:00
|
|
|
class function GetParaRange(const AWinControl: TWinControl; TextStart: Integer;
|
|
|
|
var ParaRange: TParaRange): Boolean; override;
|
2014-11-13 23:35:45 +00:00
|
|
|
|
2014-11-15 18:57:15 +00:00
|
|
|
class function GetParaNumbering(const AWinControl: TWinControl; TextStart: Integer;
|
|
|
|
var ANumber: TIntParaNumbering): Boolean; override;
|
2014-11-13 23:35:45 +00:00
|
|
|
class procedure SetParaNumbering(const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
|
|
|
const ANumber: TIntParaNumbering); override;
|
|
|
|
|
2010-05-20 12:21:17 +00:00
|
|
|
class procedure InDelText(const AWinControl: TWinControl; const TextUTF8: String; DstStart, DstLen: Integer); override;
|
2014-11-24 07:59:03 +00:00
|
|
|
|
|
|
|
class function Search(const AWinControl: TWinControl; const ANiddle: string;
|
|
|
|
const SearchOpts: TIntSearchOpt): Integer; override;
|
2009-06-04 19:38:39 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
const
|
|
|
|
AlignmentToEditFlags: array[TAlignment] of DWord =
|
|
|
|
(
|
|
|
|
{ taLeftJustify } ES_LEFT,
|
|
|
|
{ taRightJustify } ES_RIGHT,
|
|
|
|
{ taCenter } ES_CENTER
|
|
|
|
);
|
|
|
|
|
|
|
|
|
2009-07-04 21:57:50 +00:00
|
|
|
procedure LockRedraw(AHandle: HWND);
|
2009-06-04 19:38:39 +00:00
|
|
|
begin
|
|
|
|
SendMessage(AHandle, WM_SETREDRAW, 0, 0);
|
|
|
|
end;
|
|
|
|
|
2009-07-04 21:57:50 +00:00
|
|
|
procedure UnlockRedraw(AHandle: HWND; NeedInvalidate: Boolean = true);
|
2009-06-04 19:38:39 +00:00
|
|
|
begin
|
|
|
|
SendMessage(AHandle, WM_SETREDRAW, 1, 0);
|
2009-07-04 21:57:50 +00:00
|
|
|
if NeedInvalidate then
|
|
|
|
Windows.InvalidateRect(AHandle, nil, true);
|
2009-06-04 19:38:39 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
function RichEditProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
|
|
|
|
LParam: Windows.LParam): LResult; stdcall;
|
|
|
|
begin
|
2009-07-04 21:57:50 +00:00
|
|
|
if Msg = WM_PAINT then begin
|
2009-06-04 19:38:39 +00:00
|
|
|
//todo: LCL WM_PAINT handling prevents richedit from drawing correctly
|
|
|
|
Result := CallDefaultWindowProc(Window, Msg, WParam, LParam)
|
2009-07-04 21:57:50 +00:00
|
|
|
//Result := WindowProc(Window, Msg, WParam, LParam)
|
|
|
|
end else
|
2009-06-04 19:38:39 +00:00
|
|
|
Result := WindowProc(Window, Msg, WParam, LParam);
|
2014-11-20 23:46:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{ TWin32RichMemoStringsW }
|
|
|
|
|
|
|
|
constructor TWin32RichMemoStringsW.Create(AHandle: HWND; TheOwner: TWinControl);
|
|
|
|
begin
|
|
|
|
inherited Create(AHandle, TheOwner);
|
|
|
|
fHandle:=AHandle;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWin32RichMemoStringsW.GetTextStr: string;
|
|
|
|
var
|
|
|
|
p : GETTEXTLENGTHEX;
|
|
|
|
t : GETTEXTEX;
|
|
|
|
res : Integer;
|
|
|
|
w : WideString;
|
|
|
|
begin
|
|
|
|
fillchar(p, sizeof(p), 0);
|
|
|
|
p.flags:=GTL_DEFAULT or GTL_PRECISE or GTL_NUMCHARS;
|
|
|
|
res := SendMessageW(fHandle, EM_GETTEXTLENGTHEX, WPARAM(@P), CP_WINUNICODE);
|
|
|
|
if res>0 then begin
|
|
|
|
SetLength(w, res);
|
|
|
|
FillChar(t, sizeof(t), 0);
|
2014-11-24 07:59:03 +00:00
|
|
|
t.cb:=(length(w)+1)*sizeof(WideChar);
|
2014-11-20 23:46:38 +00:00
|
|
|
t.flags:=GT_DEFAULT;
|
|
|
|
t.codepage:=CP_WINUNICODE;
|
|
|
|
res:=SendMessageW(fHandle, EM_GETTEXTEX, WPARAM(@t), LPARAM(@w[1]));
|
|
|
|
Result:=UTF8Encode(w);
|
|
|
|
end else
|
|
|
|
Result:='';
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ TWin32RichMemoStringsA }
|
|
|
|
|
|
|
|
constructor TWin32RichMemoStringsA.Create(AHandle: HWND; TheOwner: TWinControl);
|
|
|
|
begin
|
|
|
|
inherited Create(AHandle, TheOwner);
|
|
|
|
fHandle:=AHandle;
|
|
|
|
end;
|
|
|
|
|
|
|
|
function TWin32RichMemoStringsA.GetTextStr: string;
|
|
|
|
var
|
|
|
|
p : GETTEXTLENGTHEX;
|
|
|
|
t : GETTEXTEX;
|
|
|
|
res : Integer;
|
|
|
|
s : WideString;
|
|
|
|
begin
|
|
|
|
fillchar(p, sizeof(p), 0);
|
|
|
|
p.flags:=GTL_DEFAULT or GTL_PRECISE or GTL_NUMBYTES;
|
|
|
|
res := SendMessageW(fHandle, EM_GETTEXTLENGTHEX, WPARAM(@P), CP_ACP);
|
|
|
|
if res>0 then begin
|
|
|
|
SetLength(s, res);
|
|
|
|
FillChar(t, sizeof(t), 0);
|
2014-11-24 07:59:03 +00:00
|
|
|
t.cb:=length(s)+1;
|
2014-11-20 23:46:38 +00:00
|
|
|
t.flags:=GT_DEFAULT;
|
|
|
|
t.codepage:=CP_ACP;
|
|
|
|
res:=SendMessageW(fHandle, EM_GETTEXTEX, WPARAM(@t), LPARAM(@s[1]));
|
|
|
|
Result:=AnsiToUtf8(s);
|
|
|
|
end else
|
|
|
|
Result:='';
|
|
|
|
end;
|
2009-06-04 19:38:39 +00:00
|
|
|
|
|
|
|
{ TWin32WSCustomRichMemo }
|
|
|
|
|
2014-11-20 23:46:38 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetStrings(const ACustomMemo: TCustomMemo
|
|
|
|
): TStrings;
|
|
|
|
begin
|
|
|
|
if UnicodeEnabledOS then
|
|
|
|
Result := TWin32RichMemoStringsW.Create(ACustomMemo.Handle, ACustomMemo)
|
|
|
|
else
|
|
|
|
Result := TWin32RichMemoStringsA.Create(ACustomMemo.Handle, ACustomMemo);
|
|
|
|
end;
|
|
|
|
|
2009-07-21 22:40:13 +00:00
|
|
|
class procedure TWin32WSCustomRichMemo.SetColor(const AWinControl: TWinControl);
|
|
|
|
begin
|
|
|
|
// this methos is implemented, because Win32RichMemo doesn't use
|
|
|
|
// default LCL WM_PAINT message!
|
2010-01-24 12:45:21 +00:00
|
|
|
SendMessage(AWinControl.Handle, EM_SETBKGNDCOLOR, 0, ColorToRGB(AWinControl.Color));
|
2009-07-21 22:40:13 +00:00
|
|
|
end;
|
|
|
|
|
2009-07-04 21:57:50 +00:00
|
|
|
class procedure TWin32WSCustomRichMemo.SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer);
|
|
|
|
var
|
|
|
|
range : Tcharrange;
|
|
|
|
begin
|
|
|
|
range.cpMin := NewStart;
|
|
|
|
range.cpMax := NewStart;
|
|
|
|
SendMessage(ACustomEdit.Handle, EM_EXSETSEL, 0, LPARAM(@range));
|
|
|
|
InvalidateRect(ACustomEdit.Handle, nil, false);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer);
|
|
|
|
var
|
|
|
|
range : Tcharrange;
|
|
|
|
begin
|
|
|
|
SendMessage(ACustomEdit.Handle, EM_EXGETSEL, 0, LPARAM(@range));
|
|
|
|
range.cpMax := range.cpMin + NewLength;
|
|
|
|
SendMessage(ACustomEdit.Handle, EM_EXSETSEL, 0, LPARAM(@range));
|
|
|
|
InvalidateRect(ACustomEdit.Handle, nil, false);
|
|
|
|
end;
|
|
|
|
|
2010-05-01 21:04:43 +00:00
|
|
|
class procedure TWin32WSCustomRichMemo.CutToClipboard(const AWinControl: TWinControl);
|
|
|
|
begin
|
|
|
|
SendMessage(AWinControl.Handle, WM_CUT, 0,0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.CopyToClipboard(const AWinControl: TWinControl);
|
|
|
|
begin
|
|
|
|
SendMessage(AWinControl.Handle, WM_COPY, 0,0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.PasteFromClipboard(const AWinControl: TWinControl);
|
|
|
|
begin
|
|
|
|
SendMessage(AWinControl.Handle, WM_PASTE, 0,0);
|
|
|
|
end;
|
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
class function TWin32WSCustomRichMemo.CreateHandle(const AWinControl: TWinControl;
|
|
|
|
const AParams: TCreateParams): HWND;
|
|
|
|
var
|
|
|
|
Params : TCreateWindowExParams;
|
|
|
|
RichClass : AnsiString;
|
|
|
|
ACustomMemo : TCustomMemo;
|
|
|
|
begin
|
|
|
|
InitRichEdit;
|
|
|
|
RichClass := GetRichEditClass;
|
|
|
|
if RichClass = '' then begin
|
|
|
|
Result := 0;
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// general initialization of Params
|
2010-03-07 16:03:45 +00:00
|
|
|
|
|
|
|
// if you're using 0.9.28.2 compiler, uncomment the line,
|
|
|
|
// PrepareCreateWindow(AWinControl, Params);
|
|
|
|
// and comment the following like (it's for 0.9.30 compatiblity):
|
2010-03-07 11:51:34 +00:00
|
|
|
PrepareCreateWindow(AWinControl, AParams, Params);
|
2010-03-07 16:03:45 +00:00
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
Params.SubClassWndProc := @RichEditProc;
|
|
|
|
|
|
|
|
// customization of Params
|
|
|
|
ACustomMemo := TCustomMemo(AWinControl);
|
|
|
|
with Params do
|
|
|
|
begin
|
|
|
|
Flags := Flags or ES_AUTOVSCROLL or ES_MULTILINE or ES_WANTRETURN;
|
2010-01-24 12:45:21 +00:00
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
if ACustomMemo.ReadOnly then
|
|
|
|
Flags := Flags or ES_READONLY;
|
|
|
|
Flags := Flags or AlignmentToEditFlags[ACustomMemo.Alignment];
|
|
|
|
case ACustomMemo.ScrollBars of
|
|
|
|
ssHorizontal, ssAutoHorizontal:
|
|
|
|
Flags := Flags or WS_HSCROLL;
|
|
|
|
ssVertical, ssAutoVertical:
|
|
|
|
Flags := Flags or WS_VSCROLL;
|
|
|
|
ssBoth, ssAutoBoth:
|
|
|
|
Flags := Flags or WS_HSCROLL or WS_VSCROLL;
|
|
|
|
end;
|
|
|
|
if ACustomMemo.WordWrap then
|
|
|
|
Flags := Flags and not WS_HSCROLL
|
|
|
|
else
|
|
|
|
Flags := Flags or ES_AUTOHSCROLL;
|
2009-07-21 22:40:13 +00:00
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
if ACustomMemo.BorderStyle=bsSingle then
|
|
|
|
FlagsEx := FlagsEx or WS_EX_CLIENTEDGE;
|
2009-07-21 22:40:13 +00:00
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
pClassName := @RichClass[1];
|
|
|
|
WindowTitle := StrCaption;
|
|
|
|
end;
|
|
|
|
// create window
|
|
|
|
FinishCreateWindow(AWinControl, Params, false);
|
|
|
|
// memo is not a transparent control -> no need for parentpainting
|
|
|
|
Params.WindowInfo^.needParentPaint := false;
|
|
|
|
Result := Params.Window;
|
|
|
|
end;
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.SetTextAttributes(const AWinControl: TWinControl;
|
2009-06-14 09:18:53 +00:00
|
|
|
TextStart, TextLen: Integer; const Params: TIntFontParams);
|
2009-06-04 19:38:39 +00:00
|
|
|
var
|
|
|
|
OrigStart : Integer;
|
|
|
|
OrigLen : Integer;
|
|
|
|
NeedLock : Boolean;
|
|
|
|
begin
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
|
|
|
|
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
|
|
|
|
|
|
NeedLock := (OrigStart <> TextStart) or (OrigLen <> TextLen);
|
|
|
|
if NeedLock then begin
|
|
|
|
LockRedraw(AWinControl.Handle);
|
|
|
|
RichEditManager.SetSelection(AWinControl.Handle, TextStart, TextLen);
|
2009-06-14 09:18:53 +00:00
|
|
|
RichEditManager.SetSelectedTextStyle(AWinControl.Handle, Params );
|
2009-06-04 19:38:39 +00:00
|
|
|
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
|
|
UnlockRedraw(AWinControl.Handle);
|
|
|
|
end else
|
2009-06-14 09:18:53 +00:00
|
|
|
RichEditManager.SetSelectedTextStyle(AWinControl.Handle, Params);
|
2009-06-04 19:38:39 +00:00
|
|
|
end;
|
|
|
|
|
2009-07-21 22:40:13 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetTextAttributes(const AWinControl: TWinControl;
|
|
|
|
TextStart: Integer; var Params: TIntFontParams): Boolean;
|
2009-06-04 19:38:39 +00:00
|
|
|
var
|
|
|
|
OrigStart : Integer;
|
|
|
|
OrigLen : Integer;
|
|
|
|
NeedLock : Boolean;
|
2009-07-21 22:40:13 +00:00
|
|
|
eventmask : LongWord;
|
2009-06-04 19:38:39 +00:00
|
|
|
begin
|
2009-06-14 17:33:35 +00:00
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
|
|
|
Result := false;
|
|
|
|
Exit;
|
|
|
|
end;
|
2009-06-04 19:38:39 +00:00
|
|
|
|
2009-07-21 22:40:13 +00:00
|
|
|
eventmask := SendMessage(AWinControl.Handle, EM_GETEVENTMASK, 0, 0);
|
|
|
|
SendMessage(AWinControl.Handle, EM_SETEVENTMASK, 0, 0);
|
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
|
|
|
|
|
|
NeedLock := (OrigStart <> TextStart);
|
|
|
|
if NeedLock then begin
|
|
|
|
LockRedraw(AWinControl.Handle);
|
|
|
|
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
|
|
|
Result := RichEditManager.GetSelectedTextStyle(AWinControl.Handle, Params );
|
|
|
|
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
2009-09-19 18:11:58 +00:00
|
|
|
UnlockRedraw(AWinControl.Handle, false);
|
2009-07-21 22:40:13 +00:00
|
|
|
end else begin
|
|
|
|
LockRedraw(AWinControl.Handle);
|
2009-06-04 19:38:39 +00:00
|
|
|
Result := RichEditManager.GetSelectedTextStyle(AWinControl.Handle, Params);
|
2009-09-19 18:11:58 +00:00
|
|
|
UnlockRedraw(AWinControl.Handle, false);
|
2009-07-21 22:40:13 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
SendMessage(AWinControl.Handle, EM_SETEVENTMASK, 0, eventmask);
|
2009-06-04 19:38:39 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.SetHideSelection(
|
2010-05-01 21:04:43 +00:00
|
|
|
const ACustomEdit: TCustomEdit; AHideSelection: Boolean);
|
2009-06-04 19:38:39 +00:00
|
|
|
begin
|
2010-05-01 21:04:43 +00:00
|
|
|
if not Assigned(RichEditManager) or not Assigned(ACustomEdit) then Exit;
|
|
|
|
RichEditManager.SetHideSelection(ACustomEdit.Handle, AHideSelection);
|
2009-06-04 19:38:39 +00:00
|
|
|
end;
|
|
|
|
|
2009-07-04 21:57:50 +00:00
|
|
|
procedure InitScrollInfo(var info: TScrollInfo);
|
|
|
|
begin
|
|
|
|
FillChar(info, sizeof(info), 0);
|
|
|
|
info.cbSize := sizeof(info);
|
|
|
|
info.fMask := SIF_ALL;
|
|
|
|
end;
|
|
|
|
|
2009-06-14 09:18:53 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetStyleRange(
|
|
|
|
const AWinControl: TWinControl; TextStart: Integer; var RangeStart,
|
|
|
|
RangeLen: Integer): Boolean;
|
2009-06-15 21:53:45 +00:00
|
|
|
var
|
|
|
|
OrigStart : Integer;
|
|
|
|
OrigLen : Integer;
|
2009-07-04 21:57:50 +00:00
|
|
|
hInfo : TScrollInfo;
|
|
|
|
vInfo : TScrollInfo;
|
|
|
|
hVisible : Boolean;
|
|
|
|
vVisible : Boolean;
|
2009-07-21 22:40:13 +00:00
|
|
|
eventmask : longword;
|
2009-06-14 09:18:53 +00:00
|
|
|
begin
|
2009-06-15 21:53:45 +00:00
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then begin
|
|
|
|
Result := false;
|
|
|
|
Exit;
|
|
|
|
end;
|
2009-07-04 21:57:50 +00:00
|
|
|
|
2009-07-21 22:40:13 +00:00
|
|
|
eventmask := SendMessage(AWinControl.Handle, EM_GETEVENTMASK, 0, 0);
|
|
|
|
SendMessage(AWinControl.Handle, EM_SETEVENTMASK, 0, 0);
|
|
|
|
|
2009-06-15 21:53:45 +00:00
|
|
|
RichEditManager.GetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
|
|
|
LockRedraw(AWinControl.Handle);
|
2009-07-04 21:57:50 +00:00
|
|
|
InitScrollInfo(hInfo);
|
|
|
|
InitScrollInfo(vInfo);
|
|
|
|
hVisible:=GetScrollbarVisible(AWinControl.Handle, SB_Horz);
|
|
|
|
vVisible:=GetScrollbarVisible(AWinControl.Handle, SB_Vert);
|
|
|
|
GetScrollInfo(AWinControl.Handle, SB_Horz, hInfo);
|
|
|
|
GetScrollInfo(AWinControl.Handle, SB_Vert, vInfo);
|
|
|
|
|
2009-06-15 21:53:45 +00:00
|
|
|
RichEditManager.SetSelection(AWinControl.Handle, TextStart, 1);
|
2009-07-04 21:57:50 +00:00
|
|
|
try
|
|
|
|
Result := RichEditManager.GetStyleRange(AWinControl.Handle, TextStart, RangeStart, RangeLen);
|
|
|
|
except
|
|
|
|
end;
|
|
|
|
|
|
|
|
if hVisible then SetScrollInfo(AWinControl.Handle, SB_Horz, hInfo, false);
|
|
|
|
if vVisible then SetScrollInfo(AWinControl.Handle, SB_Vert, vInfo, false);
|
2009-06-15 21:53:45 +00:00
|
|
|
RichEditManager.SetSelection(AWinControl.Handle, OrigStart, OrigLen);
|
2009-07-04 21:57:50 +00:00
|
|
|
UnlockRedraw(AWinControl.Handle, false);
|
2009-07-21 22:40:13 +00:00
|
|
|
|
|
|
|
SendMessage(AWinControl.Handle, EM_SETEVENTMASK, 0, eventmask);
|
2009-06-14 09:18:53 +00:00
|
|
|
end;
|
2009-06-15 20:40:16 +00:00
|
|
|
|
|
|
|
class function TWin32WSCustomRichMemo.LoadRichText(
|
|
|
|
const AWinControl: TWinControl; Source: TStream): Boolean;
|
|
|
|
begin
|
2010-07-04 15:01:15 +00:00
|
|
|
Result := False;
|
2009-06-15 20:50:00 +00:00
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
2009-06-15 20:40:16 +00:00
|
|
|
Result := RichEditManager.LoadRichText(AWinControl.Handle, Source);
|
|
|
|
end;
|
|
|
|
|
|
|
|
class function TWin32WSCustomRichMemo.SaveRichText(
|
|
|
|
const AWinControl: TWinControl; Dst: TStream): Boolean;
|
|
|
|
begin
|
|
|
|
Result := false;
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
Result := RichEditManager.SaveRichText(AWinControl.Handle, Dst);
|
|
|
|
end;
|
2010-05-20 12:21:17 +00:00
|
|
|
|
2014-11-12 04:38:24 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetParaAlignment(
|
2014-11-19 03:58:06 +00:00
|
|
|
const AWinControl: TWinControl; TextStart: Integer; var AAlign: TParaAlignment
|
2014-11-12 04:38:24 +00:00
|
|
|
): Boolean;
|
|
|
|
var
|
|
|
|
para : PARAFORMAT2;
|
|
|
|
begin
|
|
|
|
Result:=false;
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
|
|
|
case para.wAlignment of
|
2014-11-19 03:58:06 +00:00
|
|
|
PFA_CENTER: AAlign:=paCenter;
|
|
|
|
PFA_RIGHT: AAlign:=paRight;
|
|
|
|
PFA_JUSTIFY: AAlign:=paJustify;
|
2014-11-12 04:38:24 +00:00
|
|
|
else
|
2014-11-19 03:58:06 +00:00
|
|
|
AAlign:=paLeft;
|
2014-11-12 04:38:24 +00:00
|
|
|
end;
|
|
|
|
Result:=true;
|
|
|
|
end;
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.SetParaAlignment(
|
2014-11-19 03:58:06 +00:00
|
|
|
const AWinControl: TWinControl; TextStart, TextLen: Integer; const AAlign: TIntParaAlignment);
|
2014-11-12 04:38:24 +00:00
|
|
|
var
|
|
|
|
para : PARAFORMAT2;
|
|
|
|
const
|
2014-11-19 03:58:06 +00:00
|
|
|
WinPara : array [TIntParaAlignment] of word = (PFA_LEFT, PFA_RIGHT, PFA_CENTER, PFA_JUSTIFY);
|
2014-11-12 04:38:24 +00:00
|
|
|
begin
|
2014-11-19 03:58:06 +00:00
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
2014-11-12 04:38:24 +00:00
|
|
|
FillChar(para, sizeof(para), 0);
|
|
|
|
para.cbSize:=sizeof(para);
|
|
|
|
para.dwMask:=PFM_ALIGNMENT;
|
2014-11-19 03:58:06 +00:00
|
|
|
para.wAlignment:=WinPara[AAlign];
|
2014-11-12 04:38:24 +00:00
|
|
|
RichEditManager.SetPara2(AWinControl.Handle, TextStart, TextLen, para);
|
|
|
|
end;
|
|
|
|
|
2014-11-13 23:35:45 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetParaMetric(
|
2014-11-12 04:38:24 +00:00
|
|
|
const AWinControl: TWinControl; TextStart: Integer;
|
|
|
|
var AMetrics: TIntParaMetric): Boolean;
|
|
|
|
var
|
|
|
|
para : PARAFORMAT2;
|
|
|
|
begin
|
|
|
|
Result:=false;
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
2014-11-13 23:35:45 +00:00
|
|
|
|
2014-11-15 18:57:15 +00:00
|
|
|
AMetrics.FirstLine:=para.dxStartIndent/20;
|
|
|
|
AMetrics.TailIndent:=para.dxRightIndent/20;
|
|
|
|
AMetrics.HeadIndent:=(para.dxStartIndent+para.dxOffset)/20;
|
2014-11-13 23:35:45 +00:00
|
|
|
AMetrics.SpaceAfter:=para.dySpaceAfter/20;
|
|
|
|
AMetrics.SpaceBefore:=para.dySpaceBefore/20;
|
|
|
|
AMetrics.LineSpacing:=para.dyLineSpacing/20;
|
|
|
|
end;
|
|
|
|
|
|
|
|
class procedure TWin32WSCustomRichMemo.SetParaMetric(
|
|
|
|
const AWinControl: TWinControl; TextStart, TextLength: Integer;
|
|
|
|
const AMetrics: TIntParaMetric);
|
|
|
|
var
|
|
|
|
para : PARAFORMAT2;
|
|
|
|
begin
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
FillChar(para, SizeOf(para), 0);
|
|
|
|
|
|
|
|
para.cbSize:=sizeof(para);
|
|
|
|
para.dwMask:=
|
|
|
|
PFM_STARTINDENT or PFM_RIGHTINDENT
|
|
|
|
or PFM_OFFSET
|
|
|
|
or PFM_SPACEAFTER or PFM_SPACEBEFORE
|
|
|
|
or PFM_LINESPACING;
|
2014-11-15 18:57:15 +00:00
|
|
|
para.dxStartIndent:=round(AMetrics.FirstLine*20);
|
|
|
|
para.dxRightIndent:=round(AMetrics.TailIndent*20);
|
|
|
|
para.dxOffset:=round((AMetrics.HeadIndent-AMetrics.FirstLine)*20);
|
|
|
|
//round(AMetrics.HeadIndent*20);
|
2014-11-13 23:35:45 +00:00
|
|
|
para.dySpaceAfter:=round(AMetrics.SpaceAfter*20);
|
|
|
|
para.dySpaceBefore:=round(AMetrics.SpaceBefore*20);
|
2014-11-16 06:46:18 +00:00
|
|
|
if AMetrics.LineSpacing > 0 then begin
|
|
|
|
para.dyLineSpacing:=round(AMetrics.LineSpacing*20);
|
|
|
|
para.bLineSpacingRule:=5; // always line spacing?
|
|
|
|
end;
|
2014-11-13 23:35:45 +00:00
|
|
|
RichEditManager.SetPara2(AWinControl.Handle, TextStart, TextLength, para);
|
|
|
|
end;
|
|
|
|
|
2014-11-26 16:16:54 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetParaRange(const AWinControl: TWinControl;
|
|
|
|
TextStart: Integer; var ParaRange: TParaRange): Boolean;
|
|
|
|
begin
|
|
|
|
if not Assigned(AWinControl) then
|
|
|
|
Result:=False
|
|
|
|
else begin
|
|
|
|
RichEditManager.GetParaRange(AWinControl.Handle, TextStart, ParaRange);
|
|
|
|
Result:=true;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2014-11-13 23:35:45 +00:00
|
|
|
const
|
2014-11-15 18:57:15 +00:00
|
|
|
PFN_ARABIC = 2;
|
|
|
|
PFN_LCLETTER = 3;
|
|
|
|
PFN_LCROMAN = 4;
|
|
|
|
PFN_UCLETTER = 5;
|
|
|
|
PFN_UCROMAN = 6;
|
2014-11-13 23:35:45 +00:00
|
|
|
PFN_CUSTOM = 7;
|
|
|
|
|
2014-11-15 18:57:15 +00:00
|
|
|
class function TWin32WSCustomRichMemo.GetParaNumbering(
|
|
|
|
const AWinControl: TWinControl; TextStart: Integer;
|
|
|
|
var ANumber: TIntParaNumbering): Boolean;
|
|
|
|
var
|
|
|
|
para : PARAFORMAT2;
|
|
|
|
begin
|
|
|
|
Result:=False;
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
|
|
|
|
RichEditManager.GetPara2(AWinControl.Handle, TextStart, para);
|
|
|
|
case para.wNumbering of
|
|
|
|
PFN_BULLET: ANumber.Numbering:=pnBullet;
|
|
|
|
PFN_ARABIC: ANumber.Numbering:=pnNumber;
|
|
|
|
PFN_LCLETTER: ANumber.Numbering:=pnLowLetter;
|
|
|
|
PFN_LCROMAN: ANumber.Numbering:=pnLowRoman;
|
|
|
|
PFN_UCLETTER: ANumber.Numbering:=pnUpLetter;
|
|
|
|
PFN_UCROMAN: ANumber.Numbering:=pnUpRoman;
|
|
|
|
PFN_CUSTOM: begin
|
|
|
|
ANumber.Numbering:=pnCustomChar;
|
|
|
|
ANumber.NumCustom:=WideChar(para.wNumberingStart);
|
|
|
|
end;
|
|
|
|
else
|
|
|
|
ANumber.Numbering:=pnNone;
|
|
|
|
end;
|
|
|
|
ANumber.NumIndent:=para.wNumberingTab/20;
|
|
|
|
Result:=true
|
|
|
|
end;
|
|
|
|
|
2014-11-13 23:35:45 +00:00
|
|
|
class procedure TWin32WSCustomRichMemo.SetParaNumbering(
|
|
|
|
const AWinControl: TWinControl; TextStart, TextLen: Integer;
|
|
|
|
const ANumber: TIntParaNumbering);
|
|
|
|
var
|
|
|
|
para : PARAFORMAT2;
|
|
|
|
begin
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
FillChar(para, SizeOf(para), 0);
|
|
|
|
|
|
|
|
para.cbSize:=sizeof(para);
|
|
|
|
para.dwMask:=
|
|
|
|
PFM_NUMBERING or PFM_NUMBERINGTAB;
|
|
|
|
case ANumber.Numbering of
|
|
|
|
pnNone: para.wNumbering:=0;
|
|
|
|
pnBullet: para.wNumbering:=PFN_BULLET;
|
|
|
|
pnNumber: para.wNumbering:=PFN_ARABIC;
|
|
|
|
pnLowLetter: para.wNumbering:=PFN_LCLETTER;
|
|
|
|
pnLowRoman: para.wNumbering:=PFN_LCROMAN;
|
|
|
|
pnUpLetter: para.wNumbering:=PFN_UCLETTER;
|
|
|
|
pnUpRoman: para.wNumbering:=PFN_UCROMAN;
|
|
|
|
pnCustomChar: begin
|
|
|
|
para.wNumbering:=PFN_CUSTOM;
|
|
|
|
para.wNumberingStart:=Word(ANumber.NumCustom);
|
|
|
|
para.dwMask:=para.dwMask or PFM_NUMBERINGSTART;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
para.wNumberingTab:=round(ANumber.NumIndent*20);
|
|
|
|
RichEditManager.SetPara2(AWinControl.Handle, TextStart, TextLen, para);
|
2014-11-12 04:38:24 +00:00
|
|
|
end;
|
|
|
|
|
2010-05-20 12:21:17 +00:00
|
|
|
class procedure TWin32WSCustomRichMemo.InDelText(const AWinControl:TWinControl;
|
|
|
|
const TextUTF8:String;DstStart,DstLen:Integer);
|
|
|
|
begin
|
2014-11-24 07:59:03 +00:00
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
2010-05-20 12:21:17 +00:00
|
|
|
RichEditManager.SetText(AWinControl.Handle,UTF8Decode(TextUTF8),DstStart,DstLen);
|
|
|
|
end;
|
2014-11-24 07:59:03 +00:00
|
|
|
|
|
|
|
class function TWin32WSCustomRichMemo.Search(const AWinControl: TWinControl;
|
|
|
|
const ANiddle: string; const SearchOpts: TIntSearchOpt): Integer;
|
|
|
|
begin
|
|
|
|
if not Assigned(RichEditManager) or not Assigned(AWinControl) then Exit;
|
|
|
|
Result:=RichEditManager.Find(AWinControl.Handle, UTF8Decode(ANiddle), SearchOpts);
|
|
|
|
end;
|
2009-06-14 09:18:53 +00:00
|
|
|
|
2009-06-04 19:38:39 +00:00
|
|
|
end.
|
|
|
|
|