MMMainFrm.cpp
上传用户: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. #include <vcl.h>
  16. #pragma hdrstop
  17. #include "MMMainFrm.h"
  18. //---------------------------------------------------------------------------
  19. #pragma package(smart_init)
  20. #pragma link "RichView"
  21. #pragma link "RVScroll"
  22. #pragma link "RVStyle"
  23. #pragma resource "*.dfm"
  24. TForm1 *Form1;
  25. //---------------------------------------------------------------------------
  26. __fastcall TForm1::TForm1(TComponent* Owner)
  27.     : TForm(Owner)
  28. {
  29. }
  30. //---------------------------------------------------------------------------
  31. void __fastcall TForm1::FormCreate(TObject *Sender)
  32. {
  33.   // Loading template with fields
  34.   RichView1->LoadRVF(ExtractFilePath(Application->ExeName)+"Template.rvf");
  35.   // RVData->InsertFromStream() (we will call it later) does not support
  36.   // style merging. So changing mode to style ignoring:
  37.   RichView1->RVFParaStylesReadMode = rvf_sIgnore;
  38.   RichView1->RVFTextStylesReadMode = rvf_sIgnore;
  39.   // Replace styles with values
  40.   ReplaceFields(RichView1->RVData);
  41.   RichView1->Format();
  42. }
  43. //---------------------------------------------------------------------------
  44. void TForm1::ReplaceFields(TCustomRVFormattedData* RVData)
  45. {
  46.   TColor Dummy1 = clNone;
  47.   TRVBackground * Dummy2 = NULL;
  48.   TRVLayoutInfo * Dummy3 = NULL;
  49.   for (int i=RVData->ItemCount-1; i>=0; i--)
  50.   {
  51.     switch (RVData->GetItemStyle(i))
  52.     {
  53.       case 1: // the first text style is used for fields
  54.       {
  55.         // storing parameters of deleted items
  56.         int ParaNo = RVData->GetItemPara(i);
  57.         bool BR    = RVData->GetItem(i)->BR;
  58.         bool ContinuePara = RVData->GetItem(i)->SameAsPrev;
  59.         // loading field value in the stream
  60.         TMemoryStream* Stream;
  61.         LoadData(RVData->GetItemTextA(i), Stream);
  62.         if (Stream)
  63.         {
  64.           // deleting the field code
  65.           RVData->DeleteItems(i,1);
  66.           // inserting the field value
  67.           RVData->InsertRVFFromStream(Stream, i, Dummy1, Dummy2, Dummy3, false);
  68.           // applying stored parameters to the inserted items
  69.           for (int j = i; j<RVData->ItemCount; j++)
  70.           {
  71.             if (i==j)
  72.             {
  73.               RVData->GetItem(j)->SameAsPrev = ContinuePara;
  74.               if (BR)
  75.                 RVData->GetItem(j)->BR = true;
  76.             }
  77.             if (j>i && RVData->IsParaStart(j))
  78.               break;
  79.             RVData->GetItem(j)->ParaNo = ParaNo;
  80.           }
  81.           delete Stream;
  82.         }
  83.         break;
  84.       }
  85.       case rvsTable:
  86.       {
  87.         // recursive call for table cells
  88.         TRVTableItemInfo* table = (TRVTableItemInfo*)(RVData->GetItem(i));
  89.         for (int r=0; r<table->Rows->Count; r++)
  90.           for (int c=0; c<table->Rows->Items[r]->Count; c++)
  91.             if (table->Cells[r][c])
  92.               ReplaceFields(table->Cells[r][c]);
  93.         break;
  94.       }
  95.     }
  96.   }
  97.   RVData->Normalize();
  98. }
  99. //---------------------------------------------------------------------------
  100. // Loading field code
  101. void TForm1::LoadData(const AnsiString Code, TMemoryStream* &Stream)
  102. {
  103.   TLocateOptions SearchOptions;
  104.   if (! Table1->Locate("Code", Code, SearchOptions))
  105.     return;
  106.   Stream = new TMemoryStream;
  107.   ((TBlobField*)(Table1->FieldByName("Data")))->SaveToStream(Stream);
  108.   Stream->Position = 0;
  109.   RichView2->Clear();
  110.   RichView2->InsertRVFFromStream(Stream, 0); // inserting will merge styles;
  111.     // RichView1 and RichView2 have the same collections of styles
  112.   Stream->Clear();
  113.   RichView2->SaveRVFToStream(Stream, false);
  114.   Stream->Position = 0;
  115.   return;
  116. }