?? richeditviewer.pas
字號(hào):
unit RichEditViewer;
{ TRichEditViewer v1.11 by Jordan Russell
Known problem:
If, after assigning rich text to a TRichEditViewer component, you change
a property that causes the component's handle to be recreated, all text
formatting will be lost. In the interests of code size, I do not intend
to work around this.
Rich Edit 2.0 and > 64 kb support added by Martijn Laan for My Inno Setup Extensions
See http://isx.wintax.nl/ for more information
$jrsoftware: issrc/Components/RichEditViewer.pas,v 1.5 2004/09/22 16:57:26 jr Exp $
}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TRichEditViewer = class(TMemo)
private
FUseRichEdit: Boolean;
FRichEditLoaded: Boolean;
procedure SetRTFTextProp(const Value: String);
procedure SetUseRichEdit(Value: Boolean);
procedure UpdateBackgroundColor;
procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
procedure CMSysColorChange(var Message: TMessage); message CM_SYSCOLORCHANGE;
procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function SetRTFText(const Value: String): Integer;
property RTFText: String write SetRTFTextProp;
published
property UseRichEdit: Boolean read FUseRichEdit write SetUseRichEdit default True;
end;
procedure Register;
implementation
uses
RichEdit, ShellApi;
const
RICHEDIT_CLASS10A = 'RICHEDIT';
RICHEDIT_CLASSA = 'RichEdit20A';
RICHEDIT_CLASS = RICHEDIT_CLASSA;
EM_AUTOURLDETECT = WM_USER + 91;
ENM_LINK = $04000000;
EN_LINK = $070b;
type
PEnLink = ^TEnLink;
TENLink = record
nmhdr: TNMHdr;
msg: UINT;
wParam: WPARAM;
lParam: LPARAM;
chrg: TCharRange;
end;
TTextRange = record
chrg: TCharRange;
lpstrText: PAnsiChar;
end;
var
RichEditModule: HMODULE;
RichEditUseCount: Integer = 0;
RichEditVersion: Integer;
procedure LoadRichEdit;
begin
if RichEditUseCount = 0 then begin
RichEditVersion := 2;
RichEditModule := LoadLibrary('RICHED20.DLL');
if RichEditModule = 0 then begin
RichEditVersion := 1;
RichEditModule := LoadLibrary('RICHED32.DLL');
end;
end;
Inc(RichEditUseCount);
end;
procedure UnloadRichEdit;
begin
if RichEditUseCount > 0 then begin
Dec(RichEditUseCount);
if RichEditUseCount = 0 then begin
FreeLibrary(RichEditModule);
RichEditModule := 0;
end;
end;
end;
{ TRichEditViewer }
constructor TRichEditViewer.Create(AOwner: TComponent);
begin
inherited;
FUseRichEdit := True;
end;
destructor TRichEditViewer.Destroy;
begin
inherited;
{ First do all other deinitialization, then decrement the DLL use count }
if FRichEditLoaded then begin
FRichEditLoaded := False;
UnloadRichEdit;
end;
end;
procedure TRichEditViewer.CreateParams(var Params: TCreateParams);
{ Based on code from TCustomRichEdit.CreateParams }
begin
if UseRichEdit and not FRichEditLoaded then begin
{ Increment the DLL use count when UseRichEdit is True, load the DLL }
FRichEditLoaded := True;
LoadRichEdit;
end;
inherited;
if UseRichEdit then begin
if RichEditVersion = 2 then
CreateSubClass(Params, RICHEDIT_CLASS)
else
CreateSubClass(Params, RICHEDIT_CLASS10A);
end else
{ Inherited handler creates a subclass of 'EDIT'.
Must have a unique class name since it uses two different classes
depending on the setting of the UseRichEdit property. }
StrCat(Params.WinClassName, '/Text'); { don't localize! }
end;
procedure TRichEditViewer.CreateWnd;
var
Mask: LongInt;
begin
inherited;
UpdateBackgroundColor;
if FUseRichEdit and (RichEditVersion = 2) then begin
Mask := ENM_LINK or SendMessage(Handle, EM_GETEVENTMASK, 0, 0);
SendMessage(Handle, EM_SETEVENTMASK, 0, LPARAM(Mask));
SendMessage(Handle, EM_AUTOURLDETECT, WPARAM(True), 0);
end;
end;
procedure TRichEditViewer.UpdateBackgroundColor;
begin
if FUseRichEdit and HandleAllocated then
SendMessage(Handle, EM_SETBKGNDCOLOR, 0, ColorToRGB(Color));
end;
procedure TRichEditViewer.SetUseRichEdit(Value: Boolean);
begin
if FUseRichEdit <> Value then begin
FUseRichEdit := Value;
RecreateWnd;
if not Value and FRichEditLoaded then begin
{ Decrement the DLL use count when UseRichEdit is set to False }
FRichEditLoaded := False;
UnloadRichEdit;
end;
end;
end;
type
PStreamLoadData = ^TStreamLoadData;
TStreamLoadData = record
Buf: PByte;
BytesLeft: Integer;
end;
function StreamLoad(dwCookie: Longint; pbBuff: PByte;
cb: Longint; var pcb: Longint): Longint; stdcall;
begin
Result := 0;
with PStreamLoadData(dwCookie)^ do begin
if cb > BytesLeft then
cb := BytesLeft;
Move(Buf^, pbBuff^, cb);
Inc(Buf, cb);
Dec(BytesLeft, cb);
pcb := cb;
end;
end;
function TRichEditViewer.SetRTFText(const Value: String): Integer;
function StreamIn(AFormat: WPARAM): Integer;
var
Data: TStreamLoadData;
EditStream: TEditStream;
begin
Data.Buf := @Value[1];
Data.BytesLeft := Length(Value);
EditStream.dwCookie := Longint(@Data);
EditStream.dwError := 0;
EditStream.pfnCallback := @StreamLoad;
SendMessage(Handle, EM_STREAMIN, AFormat, LPARAM(@EditStream));
Result := EditStream.dwError;
end;
begin
if not FUseRichEdit then begin
Text := Value;
Result := 0;
end
else begin
SendMessage(Handle, EM_EXLIMITTEXT, 0, LParam($7FFFFFFE));
Result := StreamIn(SF_RTF);
if Result <> 0 then
Result := StreamIn(SF_TEXT);
end;
end;
procedure TRichEditViewer.SetRTFTextProp(const Value: String);
begin
SetRTFText(Value);
end;
procedure TRichEditViewer.CMColorChanged(var Message: TMessage);
begin
inherited;
UpdateBackgroundColor;
end;
procedure TRichEditViewer.CMSysColorChange(var Message: TMessage);
begin
inherited;
UpdateBackgroundColor;
end;
procedure TRichEditViewer.CNNotify(var Message: TWMNotify);
var
EnLink: PEnLink;
CharRange: TCharRange;
TextRange: TTextRange;
Length: Integer;
URL: String;
begin
case Message.NMHdr^.code of
EN_LINK: begin
EnLink := PEnLink(Message.NMHdr);
if EnLink.msg = WM_LBUTTONDOWN then begin
CharRange := EnLink.chrg;
if (CharRange.cpMin = 0) and (CharRange.cpMax = -1) then
Length := SendMessage(Handle, WM_GETTEXTLENGTH, 0, 0)
else
Length := CharRange.cpMax-CharRange.cpMin+1;
SetLength(URL, Length);
TextRange.chrg := CharRange;
TextRange.lpstrText := PChar(Url);
SetLength(URL, SendMessage(Handle, EM_GETTEXTRANGE, 0, LParam(@TextRange)));
if URL <> '' then
ShellExecute(Handle, 'open', PChar(Url), nil, nil, SW_SHOWNORMAL);
end;
end;
end;
end;
procedure Register;
begin
RegisterComponents('JR', [TRichEditViewer]);
end;
end.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -