unit Unit1;

interface
{$I RV_Defs.inc}
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  RVStyle, RVScroll, RichView, RVEdit, PtblRV, RVMisc, CtrlImg,
  {$IFDEF RICHVIEWDEF3}
  jpeg,
  {$ENDIF}
  {$IFDEF RICHVIEWDEF4}
  ImgList,
  {$ENDIF}
  Clipbrd, StdCtrls, ExtCtrls, ComCtrls, Menus, OleCtnrs;

type
  TForm1 = class(TForm)
    RichViewEdit1: TRichViewEdit;
    il: TImageList;
    StatusBar1: TStatusBar;
    MainMenu1: TMainMenu;
    mpdInsert: TMenuItem;
    mitPicture: TMenuItem;
    mpdComponent: TMenuItem;
    mitButtonComp: TMenuItem;
    mitEditBoxComp: TMenuItem;
    mitBreak: TMenuItem;
    OpenDialog1: TOpenDialog;
    Panel1: TPanel;
    cmbText: TComboBox;
    cmbPara: TComboBox;
    RVStyle1: TRVStyle;
    mpdFile: TMenuItem;
    mitLoadText: TMenuItem;
    N1: TMenuItem;
    mitExit: TMenuItem;
    mpdBullet: TMenuItem;
    mitHelpIcon: TMenuItem;
    mitHelpSearchIcon: TMenuItem;
    mitPropertiesIcon: TMenuItem;
    mitLoadRVF: TMenuItem;
    mitSaveRVF: TMenuItem;
    SaveDialog1: TSaveDialog;
    N2: TMenuItem;
    mitClear: TMenuItem;
    mpdEdit: TMenuItem;
    mitCopy: TMenuItem;
    mitPaste: TMenuItem;
    mitCut: TMenuItem;
    mitDelete: TMenuItem;
    PasteAs1: TMenuItem;
    mitPasteAsText: TMenuItem;
    mitPasteAsMetafile: TMenuItem;
    mitPasteAsBitmap: TMenuItem;
    mitPasteAsRVF: TMenuItem;
    N3: TMenuItem;
    mitEditCheckpoint: TMenuItem;
    mitEditProps: TMenuItem;
    PopupMenu1: TPopupMenu;
    mitEditProp1: TMenuItem;
    mitEditCheckpoint1: TMenuItem;
    mpdHotspot: TMenuItem;
    mitAddImageHS: TMenuItem;
    mitAddTextHS: TMenuItem;
    mitSelectAll: TMenuItem;
    mpdMisc: TMenuItem;
    mitSaveHTML: TMenuItem;
    N4: TMenuItem;
    mitPrint: TMenuItem;
    RVPrint1: TRVPrint;
    N5: TMenuItem;
    mitSavePictureBodiesinRVF: TMenuItem;
    mitSaveControlBodiesinRVF: TMenuItem;
    mitRVFIgnoreunknownpictureformats: TMenuItem;
    mitRVFIgnoreunknowncontrols: TMenuItem;
    mitRVFConvertunknownstylesto0: TMenuItem;
    mitRVFConvertTooLargeImageIndicesto0: TMenuItem;
    FindDialog1: TFindDialog;
    N6: TMenuItem;

    mitSearch: TMenuItem;
    mpdView: TMenuItem;
    mitCheckPointList: TMenuItem;
    N7: TMenuItem;
    mitSaveRVFSel: TMenuItem;
    mitRVFSaveBinary: TMenuItem;
    mitPasteAsOLE: TMenuItem;
    N8: TMenuItem;
    mitPreview: TMenuItem;
    mitNoBitmap: TMenuItem;
    mitStretched: TMenuItem;
    mitTiled: TMenuItem;
    mitTiledScrolled: TMenuItem;
    mitCentered: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure mitPictureClick(Sender: TObject);
    procedure mitButtonCompClick(Sender: TObject);
    procedure mitEditBoxCompClick(Sender: TObject);
    procedure RichViewEdit1CurParaStyleChanged(Sender: TObject);
    procedure RichViewEdit1CurTextStyleChanged(Sender: TObject);
    procedure cmbParaClick(Sender: TObject);
    procedure cmbTextClick(Sender: TObject);
    procedure mitBreakClick(Sender: TObject);
    procedure mitExitClick(Sender: TObject);
    procedure mitInsertBulletClick(Sender: TObject);
    procedure mitLoadTextClick(Sender: TObject);
    procedure mitSaveRVFClick(Sender: TObject);
    procedure mitLoadRVFClick(Sender: TObject);
    procedure mitClearClick(Sender: TObject);
    procedure mpdEditClick(Sender: TObject);
    procedure RichViewEdit1Select(Sender: TObject);
    procedure mitPasteAsBitmapClick(Sender: TObject);
    procedure mitPasteAsMetafileClick(Sender: TObject);
    procedure mitPasteAsTextClick(Sender: TObject);
    procedure mitPasteClick(Sender: TObject);
    procedure mitDeleteClick(Sender: TObject);
    procedure mitCutClick(Sender: TObject);
    procedure mitCopyClick(Sender: TObject);
    procedure mitEditCheckpointClick(Sender: TObject);
    procedure RichViewEdit1RVRightClickEx(Sender: TRichView; LineNo, Style,
      X, Y: Integer);
    procedure mitAddHSClick(Sender: TObject);
    procedure mitSelectAllClick(Sender: TObject);
    procedure mitEditPropsClick(Sender: TObject);
    procedure mitSaveHTMLClick(Sender: TObject);
    procedure mitPrintClick(Sender: TObject);
    procedure mitRVFOptionsClick(Sender: TObject);
    procedure mpdMiscClick(Sender: TObject);
    procedure RichViewEdit1RVFPictureNeeded(Sender: TRichView; Name: String; Tag: Integer;
      var gr: TGraphic);
    procedure RichViewEdit1RVFControlNeeded(Sender: TRichView; Name: String; Tag: Integer;
      var ctrl: TControl);
    procedure RichViewEdit1RVFImageListNeeded(Sender: TRichView; ImageListTag: Integer;
      var il: TImageList);
    procedure mitSearchClick(Sender: TObject);
    procedure FindDialog1Find(Sender: TObject);
    procedure mitCheckPointListClick(Sender: TObject);
    procedure mitSaveRVFSelClick(Sender: TObject);
    procedure mitPasteAsRVFClick(Sender: TObject);
    procedure mitPasteAsOLEClick(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
    procedure mitPreviewClick(Sender: TObject);
    procedure RVPrint1PrintComponent(Sender: TRVPrint;
      PrintMe: TControl; var ComponentImage: TBitmap);
    procedure mitBackClick(Sender: TObject);
    procedure RichViewEdit1SaveComponentToFile(Sender: TRichView;
      Path: String; SaveMe: TPersistent; SaveFormat: TRVSaveFormat;
      var OutStr: String);
  private
    { Private declarations }
    procedure OnOleResize(Sender: TObject);
    procedure OnOleActions(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses CPFrm, PropFrm, ListFrm, PreviewFrm;

{$R *.DFM}

{ This demo uses conditional defines from RV_Defs.inc (see include
  directive at the beginnning of this file)
  RICHVIEWDEF3 is defined, if there is Delphi3 or later or C++Builder 3 or later
  RICHVIEWDEF4 is defined, if there is Delphi4 or later
}

procedure TForm1.FormCreate(Sender: TObject);
begin
   if Application.MessageBox('Press OK to set "Tags are PChars" mode', 'Choose tag mode', MB_OKCANCEL)=IDOK then
     RichViewEdit1.Options := RichViewEdit1.Options+[rvoTagsArePChars];
   cmbPara.Items.Assign(RVStyle1.ParaStyles);
   cmbText.Items.Assign(RVStyle1.TextStyles);
   RichViewEdit1.Format;
   cmbPara.ItemIndex := RichViewEdit1.CurParaStyleNo;
   cmbText.ItemIndex := RichViewEdit1.CurTextStyleNo;
end;
{======================================================================}
{ Font and paragraph combos                                            }
{======================================================================}
procedure TForm1.RichViewEdit1CurParaStyleChanged(Sender: TObject);
begin
   cmbPara.ItemIndex := RichViewEdit1.CurParaStyleNo;
end;
{----------------------------------------------------------------------}
procedure TForm1.RichViewEdit1CurTextStyleChanged(Sender: TObject);
begin
   cmbText.ItemIndex := RichViewEdit1.CurTextStyleNo;
end;
{----------------------------------------------------------------------}
procedure TForm1.cmbParaClick(Sender: TObject);
begin
   RichViewEdit1.ApplyParaStyle(cmbPara.ItemIndex);
   RichViewEdit1.SetFocus;
end;
{----------------------------------------------------------------------}
procedure TForm1.cmbTextClick(Sender: TObject);
begin
   RichViewEdit1.ApplyTextStyle(cmbText.ItemIndex);
   RichViewEdit1.SetFocus;
end;
{======================================================================}
{ Main menu: "File"                                                    }
{======================================================================}
{ File|Load Text... ---------------------------------------------------}
procedure TForm1.mitLoadTextClick(Sender: TObject);
var a,b: Integer;
begin
  OpenDialog1.Title := 'Loading Text';
  OpenDialog1.Filter := 'Text|*.txt|All|*.*';
  if OpenDialog1.Execute then begin
    Screen.Cursor := crHourglass;
    a := cmbText.ItemIndex;
    b := cmbPara.ItemIndex;
    RichViewEdit1.Clear;
    RichViewEdit1.LoadText(OpenDialog1.FileName,a,b);
    RichViewEdit1.Format;
    RichViewEdit1.Invalidate;
    cmbPara.ItemIndex := RichViewEdit1.CurParaStyleNo;
    cmbText.ItemIndex := RichViewEdit1.CurTextStyleNo;
    Screen.Cursor := crDefault;
  end;
end;
{ File|Load RVF... ----------------------------------------------------}
procedure TForm1.mitLoadRVFClick(Sender: TObject);
begin
  OpenDialog1.Title := 'Loading RVF';
  OpenDialog1.Filter := 'RichView Format Files|*.rvf|All|*.*';
  if OpenDialog1.Execute then begin
    Screen.Cursor := crHourglass;
    if not RichViewEdit1.LoadRVF(OpenDialog1.FileName) then begin
      Application.MessageBox('Error during loading', 'Error', 0);
      RichViewEdit1.Clear;
    end;
    RichViewEdit1.Format;
    RichViewEdit1.Invalidate;
    cmbPara.ItemIndex := RichViewEdit1.CurParaStyleNo;
    cmbText.ItemIndex := RichViewEdit1.CurTextStyleNo;
    Screen.Cursor := crDefault;
  end;
end;
{ Event: picture needed while reading from RVF ------------------------}
procedure TForm1.RichViewEdit1RVFPictureNeeded(Sender: TRichView; Name: String;
                                               Tag: Integer; var gr: TGraphic);
begin
  gr := TBitmap.Create;
  gr.LoadFromFile(ExtractFilePath(Application.ExeName)+'default.bmp');
end;
{ Event: control needed while reading from RVF ------------------------}
procedure TForm1.RichViewEdit1RVFControlNeeded(Sender: TRichView; Name: String;
                                               Tag: Integer; var ctrl: TControl);
begin
  ctrl := TButton.Create(RichViewEdit1);
  TButton(ctrl).Caption := 'from file';
end;
{ Event: imagelist needed while reading from RVF ----------------------}
procedure TForm1.RichViewEdit1RVFImageListNeeded(Sender: TRichView;
                                                 ImageListTag: Integer;
                                                  var il: TImageList);
begin
  il := Self.il;
end;
{ File|Save RVF... ----------------------------------------------------}
procedure TForm1.mitSaveRVFClick(Sender: TObject);
begin
  SaveDialog1.Title := 'Saving RVF';
  SaveDialog1.Filter := 'rvf files(*.rvf)|*.rvf|All(*.*)|*.*';
  SaveDialog1.DefaultExt := 'rvf';
  if SaveDialog1.Execute then begin
    Screen.Cursor := crHourglass;
    if not RichViewEdit1.SaveRVF(SaveDialog1.FileName, False) then
      Application.MessageBox('Error during saving', 'Error', 0);
    Screen.Cursor := crDefault;
  end;
end;
{ File|Save Selection as RVF... ---------------------------------------}
procedure TForm1.mitSaveRVFSelClick(Sender: TObject);
begin
  SaveDialog1.Title := 'Saving RVF';
  SaveDialog1.Filter := 'rvf files(*.rvf)|*.rvf|All(*.*)|*.*';
  SaveDialog1.DefaultExt := 'rvf';
  if SaveDialog1.Execute then begin
    Screen.Cursor := crHourglass;
    if not RichViewEdit1.SaveRVF(SaveDialog1.FileName, True) then
      Application.MessageBox('Error during saving', 'Error', 0);
    Screen.Cursor := crDefault;
  end;
end;
{ File|Save HTML... ---------------------------------------------------}
procedure TForm1.mitSaveHTMLClick(Sender: TObject);
begin
  SaveDialog1.Title := 'Saving HTML';
  SaveDialog1.DefaultExt := 'htm';
  SaveDialog1.Filter := 'html files(*.htm;*.html)|*.htm;*.html|All(*.*)|*.*';
  if SaveDialog1.Execute then begin
    Screen.Cursor := crHourglass;
    if not RichViewEdit1.SaveHTMLEx(SaveDialog1.FileName,'Demo File','img',
      '','','',[rvsoOverrideImages]) then
      Application.MessageBox('Error during saving', 'Error', 0);
    Screen.Cursor := crDefault;
  end;
end;
{ Event: saving controls in HTML --------------------------------------}
procedure TForm1.RichViewEdit1SaveComponentToFile(Sender: TRichView;
  Path: String; SaveMe: TPersistent; SaveFormat: TRVSaveFormat;
  var OutStr: String);
begin
  case SaveFormat of
   rvsfText:
      begin
      end;
   rvsfHTML:
       begin
         if SaveMe is TButton then begin
           OutStr := '<INPUT type="button" value="'+TButton(SaveMe).Caption+'" '+
                     'onClick="alert(''Just a demo?'')">';
           exit;
         end;
         if SaveMe is TEdit then begin
           OutStr := '<INPUT type="text" value="'+TEdit(SaveMe).Text+'"';
           exit;
         end;
       end;
   end;
end;
{ File|Clear ----------------------------------------------------------}
procedure TForm1.mitClearClick(Sender: TObject);
begin
   RichViewEdit1.SetFocus;
   RichViewEdit1.Clear;
   RichViewEdit1.Format;
   RichViewEdit1.Invalidate;
   cmbPara.ItemIndex := RichViewEdit1.CurParaStyleNo;
   cmbText.ItemIndex := RichViewEdit1.CurTextStyleNo;
end;
{ File|Print Preview --------------------------------------------------}
procedure TForm1.mitPreviewClick(Sender: TObject);
begin
  RVPrint1.AssignSource(RichViewEdit1);
  RVPrint1.FormatPages(rvdoALL);
  if RVPrint1.PagesCount>0 then begin
    frmPreview.rvpp.RVPrint := RVPrint1;
    frmPreview.Button1Click(nil); //  Show First Page
    frmPreview.ShowModal;
  end;
end;
{ File|Print on Default Printer ---------------------------------------}
procedure TForm1.mitPrintClick(Sender: TObject);
begin
  RVPrint1.AssignSource(RichViewEdit1);
  RVPrint1.FormatPages(rvdoALL);
  if RVPrint1.PagesCount>0 then
    RVPrint1.Print('RichView Edit Demo',1,False);
end;
{ Event: making image of  controls for printing -----------------------}
procedure TForm1.RVPrint1PrintComponent(Sender: TRVPrint;
  PrintMe: TControl; var ComponentImage: TBitmap);
var r: TRect;
begin
  if PrintMe is TButton then
    ComponentImage := DrawButton(PrintMe as TButton)
  else if PrintMe is TEdit then
    ComponentImage := DrawEdit(PrintMe as TEdit)
  else if PrintMe is TOleContainer then begin
    ComponentImage := TBitmap.Create;
    ComponentImage.Width  := PrintMe.Width;
    ComponentImage.Height := PrintMe.Height;
    r := Bounds(0,0,PrintMe.Width,PrintMe.Height);
    with r do
      ComponentImage.Canvas.Rectangle(Left,Top,Right,Bottom);
    InflateRect(r,-1,-1);
    DrawText(ComponentImage.Canvas.Handle, PChar(TOleContainer(PrintMe).OleClassName),-1,
             r, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
  end;
end;
{ File|Exit -----------------------------------------------------------}
procedure TForm1.mitExitClick(Sender: TObject);
begin
  Close;
end;
{======================================================================}
{ Main menu: "Insert"                                                  }
{======================================================================}
{ Insert|Picture... ---------------------------------------------------}
procedure TForm1.mitPictureClick(Sender: TObject);
var gr: TGraphic;
    ext: String;
begin
  OpenDialog1.Title := 'Inserting Image';
  {$IFDEF RICHVIEWDEF3}
  OpenDialog1.Filter := 'Graphics(*.bmp;*.wmf;*.ico;*.jpg)|*.bmp;*.wmf;*.ico;*.jpg|All(*.*)|*.*';
  {$ELSE}
  OpenDialog1.Filter := 'Graphics(*.bmp;*.wmf;*.ico)|*.bmp;*.wmf;*.ico|All(*.*)|*.*';
  {$ENDIF}
  if OpenDialog1.Execute then begin
    gr := nil;
    ext := UpperCase(ExtractFileExt(OpenDialog1.FileName));
    {$IFDEF RICHVIEWDEF3}
    if (ext='.JPG') or (ext='.JPEG') then
      gr := TJPegImage.Create
    else
   {$ENDIF}
    if (ext='.BMP')or(ext='.DIB') then
      gr := TBitmap.Create
    else if ext='.ICO' then
      gr := TIcon.Create
    else if (ext='.WMF') or (ext='.EMF') then
      gr := TMetafile.Create;
    if gr<>nil then begin
      gr.LoadFromFile(OpenDialog1.FileName);
      RichViewEdit1.InsertPicture('',gr,rvvaBaseLine);
    end;
  end;
end;
{ Insert|Component|Button ---------------------------------------------}
procedure TForm1.mitButtonCompClick(Sender: TObject);
var btn: TButton;
const Captions: array[0..9] of String =
       (
       'Help','Exit','Cancel','Ok','Close','Run','Options...','Minimize',
       'Hide','Show'
       );
begin
  btn := TButton.Create(Self);
  btn.Caption := Captions[Random(10)];
  RichViewEdit1.InsertControl('',btn,rvvaBaseline);
end;
{ Insert|Component|Edit Box -------------------------------------------}
procedure TForm1.mitEditBoxCompClick(Sender: TObject);
var edt: TEdit;
const Captions: array[0..9] of String =
       (
       '0','Hello','1','$0','2x2=4','really cool!','x<y','don'' turn arownd!!!',
       '(empty)','(full)'
       );
begin
  edt := TEdit.Create(Self);
  edt.Text := Captions[Random(10)];
  RichViewEdit1.InsertControl('',edt,rvvaBaseline);
end;

{ Insert|Bullet|"XXX" -------------------------------------------------}
procedure TForm1.mitInsertBulletClick(Sender: TObject);
begin
  RichViewEdit1.InsertBullet(TMenuItem(Sender).Tag, il);
end;
{ Insert|Hot Spot|"XXX" -----------------------------------------------}
procedure TForm1.mitAddHSClick(Sender: TObject);
begin
  RichViewEdit1.InsertHotSpot(TMenuItem(Sender).Tag, TMenuItem(Sender).Tag+2, il);
end;
{ Insert|Break --------------------------------------------------------}
procedure TForm1.mitBreakClick(Sender: TObject);
begin
   RichViewEdit1.InsertBreak(1, rvbsLine, clNone);
end;
{======================================================================}
{ Main menu : "Edit"                                                   }
{======================================================================}
{ Edit ----------------------------------------------------------------}
procedure TForm1.mpdEditClick(Sender: TObject);
begin
  mitPasteAsText.Enabled     := Clipboard.HasFormat(CF_TEXT);
  mitPasteAsMetafile.Enabled := Clipboard.HasFormat(CF_METAFILEPICT);
  mitPasteAsBitmap.Enabled   := Clipboard.HasFormat(CF_BITMAP);
  mitPasteAsRVF.Enabled      := RichViewEdit1.CanPasteRVF;
  mitPaste.Enabled           := RichViewEdit1.CanPaste;

  // You can edit properties only for item with caret.
  // We disable this item because otherwise user can think what he will
  // edit properties of all selected items.
  // More smart programs can determine if there is only one item is selected
  // and do not disable this item in this case
  mitEditProps.Enabled       := not RichViewEdit1.SelectionExists;
end;
{ Edit|Cut ------------------------------------------------------------}
procedure TForm1.mitCutClick(Sender: TObject);
begin
  RichViewEdit1.Copy;
  RichViewEdit1.DeleteSelection;
end;
{ Edit|Copy -----------------------------------------------------------}
procedure TForm1.mitCopyClick(Sender: TObject);
begin
  // Copying both RVF and plain text
  RichViewEdit1.Copy;
  // In order to copy only one format, use CopyText or CopyRVF instead
end;
{ Edit|Paste ----------------------------------------------------------}
procedure TForm1.mitPasteClick(Sender: TObject);
begin
  RichViewEdit1.Paste;
end;
{ Edit|Paste As|Text --------------------------------------------------}
procedure TForm1.mitPasteAsTextClick(Sender: TObject);
begin
  RichViewEdit1.PasteText;
end;
{ Edit|Paste As|Bitmap ------------------------------------------------}
procedure TForm1.mitPasteAsBitmapClick(Sender: TObject);
begin
  RichViewEdit1.PasteBitmap(False);
end;
{ Edit|Paste As|Metafile ----------------------------------------------}
procedure TForm1.mitPasteAsMetafileClick(Sender: TObject);

begin
  RichViewEdit1.PasteMetafile(False);
end;
{ Edit|Paste As|RVF ---- ----------------------------------------------}
procedure TForm1.mitPasteAsRVFClick(Sender: TObject);
begin
  RichViewEdit1.PasteRVF;
end;
{ Edit|Delete ---------------------------------------------------------}
procedure TForm1.mitDeleteClick(Sender: TObject);
begin
  // Shortcut to this item is Ctrl+Del
  // If you make it Del, you will be unable to use del key in editor
  RichViewEdit1.DeleteSelection;
end;
{ Edit|Select All -----------------------------------------------------}
procedure TForm1.mitSelectAllClick(Sender: TObject);
begin
  { warning: SelectAll moves caret to the end of the text }
  RichViewEdit1.SelectAll;
  RichViewEdit1.Invalidate;
end;
{ Another clipboard-related action ------------------------------------}
procedure TForm1.RichViewEdit1Select(Sender: TObject);
begin
  mitCopy.Enabled := RichViewEdit1.SelectionExists;
  mitCut.Enabled := mitCopy.Enabled;
  mitDelete.Enabled := mitCopy.Enabled;
end;
{----------------------------------------------------------------------}
// This function is used in mitEditCheckpointClick() and mitEditPropsClick()
// to convert tag to string
function GetTagStr(Tag: Integer): String;
begin
  if (rvoTagsArePChars in Form1.RichViewEdit1.Options) then
    if Tag = 0 then
      Result := ''
    else
      Result := PChar(Tag)
  else
    Result := IntToStr(Tag);
end;
// This function is used in mitEditCheckpointClick() and mitEditPropsClick()
// to create valid tags from string TagStr (user input in edit box)
// If tags are PChars, it allocates new ansiz string and replaces all
// spaces with '_'.
// If tags are Integers, it convert TagStr to integer.
function MakeTag(TagStr: String): Integer;
var i: Integer;
    r: PChar;
begin
   if (TagStr<>'0') and (TagStr<>'') and (rvoTagsArePChars in Form1.RichViewEdit1.Options) then begin
     r := StrNew(PChar(TagStr));
     for i := 0 to StrLen(r)-1 do
       if r[i]=' ' then r[i]:='_';
       Result := Integer(r);
     end
   else
     Result := StrToIntDef(TagStr,0);
end;
{ Edit|Checkpoint... --------------------------------------------------}
procedure TForm1.mitEditCheckpointClick(Sender: TObject);
var CpNo, Tag: Integer;
    Name: String;
    CheckPointData: TCheckPointData;
    RaiseEvent: Boolean;
begin
  CheckPointData := RichViewEdit1.GetCurrentCheckpoint;
  if CheckPointData<>nil then begin
    RichViewEdit1.GetCheckpointInfo(CheckPointData,Tag,Name,RaiseEvent);
    CpNo := RichViewEdit1.GetCheckpointNo(CheckPointData);
    frmCp.lblStatus.Caption := 'Editing checkpoint #'+IntToStr(CpNo);
    frmCp.txtName.Text := Name;
    frmCp.txtTag.Text := GetTagStr(Tag);
    frmCp.btnOk.Caption := 'OK';
    frmCp.btnDelete.Enabled := True;
    end
  else begin
    frmCp.lblStatus.Caption := 'Checkpoint does not exist';
    frmCp.txtName.Text := '';
    frmCp.txtTag.Text := GetTagStr(0);
    frmCp.btnOk.Caption := 'Add';
    frmCp.btnDelete.Enabled := False;
  end;
  case frmCP.ShowModal of
    mrOk: { add new checkpoint or modify existed one }
      RichViewEdit1.SetCurrentCheckpointInfo(MakeTag(frmCp.txtTag.Text),
                                             frmCp.txtName.Text,False);
    mrYes: { delete checkpoint }
      RichViewEdit1.RemoveCurrentCheckpoint;
  end;
end;
{ Edit|Search... -------------------------------------}
procedure TForm1.mitSearchClick(Sender: TObject);
begin
  FindDialog1.Execute;
end;
{ Edit|Current Item Properties... -------------------------------------}
procedure TForm1.mitEditPropsClick(Sender: TObject);
var s: String;
    Tag, Index: Integer;
    VAlign: TRVVAlign;
    ImageList: TImageList;
    gr: TGraphic;
    ctrl: TControl;
    BreakColor: TColor;
    BreakStyle: TRVBreakStyle; // <- not implemented
    BreakWidth: Byte;
begin
  frmProp.PageControl1.Visible := True;
  frmProp.tsBullet.TabVisible := False;
  frmProp.tsHotSpot.TabVisible := False;
  frmProp.tsPicture.TabVisible := False;
  frmProp.tsText.TabVisible := False;
  frmProp.tsComponent.TabVisible := False;
  frmProp.tsBreak.TabVisible := False;
  frmProp.txtName.Enabled := True;
  case RichViewEdit1.CurItemStyle of
    rvsBullet:
      begin
        RichViewEdit1.GetCurrentBulletInfo(s, Index, ImageList, Tag);
        frmProp.tsBullet.TabVisible := True;
        frmProp.rgBullet.ItemIndex := Index;
        frmProp.txtName.Text := s;
        frmProp.txtTag.Text := GetTagStr(Tag);
      end;
    rvsHotspot:
      begin
        // you can use GetCurrentBulletInfo or GetCurrentHotspotInfo
        // to receive info about hotspot in caret position.
        // in this demo we need not HotImageIndex, because here
        // HotImageIndex = ImageIndex+2
        // and so we can use GetCurrentBulletInfo
        RichViewEdit1.GetCurrentBulletInfo(s, Index, ImageList, Tag);
        frmProp.tsHotspot.TabVisible := True;
        frmProp.rgHotspot.ItemIndex := Index-3;
        frmProp.txtName.Text := s;
        frmProp.txtTag.Text := GetTagStr(Tag);
      end;
    rvsPicture:
      begin
        RichViewEdit1.GetCurrentPictureInfo(s, gr, VAlign, Tag);
        frmProp.tsPicture.TabVisible := True;
        frmProp.Image1.Picture.Graphic := gr;
        frmProp.txtName.Text := s;
        frmProp.txtTag.Text := GetTagStr(Tag);
        frmProp.rgPicVAlign.ItemIndex := Integer(VAlign);
      end;
    rvsComponent:
      begin
        RichViewEdit1.GetCurrentControlInfo(s, ctrl, VAlign, Tag);
        frmProp.tsComponent.TabVisible := True;
        frmProp.txtWidth.Text := IntToStr(ctrl.Width);
        frmProp.txtHeight.Text := IntToStr(ctrl.Height);
        frmProp.txtName.Text := s;
        frmProp.lblComponent.Caption := ctrl.ClassName;
        frmProp.txtTag.Text := GetTagStr(Tag);
        frmProp.rgCtrlVAlign.ItemIndex := Integer(VAlign);
      end;
    rvsBreak:
      begin
        frmProp.tsBreak.TabVisible := True;
        RichViewEdit1.GetCurrentBreakInfo(BreakWidth, BreakStyle, BreakColor, Tag);
        frmProp.txtBreakWidth.Text := IntToStr(BreakWidth);
        case BreakColor of
          clNone:
            frmProp.rgBreakColor.ItemIndex := 0;
          clRed:
            frmProp.rgBreakColor.ItemIndex := 1;
          clGreen:
            frmProp.rgBreakColor.ItemIndex := 2;
          clBlue:
            frmProp.rgBreakColor.ItemIndex := 3;
        end;
        frmProp.txtName.Text := '(not available for breaks)';
        frmProp.txtName.Enabled := False;
        frmProp.txtTag.Text := GetTagStr(Tag);
      end;
    else
      begin
        RichViewEdit1.GetCurrentTextInfo(s, Tag);
        frmProp.tsText.TabVisible := True;
        frmProp.txtName.Text := '(not available for text)';
        frmProp.txtName.Enabled := False;
        frmProp.lblText.Caption := s;
        frmProp.txtTag.Text := GetTagStr(Tag);
      end;
  end;
  if frmProp.ShowModal=mrOk then
  case RichViewEdit1.CurItemStyle of
    rvsBullet:
      begin
        RichViewEdit1.SetCurrentBulletInfo(
          frmProp.txtName.Text,
          frmProp.rgBullet.ItemIndex,
          nil,
          MakeTag(frmProp.txtTag.Text));
      end;
    rvsHotspot:
      begin
        RichViewEdit1.SetCurrentHotspotInfo(
          frmProp.txtName.Text,
          frmProp.rgHotspot.ItemIndex+3,
          frmProp.rgHotspot.ItemIndex+3+2,
          nil,
          MakeTag(frmProp.txtTag.Text));
      end;
    rvsPicture:
      begin
        { first we need to create a copy of image ...}
        gr := TGraphic(frmProp.Image1.Picture.Graphic.ClassType.Create);
        gr.Assign(frmProp.Image1.Picture.Graphic);
        RichViewEdit1.SetCurrentPictureInfo(
          frmProp.txtName.Text,
          gr,
          TRVVAlign(frmProp.rgPicVAlign.ItemIndex),
          MakeTag(frmProp.txtTag.Text));
      end;
    rvsComponent:
      begin
        RichViewEdit1.SetCurrentControlInfo(
          frmProp.txtName.Text,
          TRVVAlign(frmProp.rgCtrlVAlign.ItemIndex),
          MakeTag(frmProp.txtTag.Text));
        RichViewEdit1.ResizeControl(RichViewEdit1.CurItemNo,
          StrToIntDef(frmProp.txtWidth.Text, ctrl.Width),
          StrToIntDef(frmProp.txtHeight.Text, ctrl.Height));
      end;
    rvsBreak:
      begin
        case frmProp.rgBreakColor.ItemIndex of
          -1,0:
            BreakColor := clNone;
          1:
            BreakColor := clRed;
          2:
            BreakColor := clGreen;
          3:
            BreakColor := clBlue;
        end;
        BreakWidth := StrToIntDef(frmProp.txtBreakWidth.Text,1);
        RichViewEdit1.SetCurrentBreakInfo(BreakWidth,BreakStyle,BreakColor,
                                          MakeTag(frmProp.txtTag.Text));
      end;
    else
      begin
        RichViewEdit1.SetCurrentTag(MakeTag(frmProp.txtTag.Text));
      end;
  end;
end;
{======================================================================}
{ Main menu : "View"                                                   }
{======================================================================}
{ View | Checkpoint list... -------------------------------------------}
procedure TForm1.mitCheckPointListClick(Sender: TObject);
var X,Y,Tag: Integer;
    Name: String;
    CheckpointData: TCheckpointData;
    RaiseEvent: Boolean;
    s: String;
begin
  frmList.lst.Items.Clear;
  CheckpointData := RichViewEdit1.GetFirstCheckPoint;
  while CheckpointData<>nil do begin
    RichViewEdit1.GetCheckpointInfo(CheckpointData,Tag,Name,RaiseEvent);
    RichViewEdit1.GetCheckpointXY(CheckpointData,X,Y);
    s := Format('(X:%d,Y:%d) Name:"%s" Tag:"%s"', [X,Y,Name,GetTagStr(Tag)]);
    frmList.lst.Items.Add(s);
    CheckpointData := RichViewEdit1.GetNextCheckpoint(CheckpointData);
  end;
  if frmList.ShowModal=mrOk then
    with RichViewEdit1 do
      ScrollTo(GetCheckPointY(frmList.lst.ItemIndex));
end;
{======================================================================}
{ Main menu : "Misc"                                                   }
{======================================================================}
{ Misc ----------------------------------------------------------------}
procedure TForm1.mpdMiscClick(Sender: TObject);
begin
  mitSavePictureBodiesinRVF.Checked         := rvfoSavePicturesBody        in RichViewEdit1.RVFOptions;
  mitSaveControlBodiesinRVF.Checked         := rvfoSaveControlsBody        in RichViewEdit1.RVFOptions;
  mitRVFIgnoreunknownpictureformats.Checked := rvfoIgnoreUnknownPicFmt     in RichViewEdit1.RVFOptions;
  mitRVFIgnoreunknowncontrols.Checked       := rvfoIgnoreUnknownCtrls      in RichViewEdit1.RVFOptions;
  mitRVFConvertunknownstylesto0.Checked     := rvfoConvUnknownStylesToZero in RichViewEdit1.RVFOptions;
  mitRVFConvertTooLargeImageIndicesto0.Checked := rvfoConvLargeImageIdxToZero in RichViewEdit1.RVFOptions;
  mitRVFSaveBinary.Checked                  := rvfoSaveBinary              in RichViewEdit1.RVFOptions;

  mitNoBitmap.Checked := RichViewEdit1.BackgroundStyle=bsNoBitmap;
  mitCentered.Checked := RichViewEdit1.BackgroundStyle=bsCentered;
  mitStretched.Checked := RichViewEdit1.BackgroundStyle=bsStretched;
  mitTiledScrolled.Checked := RichViewEdit1.BackgroundStyle=bsTiledAndScrolled;
  mitTiled.Checked := RichViewEdit1.BackgroundStyle=bsTiled;
end;
{ Misc| rvf options ---------------------------------------------------}
procedure TForm1.mitRVFOptionsClick(Sender: TObject);
begin
  with Sender as TMenuItem do begin
    Checked := not Checked;
    if Checked then
      RichViewEdit1.RVFOptions := RichViewEdit1.RVFOptions + [TRVFOption(Tag)]
    else
      RichViewEdit1.RVFOptions := RichViewEdit1.RVFOptions - [TRVFOption(Tag)];
  end;
end;
{ Misc| Background options --------------------------------------------}
procedure TForm1.mitBackClick(Sender: TObject);
begin
  RichViewEdit1.BackgroundStyle := TBackgroundStyle(TMenuItem(Sender).Tag);
end;
{======================================================================}
{ Displaying popup menu -----------------------------------------------}
procedure TForm1.RichViewEdit1RVRightClickEx(Sender: TRichView; LineNo,
  Style, X, Y: Integer);
begin
   { Here you can work with clicked item.
     LineNo, Style are for clicked item.
     Special case : LineNo=-1, Style=rvsBack }
   { But with editor, you should work not with clicked item,  but
     with "active" item (which has caret). So it has no meaning, where
     user right-click the component. So you can use not OnRVRightClickEx
     event, but PopupMenu property.
   }
   { Old OnRVRightClick event still works }
   PopupMenu1.Popup(X,Y);
end;
{ On Popup -------------------------------------------------------------}
procedure TForm1.PopupMenu1Popup(Sender: TObject);
begin
  mitEditProp1.Enabled := not RichViewEdit1.SelectionExists;
end;
{-----------------------------------------------------------------------}
{OnChange event handler. You can, for example, set here some "Modified" flag}
{-----------------------------------------------------------------------}
procedure TForm1.FindDialog1Find(Sender: TObject);
begin
  if not RichViewEdit1.SearchText(FindDialog1.FindText,
                           GetRVESearchOptions(FindDialog1.Options)) then
   Application.MessageBox('Can''t find', 'Search complete', MB_OK or MB_ICONEXCLAMATION);
end;
{-----------------------------------------------------------------------}
procedure TForm1.mitPasteAsOLEClick(Sender: TObject);
var oc: TOleContainer;
begin
  oc := TOleContainer.Create(nil);
  if oc.CanPaste then begin
    oc.Visible := False;
    oc.Parent := RichViewEdit1;
    oc.SizeMode := smAutoSize;
    oc.Paste;
    RichViewEdit1.InsertControl('', oc,rvvaBaseline);
    oc.OnResize := OnOleResize;
    oc.OnActivate := OnOleActions;
    oc.OnDeactivate := OnOleActions;
    oc.Visible := True;
    end
  else
    oc.Free;
end;
{-----------------------------------------------------------------------}
procedure TForm1.OnOleResize(Sender: TObject);
begin
  RichViewEdit1.AdjustControlPlacement(RichViewEdit1.FindControlItemNo(TControl(Sender)));
end;
{-----------------------------------------------------------------------}
procedure TForm1.OnOleActions(Sender: TObject);
begin
  RichViewEdit1.AdjustControlPlacement(RichViewEdit1.FindControlItemNo(TControl(Sender)));
end;


initialization
  // We need to register classes in order to load them from rvf files
  RegisterClasses([TButton, TEdit, TOleContainer]);
end.
