cxrichedit.pas
来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,877 行 · 第 1/5 页
PAS
1,877 行
function cxRichEditGetOleInterface(ARichEdit: TcxRichInnerEdit;
out AOleInterface: IcxRichEditOle): Boolean;
begin
Result := Assigned(ARichEdit) and ARichEdit.HandleAllocated and
Boolean(SendMessage(ARichEdit.Handle, EM_GETOLEINTERFACE, 0, longint(@AOleInterface)));
end;
function cxRichEditSetOleCallback(ARichEdit: TcxRichInnerEdit;
AOleInterface: IcxRichEditOleCallback): Boolean;
begin
Result := Assigned(ARichEdit) and ARichEdit.HandleAllocated and
Boolean(SendMessage(ARichEdit.Handle, EM_SETOLECALLBACK, 0, longint(AOleInterface)));
end;
function cxGetVCLFrameForm(AForm: TCustomForm): IVCLFrameForm;
begin
if AForm.OleFormObject = nil then
TOleForm.Create(AForm);
Result := AForm.OleFormObject as IVCLFrameForm;
end;
function cxSendStructMessageEx(AHandle: THandle; AMsg: UINT; const AStructure; AParam: Integer; AStructureIsLParam: Boolean): LRESULT; overload;
begin
if AStructureIsLParam then
Result := SendMessage(AHandle, AMsg, AParam, Integer(@AStructure))
else
Result := SendMessage(AHandle, AMsg, Integer(@AStructure), AParam);
end;
function cxSendStructMessage(AHandle: THandle; AMsg: UINT; WParam: WPARAM; const LParam): LRESULT; overload;
begin
Result := cxSendStructMessageEx(AHandle, AMsg, LParam, WParam, True);
end;
function cxSendStructMessage(AHandle: THandle; AMsg: UINT; const WParam; LParam: LParam): LRESULT; overload;
begin
Result := cxSendStructMessageEx(AHandle, AMsg, WParam, LParam, False);
end;
function cxRichEditDLLNames: TcxRichEditNames;
procedure InitRichEditDLLNames;
const
cxRichEditDLLNamesCount = 3;
begin
SetLength(FRichEditDLLNames, cxRichEditDLLNamesCount);
FRichEditDLLNames[0] := 'Riched32.dll';
FRichEditDLLNames[1] := 'Riched20.dll';
FRichEditDLLNames[2] := 'Msftedit.dll';
end;
begin
if Length(FRichEditDLLNames) = 0 then
InitRichEditDLLNames;
Result := FRichEditDLLNames;
end;
function cxRichEditClassNames: TcxRichEditNames;
procedure InitRichEditClassNames;
const
cxRichEditClassNamesCount = 5;
begin
SetLength(FRichEditClassNames, cxRichEditClassNamesCount);
FRichEditClassNames[0] := 'RICHEDIT';
FRichEditClassNames[1] := 'RICHEDIT20';
FRichEditClassNames[2] := 'RICHEDIT30';
FRichEditClassNames[3] := 'RICHEDIT41';
FRichEditClassNames[4] := 'RICHEDIT50';
end;
begin
if Length(FRichEditClassNames) = 0 then
InitRichEditClassNames;
Result := FRichEditClassNames;
end;
function AdjustRichLineBreaksW(ADest, ASource: PWideChar; AShortBreak: Boolean = False): Integer;
var
APrevDest: PWideChar;
begin
APrevDest := ADest;
repeat
if ASource^ in [WideChar($0D), WideChar($0A)] then
begin
if AShortBreak then
ADest^ := WideChar($0D)
else
begin
ADest^ := WideChar($0A);
Inc(ADest);
ADest^ := WideChar($0D);
end;
if (ASource^ = WideChar($0D)) and ((ASource + 1)^ = WideChar($0A)) then
Inc(ASource);
end
else
ADest^ := ASource^;
Inc(ASource);
Inc(ADest);
until ASource^ = WideChar($00);
ADest^ := WideChar($00);
Result := ADest - APrevDest;
end;
function AdjustRichLineBreaks(ADest, ASource: PChar; AShortBreak: Boolean = False): Integer;
var
APrevDest: PChar;
begin
APrevDest := ADest;
repeat
if ASource^ in [#13, #10] then
begin
if AShortBreak then
ADest^ := #13
else
begin
PWord(ADest)^ := $0A0D;
Inc(ADest);
end;
if PWord(ASource)^ = $0A0D then
Inc(ASource);
end
else
ADest^ := ASource^;
Inc(ASource);
Inc(ADest);
until ASource^ = Char(0);
ADest^ := #0;
Result := ADest - APrevDest;
end;
function cxRichEditStreamLoad(dwCookie: Longint; pbBuff: PByte;
cb: Longint; var pcb: Longint): Longint; stdcall;
var
ABuffer, P: PChar;
AStreamInfo: PRichEditStreamInfo;
begin
Result := cxRichNoError;
AStreamInfo := PRichEditStreamInfo(Pointer(dwCookie));
ABuffer := StrAlloc(cb + 1);
try
cb := cb div 2;
pcb := 0;
P := ABuffer + cb;
try
if AStreamInfo^.Converter <> nil then
pcb := AStreamInfo^.Converter.ConvertReadStream(AStreamInfo^.Stream, P,
cb);
if pcb > 0 then
begin
P[pcb] := #0;
if P[pcb - 1] = #13 then
P[pcb - 1] := #0;
pcb := AdjustRichLineBreaks(ABuffer, P);
Move(ABuffer^, pbBuff^, pcb);
end;
except
Result := cxRichReadError;
end;
finally
StrDispose(ABuffer);
end;
end;
function cxRichEditStreamSave(dwCookie: Longint; pbBuff: PByte; cb: Longint;
var pcb: Longint): Longint; stdcall;
var
AStreamInfo: PRichEditStreamInfo;
begin
Result := cxRichNoError;
AStreamInfo := PRichEditStreamInfo(Pointer(dwCookie));
try
pcb := 0;
if AStreamInfo^.Converter <> nil then
pcb := AStreamInfo^.Converter.ConvertWriteStream(AStreamInfo^.Stream,
PChar(pbBuff), cb);
except
Result := cxRichWriteError;
end;
end;
function IsRichText(const AText: string): Boolean;
const
ARichPrefix = '{\rtf';
begin
Result := Copy(AText, 1, Length(ARichPrefix)) = ARichPrefix;
end;
procedure LoadRichFromString(ALines: TStrings; const S: string);
procedure PrepareStream(
AStream: TStringStream);
begin
end;
var
AStream: TStringStream;
begin
AStream := TStringStream.Create(S);
try
PrepareStream(AStream);
ALines.LoadFromStream(AStream);
finally
AStream.Free;
end;
end;
procedure ReleaseConversionFormatList;
var
AConversionFormatList: PConversionFormat;
begin
while FConversionFormatList <> @TextConversionFormat do
begin
AConversionFormatList := FConversionFormatList^.Next;
Dispose(FConversionFormatList);
FConversionFormatList := AConversionFormatList;
end;
end;
function CreateInnerRich: TcxRichInnerEdit;
begin
Result := nil;
if Application.Handle <> 0 then
begin
Result := TcxRichInnerEdit.Create(nil);
Result.ParentWindow := Application.Handle;
SendMessage(Result.Handle, EM_SETEVENTMASK, 0, 0);
end;
end;
function RichRenderer: TcxRichInnerEdit;
begin
if FRichRenderer = nil then
FRichRenderer := CreateInnerRich;
Result := FRichRenderer;
end;
function RichConverter: TcxRichInnerEdit;
begin
if FRichConverter = nil then
FRichConverter := CreateInnerRich;
Result := FRichConverter;
end;
procedure InternalSetRichEditText(ARichEdit: TRichEdit; const AText: string);
begin
if not ARichEdit.PlainText then
LoadRichFromString(ARichEdit.Lines, AText)
else
ARichEdit.Perform(WM_SETTEXT, 0, Longint(PChar(AText)));
end;
function ConvertRichText(const AText: string): string;
begin
InternalSetRichEditText(RichConverter, AText);
Result := RichConverter.Text;
end;
procedure SetRichDefAttributes(AEdit: TRichEdit; AFont: TFont; ATextColor: TColor);
begin
if not AEdit.HandleAllocated then
Exit;
AEdit.DefAttributes.Assign(AFont);
AEdit.DefAttributes.Color := ATextColor;
end;
procedure InitRichRenderer(AProperties: TcxCustomRichEditProperties;
AFont: TFont; AColor, ATextColor: TColor; const AText: string);
begin
with RichRenderer do
begin
MemoMode := TcxCustomRichEditProperties(AProperties).MemoMode;
PlainText := TcxCustomRichEditProperties(AProperties).PlainText;
Alignment := TcxCustomRichEditProperties(AProperties).Alignment;
AutoURLDetect := TcxCustomRichEditProperties(AProperties).AutoURLDetect;
AllowObjects := TcxCustomRichEditProperties(AProperties).AllowObjects;
HandleNeeded;
if not RichRenderer.MemoMode then
LoadRichFromString(RichLines, AText)
else
Text := AText;
if not IsRichText(AText) or MemoMode or PlainText then
SetRichDefAttributes(RichRenderer, AFont, ATextColor);
SendMessage(Handle, EM_SETBKGNDCOLOR, 0, ColorToRGB(AColor));
end;
end;
procedure DrawRichEdit(ADC: HDC; const ARect: TRect; const AText: string;
AProperties: TcxCustomRichEditProperties; AFont: TFont;
AColor, ATextColor: TColor; ACalculateHeight: Boolean; out AHeight: Integer);
const
TwipsPerInch = 1440;
var
AFormatRange: TFormatRange;
AStartIndex: Integer;
begin
if not ACalculateHeight then
FillRect(ADC, Rect(0, 0, ARect.Right - ARect.Left,
ARect.Bottom - ARect.Top), GetSolidBrush(AColor));
InitRichRenderer(AProperties, AFont, AColor, ATextColor, AText);
SendMessage(RichRenderer.Handle, EM_FORMATRANGE, 0, 0);
if ACalculateHeight then
AHeight := 0;
AFormatRange.hdc := ADC;
AFormatRange.hdcTarget := ADC;
AFormatRange.chrg.cpMin := 0;
AFormatRange.chrg.cpMax := -1;
repeat
AFormatRange.rc := cxEmptyRect;
AFormatRange.rc.Right := (ARect.Right - ARect.Left) * TwipsPerInch div GetDeviceCaps(ADC, LOGPIXELSX);
if ACalculateHeight then
AFormatRange.rc.Bottom := TwipsPerInch
else
AFormatRange.rc.Bottom := (ARect.Bottom - ARect.Top)(*65535*) * TwipsPerInch div GetDeviceCaps(ADC, LOGPIXELSY);
AFormatRange.rcPage := AFormatRange.rc;
AStartIndex := AFormatRange.chrg.cpMin;
AFormatRange.chrg.cpMin := cxSendStructMessage(RichRenderer.Handle, EM_FORMATRANGE,
WPARAM(not ACalculateHeight), AFormatRange);
if AFormatRange.chrg.cpMin <= AStartIndex then
Break;
if ACalculateHeight then
Inc(AHeight, AFormatRange.rc.Bottom - AFormatRange.rc.Top);
until not ACalculateHeight;
if ACalculateHeight then
AHeight := AHeight * GetDeviceCaps(ADC, LOGPIXELSY) div TwipsPerInch;
SendMessage(RichRenderer.Handle, EM_FORMATRANGE, 0, 0);
end;
procedure SetRichEditText(ARichEdit: TRichEdit; const AEditValue: TcxEditValue);
begin
InternalSetRichEditText(ARichEdit, VarToStr(AEditValue));
end;
{ TcxRichEdit }
class function TcxRichEdit.GetPropertiesClass: TcxCustomEditPropertiesClass;
begin
Result := TcxRichEditProperties;
end;
function TcxRichEdit.GetActiveProperties: TcxRichEditProperties;
begin
Result := TcxRichEditProperties(InternalGetActiveProperties);
end;
function TcxRichEdit.GetProperties: TcxRichEditProperties;
begin
Result := TcxRichEditProperties(FProperties);
end;
procedure TcxRichEdit.SetProperties(Value: TcxRichEditProperties);
begin
FProperties.Assign(Value);
end;
{ TcxRichInnerEditHelper }
constructor TcxRichInnerEditHelper.Create(AEdit: TcxRichInnerEdit);
begin
inherited Create(nil);
FEdit := AEdit;
FEdit.PlainText := False;
FEdit.WordWrap := False;
end;
function TcxRichInnerEditHelper.GetControl: TWinControl;
begin
Result := Edit;
end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?