2008. szeptember 17., szerda

How to get TRichEdit to use the RichEd20.dll


Problem/Question/Abstract:

Is there any easy way to get TRichEdit to use RichEd20.dll? We need to use the latest RTF v3, not the 1.0 currently supported by TRichEdit.

Answer:

It's better to use a third-party wrapper, but you can try to trick the standard TRichEdit. Override CreateParams and call CreateSubClass(Params, RICHEDIT_CLASS) there. The RICHEDIT_CLASS constant designates a Rich Edit version 2.0 and higher control. Also, you should call the LoadLibrary('RICHED20.DLL') function to verify which version of Rich Edit is installed. Check the code listed below for details. There is additional code to suppress exceptions, which the RichEdit strings object generates, after the new string was inserted.

{ ... }
type
  TMyRichEdit20 = class(TRichEdit)
  protected
    FMax: integer;
    FSelection: TCharRange;
    procedure EMExSetSel(var Message: TMessage); message EM_EXSETSEL;
    procedure EMReplaceSel(var Message: TMessage); message EM_REPLACESEL;
    function GetSelStart: integer; override;
    procedure CreateParams(var Params: TCreateParams); override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

  { ... }

constructor TMyRichEdit20.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMax := 0;
  FSelection.cpMin := 0;
  FSelection.cpMax := 0;
end;

procedure TMyRichEdit20.EMExSetSel(var Message: TMessage);
var
  ISel: integer;
  XSel: ^TCharRange absolute ISel;
begin
  inherited;
  ISel := Message.LParam;
  FSelection := XSel^;
end;

procedure TMyRichEdit20.EMReplaceSel(var Message: TMessage);
begin
  inherited;
  FMax := FSelection.cpMax + length(PChar(Message.LParam));
end;

function TMyRichEdit20.GetSelStart: Integer;
begin
  if FMax = 0 then
    Result := inherited GetSelStart
  else
  begin
    Result := FMax;
    FMax := 0;
  end;
end;

var
  FRichEditModule: THandle;

procedure TMyRichEdit20.CreateParams(var Params: TCreateParams);
begin
  if FRichEditModule = 0 then
  begin
    FRichEditModule := LoadLibrary('RICHED20.DLL');
    if FRichEditModule <= HINSTANCE_ERROR then
      FRichEditModule := 0;
  end;
  inherited CreateParams(Params);
  CreateSubClass(Params, RICHEDIT_CLASS);
end;

{ ... }

initialization

finalization
  if FRichEditModule <> 0 then
    FreeLibrary(FRichEditModule);

end.

Nincsenek megjegyzések:

Megjegyzés küldése