Page 1 of 1

[Example] How to store page information in RVF

Posted: Tue May 12, 2009 11:33 am
by Sergey Tkachenko
Update: this code uses some deprecated properties. See the code below for the updated version: viewtopic.php?f=3&t=3196&p=34745#p34745

TRichView is designed to use the current application page settings. But if you want to store page information in RVF files, you can do it using the code below.

This code is not necessary if you use ScaleRichView. It does all this work automatically.

Page information is written and read in DocParameters property, containing subproperties for storing page size, orientation and margins.
This property is saved and loaded in RVF if rvfoSaveDocProperties and rvfoLoadDocProperties are included in RVFOptions property.
This property is saved and loaded in RTF if rvrtfSaveDocParameters is included in RTFOptions, and RTFReadProperties.ReadDocParameters = True.

How to assign DocParameters:

Code: Select all

  procedure GetPaperWH(var Width, Height: Extended);
  var DC: HDC;
  begin
    DC := Printer.Handle;
    Width := GetDeviceCaps(DC, PHYSICALWIDTH) / GetDeviceCaps(DC, LOGPIXELSX);
    Height := GetDeviceCaps(DC, PHYSICALHEIGHT) / GetDeviceCaps(DC, LOGPIXELSY);
  end;

var
  InchPerMM: Extended;
  W,H: Extended;
begin
  ...
  rve.DocParameters.Units := rvuInches;
  InchPerMM := 1/rve.DocParameters.UnitsPerInch(rvuMillimeters);
  rve.DocParameters.LeftMargin := RVPrint1.LeftMarginMM*InchPerMM;
  rve.DocParameters.TopMargin := RVPrint1.TopMarginMM*InchPerMM;
  rve.DocParameters.RightMargin := RVPrint1.RightMarginMM*InchPerMM;
  rve.DocParameters.BottomMargin := RVPrint1.BottomMarginMM*InchPerMM;
  rve.DocParameters.HeaderY := RVPrint1.HeaderYMM*InchPerMM;
  rve.DocParameters.FooterY := RVPrint1.FooterYMM*InchPerMM;
  rve.DocParameters.MirrorMargins  := RVPrint1.MirrorMargins;
  rve.DocParameters.Orientation := Printer.Orientation;
  GetPaperWH(W,H);
  rve.DocParameters.PageWidth := W;
  rve.DocParameters.PageHeight := H;
end;
If you use RichViewActions, you may wish to store additional properties, for example properties of header and footer. See viewtopic.php?t=10 how to access them.
You can use rve.DocProperties to store them:

Code: Select all

  rve.DocProperties.Clear;
  rve.DocProperties.Add('HeaderText='+RVA_HeaderInfo.Text);
  ...
After loading RVF, you need to activate the read page settings.
How to activate DocParameters:

Code: Select all

function ConvertPageSizeToPageFormat(PaperWidth, PaperHeight: Integer): Integer;
var tmp: Integer;
begin
  if PaperHeight<PaperWidth then begin
    tmp := PaperHeight;
    PaperHeight := PaperWidth;
    PaperWidth := tmp;
  end;
  // this is not a complete list (and mistakes are possible)
  if (PaperWidth = 297) and (PaperHeight = 420) then
    Result := DMPAPER_A3
  else if (PaperWidth = 210) and (PaperHeight = 297) then
    Result := DMPAPER_A4
  else if (PaperWidth = 148) and (PaperHeight = 210) then
    Result := DMPAPER_A5
  else if (PaperWidth = 257) and (PaperHeight = 364) then
    Result := DMPAPER_B4 // JIS
  else if (PaperWidth = 182) and (PaperHeight = 257) then
    Result := DMPAPER_B5 // JIS
  else if (PaperWidth = 216) and (PaperHeight = 279) then
    Result := DMPAPER_LETTER
  else if (PaperWidth = 216) and (PaperHeight = 356) then
    Result := DMPAPER_LEGAL
  else if (PaperWidth = 215) and (PaperHeight = 355) then
    Result := DMPAPER_LEGAL
  else if (PaperWidth = 279) and (PaperHeight = 432) then
    Result := DMPAPER_TABLOID
  else if (PaperWidth = 279) and (PaperHeight = 432) then
    Result := DMPAPER_LEDGER
  else if (PaperWidth = 140) and (PaperHeight = 216) then
    Result := DMPAPER_STATEMENT
  else if (PaperWidth = 203) and (PaperHeight = 254) then
    Result := DMPAPER_QUARTO
  else if (PaperWidth = 203) and (PaperHeight = 330) then
    Result := DMPAPER_FOLIO
  else if (PaperWidth = 184) and (PaperHeight = 267) then
    Result := DMPAPER_EXECUTIVE
  else if (PaperWidth = 99) and (PaperHeight = 225) then
    Result := DMPAPER_ENV_9
  else if (PaperWidth = 105) and (PaperHeight = 241) then
    Result := DMPAPER_ENV_10
  else if (PaperWidth = 114) and (PaperHeight = 264) then
    Result := DMPAPER_ENV_11
  else if (PaperWidth = 121) and (PaperHeight = 279) then
    Result := DMPAPER_ENV_12
  else if (PaperWidth = 127) and (PaperHeight = 292) then
    Result := DMPAPER_ENV_14
  else
    Result := 0;
end;


procedure SetPaperWH(Width, Height: Integer);
  var ADevice, ADriver, APort: array[0..79] of Char;
      ADeviceMode: THandle;
      DevMode: PDeviceMode;
begin
  Printer.GetPrinter(ADevice,ADriver,APort,ADeviceMode);
  if ADeviceMode<>0 then begin
    DevMode := PDeviceMode(GlobalLock(ADeviceMode))
    end
  else
    raise Exception.Create('Error initializing printer');
  DevMode.dmFields := DevMode.dmFields or DM_PAPERSIZE;
  DevMode.dmPaperSize := ConvertPageSizeToPageFormat(Width, Height);
  if DevMode.dmPaperSize=0 then begin
    // the results are correct even if standard PaperSize is not detected
    DevMode.dmPaperWidth := Width*10;
    DevMode.dmPaperLength := Height*10;
  end;
  GlobalUnlock(ADeviceMode);
  Printer.SetPrinter(ADevice,ADriver,APort,ADeviceMode);
end;

var MMPerUnit: Extended;
begin
  ...
  // assigning margins, HeaderYMM, FooterYMM, MirrorMargins
  RVPrint1.AssignDocParameters(rve.DocParameters);
  Printer.Orientation := rve.DocParameters.Orientation;
  MMPerUnit := rve.DocParameters.UnitsPerInch(rvuMillimeters)/
    rve.DocParameters.UnitsPerInch(rve.DocParameters.Units);
  SetPaperWH(Round(rve.DocParameters.PageWidth*MMPerUnit),
    Round(rve.DocParameters.PageHeight*MMPerUnit));
end;
Assign printing settings to DocParameters and DocProperties when these settings are changed. If you use RichViewActions, use rvActionPageSetup.OnChange event.

If you use TDBRichViewEdit, use OnLoadDocument event to apply loaded values, and OnNewDocument to reset them to the defaults.
If you use RichViewActions, use rvActionOpen.OpenFile to apply loaded values (TrvActionNew resets the to default automatically).

Re: [Example] How to store page information in RVF

Posted: Fri Nov 10, 2017 9:09 am
by Sergey Tkachenko
The code described in this topic is still valid.
However, some corrections are needed.

1. Use Header and Footer properties of TRVAControlPanel instead of RVA_HeaderInfo and RVF_FooterInfo
2. You can still use "MM" properties of TRVPrint (like HeaderYMM, LeftMarginMM), but they are deprecated. The recommended properties are HeaderY, FooterY, Margins.

Also, there is one more way to store custom information in RVF. Instead of DocProperties string list, you can use DocObjects collection.

Re: [Example] How to store page information in RVF

Posted: Wed May 02, 2018 12:55 pm
by Sergey Tkachenko
New version of this code.
[+] Changes
-using RVPrint.Margings, RVPrint.HeaderY, RVPrint.FooterY instead of deprecated RVPrint.***MM properties
- assigning TitlePage and FacingPages property
- the code for assigning DocParameters uses DocParameters.Units and does not change it
- using RV_UnitsToUnits function from RVFuncs units
- using TRVAControlPanel.Header instead of a deprecated function

TRichView is designed to use the current application page settings. But if you want to store page information in RVF files, you can do it using the code below.

This code is not necessary if you use ScaleRichView. It does all this work automatically.

Page information is written and read in DocParameters property, containing subproperties for storing page size, orientation and margins.
This property is saved and loaded in RVF if rvfoSaveDocProperties and rvfoLoadDocProperties are included in RVFOptions property.
This property is saved and loaded in RTF if rvrtfSaveDocParameters is included in RTFOptions, and RTFReadProperties.ReadDocParameters = True.

How to assign DocParameters:

Code: Select all

procedure GetPaperWH(var Width, Height: Extended);
var DC: HDC;
begin
  DC := Printer.Handle;
  Width := GetDeviceCaps(DC, PHYSICALWIDTH) / GetDeviceCaps(DC, LOGPIXELSX);
  Height := GetDeviceCaps(DC, PHYSICALHEIGHT) / GetDeviceCaps(DC, LOGPIXELSY);
end;

var
  W,H: Extended;
begin
  // Copying properties from RVPrint1 to rve.DocParameters 
  rve.DocParameters.LeftMargin :=
    RV_UnitsToUnits(RVPrint1.Margins.Left, RVPrint1.Units, rve.DocParameters.Units);
  rve.DocParameters.TopMargin :=
    RV_UnitsToUnits(RVPrint1.Margins.Top, RVPrint1.Units, rve.DocParameters.Units);
  rve.DocParameters.RightMargin :=
    RV_UnitsToUnits(RVPrint1.Margins.Right, RVPrint1.Units, rve.DocParameters.Units);
  rve.DocParameters.BottomMargin :=
    RV_UnitsToUnits(RVPrint1.Margins.Bottom, RVPrint1.Units, rve.DocParameters.Units);

  rve.DocParameters.HeaderY :=
    RV_UnitsToUnits(RVPrint1.HeaderY, RVPrint1.Units, rve.DocParameters.Units);
  rve.DocParameters.FooterY :=
    RV_UnitsToUnits(RVPrint1.FooterY, RVPrint1.Units, rve.DocParameters.Units);

  rve.DocParameters.MirrorMargins := RVPrint1.MirrorMargins;
  rve.DocParameters.FacingPages   := RVPrint1.FacingPages;
  rve.DocParameters.TitlePage     := RVPrint1.TitlePage;

  // Assigning the current printer property to rve.DocParameters

  rve.DocParameters.Orientation := Printer.Orientation;

  GetPaperWH(W,H);
  rve.DocParameters.PageWidth :=
    RV_UnitsToUnits(W, rvuInches, rve.DocParameters.Units);
  rve.DocParameters.PageHeight :=
    RV_UnitsToUnits(H, rvuInches, rve.DocParameters.Units);  
end;
If you use RichViewActions, you may wish to store additional properties, for example properties of header and footer. See https://www.trichview.com/forums/viewtopic.php?t=10 how to access them.
You can use rve.DocProperties to store them:

Code: Select all

  rve.DocProperties.Clear;
  rve.DocProperties.Add('HeaderText='+RVAControlPanel1.Header.Text);
  ...
After loading RVF, you need to activate the read page settings.
How to activate DocParameters:

Code: Select all

function ConvertPageSizeToPageFormat(PaperWidth, PaperHeight: Integer): Integer;
var tmp: Integer;
begin
  if PaperHeight<PaperWidth then begin
    tmp := PaperHeight;
    PaperHeight := PaperWidth;
    PaperWidth := tmp;
  end;
  // this is not a complete list (and mistakes are possible)
  if (PaperWidth = 297) and (PaperHeight = 420) then
    Result := DMPAPER_A3
  else if (PaperWidth = 210) and (PaperHeight = 297) then
    Result := DMPAPER_A4
  else if (PaperWidth = 148) and (PaperHeight = 210) then
    Result := DMPAPER_A5
  else if (PaperWidth = 257) and (PaperHeight = 364) then
    Result := DMPAPER_B4 // JIS
  else if (PaperWidth = 182) and (PaperHeight = 257) then
    Result := DMPAPER_B5 // JIS
  else if (PaperWidth = 216) and (PaperHeight = 279) then
    Result := DMPAPER_LETTER
  else if (PaperWidth = 216) and (PaperHeight = 356) then
    Result := DMPAPER_LEGAL
  else if (PaperWidth = 215) and (PaperHeight = 355) then
    Result := DMPAPER_LEGAL
  else if (PaperWidth = 279) and (PaperHeight = 432) then
    Result := DMPAPER_TABLOID
  else if (PaperWidth = 279) and (PaperHeight = 432) then
    Result := DMPAPER_LEDGER
  else if (PaperWidth = 140) and (PaperHeight = 216) then
    Result := DMPAPER_STATEMENT
  else if (PaperWidth = 203) and (PaperHeight = 254) then
    Result := DMPAPER_QUARTO
  else if (PaperWidth = 203) and (PaperHeight = 330) then
    Result := DMPAPER_FOLIO
  else if (PaperWidth = 184) and (PaperHeight = 267) then
    Result := DMPAPER_EXECUTIVE
  else if (PaperWidth = 99) and (PaperHeight = 225) then
    Result := DMPAPER_ENV_9
  else if (PaperWidth = 105) and (PaperHeight = 241) then
    Result := DMPAPER_ENV_10
  else if (PaperWidth = 114) and (PaperHeight = 264) then
    Result := DMPAPER_ENV_11
  else if (PaperWidth = 121) and (PaperHeight = 279) then
    Result := DMPAPER_ENV_12
  else if (PaperWidth = 127) and (PaperHeight = 292) then
    Result := DMPAPER_ENV_14
  else
    Result := 0;
end;


procedure SetPaperWH(Width, Height: Integer);
  var ADevice, ADriver, APort: array[0..79] of Char;
      ADeviceMode: THandle;
      DevMode: PDeviceMode;
begin
  Printer.GetPrinter(ADevice,ADriver,APort,ADeviceMode);
  if ADeviceMode<>0 then begin
    DevMode := PDeviceMode(GlobalLock(ADeviceMode))
    end
  else
    raise Exception.Create('Error initializing printer');
  DevMode.dmFields := DevMode.dmFields or DM_PAPERSIZE;
  DevMode.dmPaperSize := ConvertPageSizeToPageFormat(Width, Height);
  if DevMode.dmPaperSize=0 then begin
    // the results are correct even if standard PaperSize is not detected
    DevMode.dmPaperWidth := Width*10;
    DevMode.dmPaperLength := Height*10;
  end;
  GlobalUnlock(ADeviceMode);
  Printer.SetPrinter(ADevice,ADriver,APort,ADeviceMode);
end;

begin
  // assigning margins, HeaderYMM, FooterYMM, MirrorMargins, etc. to RVPrint1
  RVPrint1.AssignDocParameters(rve.DocParameters);
  // assigning the current printer properties
  Printer.Orientation := rve.DocParameters.Orientation;
  SetPaperWH(
    Round(RV_UnitsToUnits(rve.DocParameters.PageWidth, rve.DocParameters.Units, rvuMillimeters)),
    Round(RV_UnitsToUnits(rve.DocParameters.PageHeight, rve.DocParameters.Units, rvuMillimeters)));
end;
Assign printing settings to DocParameters and DocProperties when these settings are changed. If you use RichViewActions, use rvActionPageSetup.OnChange event.

If you use TDBRichViewEdit, use OnLoadDocument event to apply loaded values, and OnNewDocument to reset them to the defaults.
If you use RichViewActions, use rvActionOpen.OpenFile to apply loaded values (TrvActionNew resets the to default automatically).