RichViewEdit

时间:2019-09-03
本文章向大家介绍RichViewEdit,主要包括RichViewEdit使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

RichViewEdit特殊操作

RichviewEdit 图文保存操作

首先要转换成stream后才能对RichviewEdit进行正确的读和写
 function  SaveRVFToField(rv: TCustomRichView; tbl: TTable;
 const  FieldName: String): Boolean; 
var  Stream: TStream;
 begin
  Stream :=TMemoryStream.Create; 
 try Result :=  rv.SaveRVFToStream(Stream, False);
 Stream.Position :=  0;
 TBlobField(tbl.FieldByName(FieldName)).LoadFromStream(Stream);
 finally
 Stream.Free;
 end;
  end;
 
 function  LoadRVFFromField(rv: TCustomRichView; tbl: TTable;
 const  FieldName: String): Boolean;
 var  Stream: TStream;
 begin
 Stream :=  TMemoryStream.Create;
 try
 TBlobField(tbl.FieldByName(FieldName)).SaveToStream(Stream);
 Stream.Position :=  0;
 Result :=  rv.LoadRVFFromStream(Stream);
 finally
 Stream.Free;
 end;
 rv.Format;
 end;


    以上的两个函数是把RichviewEdit的内容保存到数据库里面的做法。但是,   RichViewEdit的图片内容保存到数据库后,有些图片保存的时候看起来是正常的,但是再从数据库里面读出来就看不到图片了,但是这种状况并不是每张图片都会发生,有些图片放进去数据库后又能正常显示,百思不得其解!
    后来在RichViewEdit的RVFOptions——rvfoSaveBinary设置成False,这样从数据库里面读取出来的图片就都能正常显示了。

让 RichviewEdit 内容转换成图片
procedure TSendDataFrm.btnR2BClick;
const
  VERYLARGEVALUE = $FFFFFFF;
var
  iWidth, iHeight: integer;
  Canvas: TMetafileCanvas;
  bmp: TBitmap;
  wmf: TMetafile;
  i, j, k: integer;
begin
  RVE.HScrollPos := 0;
  RVE.VScrollPos := 0;
  RVE.Deselect;
  RVE.Invalidate;
  k := 0;
  for i := 0 to RVE.LineCount - 1 do
  begin
    j := RVE.Canvas.TextWidth(RVE.GetItemTextA(i)); //+RVE.GetItemTextR(i)图片长
    if j > K then
      k := j;
  end;
  iWidth := k;
  iHeight := RVE.RVData.DocumentHeight - 10;

  Image1.Picture.Bitmap.Width := iwidth;
  Image1.Picture.Bitmap.Height := iHeight;
  bitblt(Image1.Picture.Bitmap.Canvas.Handle, -1, -7
    , RVE.Width, RVE.Height, GetWindowDC(RVE.Handle), 0, 0, SRCCOPY);
  image1.Refresh;
  

让 RichviewEdit 支持中文
⑴ 设置RichViewEdit下面的几个属性:
   ① TRVRTFReaderProperties → ParaStyleMode → rvrsAddIfNeeded
   ② TRVRTFReaderProperties → TextStyleMode → rvrsAddIfNeeded
   ③ TRVRTFReaderProperties → UnicodeMode → rvruOnlyUnicode
⑵ 设置RVStyle:
   双击该控件,在弹出的窗体里选定里面5个子项,然后在属性窗体里找到
Unicode属性,全部改为:True;
View Code

ichEdit的内容保存为图片

uses RichEdit;
{将RichEdit1的内容保存为图片,此函数也适合于RxRichEdit,即RichEdit: TRxRichEdit}
procedure RichEditToCanvas(RichEdit: TRichEdit; Canvas: TCanvas; PixelsPerInch: Integer);
var
ImageCanvas: TCanvas;
fmt: TFormatRange;
begin
ImageCanvas := Canvas;
with fmt do
begin
hdc:= ImageCanvas.Handle;
hdcTarget:= hdc;
rc:= Rect(0, 0,
ImageCanvas.ClipRect.Right * 1440 div PixelsPerInch,
ImageCanvas.ClipRect.Bottom * 1440 div PixelsPerInch);
rcPage:= rc;
chrg.cpMin := 0;
chrg.cpMax := RichEdit.GetTextLen;
end;
SetBkMode(ImageCanvas.Handle, TRANSPARENT);
RichEdit.Perform(EM_FORMATRANGE, 1, Integer(@fmt));
RichEdit.Perform(EM_FORMATRANGE, 0, 0);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RichEditToCanvas(RichEdit1, Image1.Canvas, Self.PixelsPerInch);
Image1.Refresh;
end;

TRichEdit的打印预览

Rich Edit控件(我们说的是标准的Windows控件,不是一个Delphi构件)包含内置的打印特性,可以使用这个特性向打印机传送格式化的文本,或是通过程序员稍微地努力就可将它的内容绘制到任何Canvas上。
当然,标准的Delphi TRichEdit构件封装了这一特性。我们可以使用这一可能性来制作一个快速的比例缩放的打印预览,或者将Rich Text绘制到任何Delphi控件上。
将Rich Edit控件绘制到任何Canvas上,涉及使用标准Rich Edit控件消息EM_FORMATRANGE。
这个消息的lParam参数是一个指向TFormatRange纪录的指针。在将消息传递给RichEdit之前,必须填充这个记录。
TFORMATRANGE记录包含一个rich edit控件用于格式化输出它的内容到特定设备的信息。这里的
hdc —— 要渲染的设备。
HdcTarget —— 要格式化的目标设备。
rc —— 要渲染的区域。使用的测量单位是缇。缇是一种不受屏幕约束(screen-independent)的单位,以确保屏幕元素的比例在所有显示系统上都相同。一缇被定义为一英寸的1/1440。
RcPage —— 渲染设备的整个区域。使用的测量单位是缇。
chrg —— TCHARRANGE记录指定了格式化文本的范围。
这个记录通常被EM_EXGETSEL和EM_EXSETSEL消息使用,它包含两个域:cpMin和cpMax。
 
cpMin 是一个字符位置索引,直接位于范围内第一个字符之前。
cpMax 是一个字符位置索引,直接位于范围内最后一个字符之后。
打印一个Rich Edit控件到一个位图上用于预览
 

完整页代码:
   unit Unit1;  
      
    interface  
      
   uses  
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
   Dialogs, StdCtrls, ComCtrls, ExtCtrls, RichEdit;  
     
    type  
  TForm1 = class(TForm)  
  Button1: TButton;  
  Button2: TButton;  
   Image1: TImage;  
  RichEdit1: TRichEdit;  
  procedure Button1Click(Sender: TObject);  
  procedure Button2Click(Sender: TObject);  
  private  
   { Private declarations }  
   public  
  { Public declarations }  
   end;  
   
 var  
   Form1: TForm1;  
 
  implementation  
    
   {$R *.dfm}  
     
  function PrintRTFToBitmap(ARichEdit : TRichEdit; ABitmap : TBitmap) : Longint;
var
  range : TFormatRange;
begin
   FillChar(Range, SizeOf(TFormatRange), 0);
   // 渲染我们要测量的相同DC。
   Range.hdc        := ABitmap.Canvas.handle;
   Range.hdcTarget  := ABitmap.Canvas.Handle;
   // 设定页。
   Range.rc.left    := 0;
   Range.rc.top     := 0;
   Range.rc.right   := ABitmap.Width * 1440 div Screen.PixelsPerInch;
   Range.rc.Bottom  := ABitmap.Height * 1440 div Screen.PixelsPerInch;
   // 打印文本的缺省范围为整个文档。
   Range.chrg.cpMax := -1;
   Range.chrg.cpMin := 0;
   // 格式化文本。
   Result := SendMessage(ARichedit.Handle, EM_FORMATRANGE, 1, Longint(@Range));
   // 释放缓冲信息。
   SendMessage(ARichEdit.handle, EM_FORMATRANGE, 0,0);
   //Image1.Refresh;
end;
 // 接下来的实例显示了不只是如何将Rich Edit绘制到任何Canvas上,还包括如何只绘制选择的文本范围。
function PrintToCanvas(ACanvas : TCanvas; FromChar, ToChar : integer;
                      ARichEdit : TRichEdit; AWidth, AHeight : integer) : Longint;
var
  Range : TFormatRange;
begin
    FillChar(Range, SizeOf(TFormatRange), 0);
    Range.hdc        := ACanvas.handle;
    Range.hdcTarget  := ACanvas.Handle;
    Range.rc.left    := 0;
    Range.rc.top     := 0;
    Range.rc.right   := AWidth * 1440 div Screen.PixelsPerInch;
    Range.rc.Bottom  := AHeight * 1440 div Screen.PixelsPerInch;
    Range.chrg.cpMax := ToChar;
    Range.chrg.cpMin := FromChar;
    Result := SendMessage(ARichedit.Handle, EM_FORMATRANGE, 1, Longint(@Range));
   SendMessage(ARichEdit.handle, EM_FORMATRANGE, 0,0);
end;
  {use PrintRTFToBitmap function}  
 procedure TForm1.Button1Click(Sender: TObject);  
   var  
   Bmp: TBitmap;  
  begin  
   Bmp := TBitmap.Create;  
   bmp.Width := RichEdit1.ClientWidth;  
   bmp.Height := RichEdit1.ClientHeight;  
  PrintRTFToBitmap(RichEdit1, Bmp);  
 Image1.Canvas.Draw(0, 0, Bmp);  
   bmp.Free;  
  end;  
    
  {use PrintToCanvas function}  
  procedure TForm1.Button2Click(Sender: TObject);  
   var  
    Bmp: TBitmap;  
   begin  
      Bmp := TBitmap.Create;  
      bmp.Width := RichEdit1.ClientWidth;  
      bmp.Height := RichEdit1.ClientHeight;  
      PrintToCanvas(bmp.Canvas, 0, Length(RichEdit1.Text), RichEdit1, Bmp.Width, Bmp.Height);  
       Image1.Canvas.Draw(0, 0, Bmp);  
       bmp.Free;  
   end;  
     
  end.  
View Code

richviewedit表格设置

table.BorderStyle := rvtbRaisedColor;
  table.CellBorderStyle := rvtbLoweredColor;
  table.BorderLightColor := $00FAF1C9;
  table.BorderColor := $00A98E10;
  table.CellBorderLightColor := $00FAF1C9;
  table.CellBorderColor := $00A98E10;
  table.Color := $00EAC724;
  table.BorderWidth := 0;
  table.CellBorderWidth := 2;
  table.CellPadding := 1;
  table.CellVSpacing := 1;
  table.CellHSpacing := 1;
  table.BorderVSpacing := 1;
  table.BorderHSpacing := 1;
View Code

richviewedit弹出对话框插入链接

FrmUrl.Edit1.Text := Target;
  if FrmUrl.ShowModal = mrOk then
  begin
    Target := FrmUrl.Edit1.Text;
    if rve.SelectionExists then
    begin
      if Target = '' then
        rve.ApplyStyleConversion(CONVERT_TO_NONHYPERTEXT)
      else
        rve.ApplyStyleConversion(CONVERT_TO_HYPERTEXT);
      SetTargetToSelection(Target);
    end
    else if Target = '' then
      Beep
    else
    begin
      rve.CurTextStyleNo := GetHypertextStyleNo(rve.CurTextStyleNo);
      rve.InsertStringTag(FrmUrl.Edit2.Text, Target);
    end;
  end;
View Code

richviewedit压缩保存更新

procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
var
query: TUniQuery;
UniConnection:TUniConnection;
mstream: TStream;
//Stream:TMemoryStream;
begin
  if Self.Tag=1 then
  begin
   //需要对文本改变事件进行保存
   query:=TUniQuery.Create(nil);
   UniConnection:=TUniConnection.Create(nil);
   IF Application.MessageBox('文本已经改变是否保存!','警告',MB_OKCANCEL)=ID_OK then
   begin
   try
        try
           if RichViewEdit1.Modified then   //当已打开的文件被修改了以后
            begin
            mstream:=TMemoryStream.Create;
            //des:= TStringStream.create('');
            //Stream:=TMemoryStream.Create;
            //RxRichEdit1.Lines.SaveToStream(mstream);//需要对这个流文件进行压缩
            //RxRichEdit1.Lines.SaveToStream(Stream);//需要对这个流文件进行压缩
            Sqlite_Open(Self.Hint,KeyPwd,UniConnection);
            query.Connection:=uniConnection;
            query.SQL.Text :='UPDATE Rich SET F_Con = :F_Con WHERE id = :id' ;
            query.ParamByName('id').AsString := TitleLbl.Hint;
            RichViewEdit1.SaveRTFToStream(mstream,false);
            mStream.Position :=0;
            query.ParamByName('F_Con').LoadFromStream(mStream, DB.ftBlob);
            //query.ParamByName('F_Con').LoadFromStream(CompressionStream(Stream), DB.ftBlob);
            query.Execute;
            mStream.Free;
            end;
         except
            begin end
         end;
      finally
         query.Free;
         UniConnection.Free;
      end;
      end;
      end;
  Action := caFree;

end;
procedure TMainForm.UpdateRich(Sender: TObject;ID,Title,DBPath:string);
var
query:TUniQuery;
Conn:TUniConnection;
Child: TMDIChild;
Stream:TStream;
begin
try
      Child:=TMDIChild(Sender);
      Conn:=TUniConnection.Create(nil);
      Sqlite_Open(DBPath,KeyPwd,Conn);
      query:=TUniQuery.create(nil);
      query.Connection := Conn;
      query.SQL.Clear;
      query.SQL.Add('Select id,N_name,F_Con from Rich where id=:id');
      query.ParamByName('id').AsString := ID;//NodeID;
      query.Open;
      if query.RecordCount>0 then
          if not query.FieldByName('F_Con').IsNull then
          begin
           Child.TitleLbl.Caption:=query.FieldByName('N_name').AsString;
           Child.RichViewEdit1.BeginUpdate;
           Stream:=TMemoryStream.Create;
           TBlobField(query.FieldByName('F_Con')).SaveToStream(Stream);
           Stream.Position := 0;
           Child.RichViewEdit1.LoadRTFFromStream(Stream);
           Child.RichViewEdit1.Format;
           //Stream:=TMemoryStream.Create;
           //TBlobField(query.FieldByName('F_Con')).SaveToStream(Stream);
           //Child.rxRichEdit1.Lines.LoadFromStream(UnCompressionStream(Stream));
           //Child.rxrichedit1.Lines.EndUpdate;
           Child.RichViewEdit1.EndUpdate;
           //Stream.Free;
          End
          else
          begin
           Child.TitleLbl.Caption:=Title;
           //Child.rxrichedit1.Clear;
           Child.RichViewEdit1.Clear;
          end
          else
          begin
           Child.TitleLbl.Caption:=Title;
           //Child.rxrichedit1.Clear;
           Child.RichViewEdit1.Clear;
          end;
      query.close;
      query.Free;
      Conn.Free;
      except
      end;
end;
View Code

查询表是否存在

cmd.CommandText = "SELECT COUNT(*) FROM sqlite_master where type='table' and name='DBInfo'";
View Code

原文地址:https://www.cnblogs.com/blogpro/p/11453162.html