MainAppFrm.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:4k
源码类别:

RichEdit

开发平台:

Delphi

  1. {==============================================================================}
  2. {
  3.   Mail merge application: part 2 - displaying processed template.
  4.   How it works:
  5.   - RVStyle2 has two predefined styles (the same as in the template editor;
  6.     1th text style is reserved for fields).
  7.   - RichView1 and RichView2 are linked to the same RVStyle (RVStyle2)
  8.   - Template is loaded in RichView1 (styles can be added dynamically in RVStyle2)
  9.   - RichView1 is scanned for fields. When field is found, it is deleted,
  10.     and its value is inserted in its place:
  11.     * field value is loaded in invisible RichView2 (styles can be added in RVStyle2)
  12.     * contents of RichView2 is inserted in the proper place of RichView1.
  13. }
  14. {==============================================================================}
  15. unit MainAppFrm;
  16. interface
  17. uses
  18.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  19.   Dialogs, RVScroll, RichView, RVStyle, DB, DBTables, CRVFData, RVTable;
  20. type
  21.   TForm1 = class(TForm)
  22.     RichView1: TRichView;
  23.     RichView2: TRichView;
  24.     Table1: TTable;
  25.     RVStyle2: TRVStyle;
  26.     procedure FormCreate(Sender: TObject);
  27.   private
  28.     procedure ReplaceFields(RVData: TCustomRVFormattedData);
  29.     { Private declarations }
  30.   public
  31.     { Public declarations }
  32.     function LoadData(const Code: String): TMemoryStream;
  33.   end;
  34. var
  35.   Form1: TForm1;
  36. implementation
  37. {$R *.dfm}
  38. procedure TForm1.FormCreate(Sender: TObject);
  39. begin
  40.   // Loading template with fields
  41.   RichView1.LoadRVF(ExtractFilePath(Application.ExeName)+'Template.rvf');
  42.   // RVData.InsertFromStream (we will call it later) does not support
  43.   // style merging. So changing mode to style ignoring:
  44.   RichView1.RVFParaStylesReadMode := rvf_sIgnore;
  45.   RichView1.RVFTextStylesReadMode := rvf_sIgnore;
  46.   // Replace styles with values
  47.   ReplaceFields(RichView1.RVData);
  48.   RichView1.Format;
  49. end;
  50. procedure TForm1.ReplaceFields(RVData: TCustomRVFormattedData);
  51. var i,j: Integer;
  52.     Stream: TMemoryStream;
  53.     Dummy1: TColor;
  54.     Dummy2, Dummy3: Pointer;
  55.     ParaNo: Integer;
  56.     BR, ContinuePara: Boolean;
  57.     table: TRVTableItemInfo;
  58.     r,c: Integer;
  59. begin
  60.   Dummy1 := clNone;
  61.   Dummy2 := nil;
  62.   Dummy3 := nil;
  63.   for i := RVData.ItemCount-1 downto 0 do
  64.     case RVData.GetItemStyle(i) of
  65.       1: // the first text style is used for fields
  66.         begin
  67.           // storing parameters of deleted items
  68.           ParaNo := RVData.GetItemPara(i);
  69.           BR     := RVData.GetItem(i).BR;
  70.           ContinuePara := RVData.GetItem(i).SameAsPrev;
  71.           // loading field value in the stream
  72.           Stream := LoadData(RVData.GetItemTextA(i));
  73.           if Stream<>nil then begin
  74.             // deleting the field code
  75.             RVData.DeleteItems(i,1); 
  76.             // inserting the field value
  77.             RVData.InsertRVFFromStream(Stream, i, Dummy1, Dummy2, Dummy3, False);
  78.             // applying stored parameters to the inserted items
  79.             for j := i to RVData.ItemCount-1 do begin
  80.               if (i=j) then begin
  81.                 RVData.GetItem(j).SameAsPrev := ContinuePara;
  82.                 if BR then
  83.                   RVData.GetItem(j).BR := True;
  84.               end;
  85.               if (j>i) and RVData.IsParaStart(j) then
  86.                 break;
  87.               RVData.GetItem(j).ParaNo := ParaNo;
  88.             end;
  89.             Stream.Free;
  90.           end;
  91.         end;
  92.       rvsTable:
  93.         begin
  94.           // recursive call for table cells
  95.           table := TRVTableItemInfo(RVData.GetItem(i));
  96.           for r := 0 to table.Rows.Count-1 do
  97.             for c := 0 to table.Rows[r].Count-1 do
  98.               if table.Cells[r,c]<>nil then
  99.                 ReplaceFields(table.Cells[r,c]);
  100.         end;
  101.     end;
  102.   RVData.Normalize;
  103. end;
  104. // Loading field code
  105. function TForm1.LoadData(const Code: String): TMemoryStream;
  106. begin
  107.   Result := nil;
  108.   if not Table1.Locate('Code', Code, []) then
  109.     exit;
  110.   Result := TMemoryStream.Create;
  111.   TBlobField(Table1.FieldByName('Data')).SaveToStream(Result);
  112.   Result.Position := 0;
  113.   RichView2.Clear;
  114.   RichView2.InsertRVFFromStream(Result, 0); // inserting will merge styles;
  115.     // RichView1 and RichView2 have the same collections of styles
  116.   Result.Clear;
  117.   RichView2.SaveRVFToStream(Result, False);
  118.   Result.Position := 0;
  119. end;
  120. end.