скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Распечатать RTF-файл и определить диапазон страницы для печати



Оформил: DeeCo

unit Unit1;

 interface

 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, RichEdit, RxRichEd, ExtCtrls, Printers;

 type
   TPageOffset = record
     mStart,
     mEnd: Integer;
     rendRect: TRect;
   end;
   TForm1 = class(TForm)
     Panel1: TPanel;
     Editor: TRxRichEdit;
     PrintBtn: TButton;
     PreviewBtn: TButton;
     CloseBtn: TButton;
     procedure PrintBtnClick(Sender: TObject);
     procedure PreviewBtnClick(Sender: TObject);
     procedure CloseBtnClick(Sender: TObject);
     procedure FormShow(Sender: TObject);
   private
     { Private-Deklarationen }
   public
     { Public-Deklarationen }
   end;

 var
   Form1: TForm1;

 implementation

 uses Unit2;

 {$R *.dfm}

 procedure TForm1.PrintBtnClick(Sender: TObject);
 var
    wPage, hPage, xPPI, yPPI, wTwips, hTwips: integer;
   pageRect, rendRect: TRect;
   po: TPageOffset;
   fr: TFormatRange;
   lastOffset, currPage, pageCount: integer;
   xOffset, yOffset: integer;
   FPageOffsets: array of TPageOffset;
   TextLenEx: TGetTextLengthEx;
   firstPage: boolean;
 begin
   //First, get the size of a printed page in printer device units 
  wPage := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
   hPage := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
   //Next, get the device units per inch for the printer 
  xPPI := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
   yPPI := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
   //Convert the page size from device units to twips 
  wTwips := MulDiv(wPage, 1440, xPPI);
   hTwips := MulDiv(hPage, 1440, yPPI);
   //Save the page size in twips 
  with pageRect do
    begin
     Left := 0;
     Top := 0;
     Right := wTwips;
     Bottom := hTwips
   end;
   //Next, calculate the size of the rendering rectangle in twips 
  //Rememeber - two inch margins are hardcoded, so the below code 
  //reduces the width of the output by four inches 
  with rendRect do
    begin
     Left := 0;
     Top := 0;
     Right := pageRect.Right - (1440 * 4);
     Bottom := pageRect.Bottom - (1440 * 4)
   end;
   //Define a single page and set starting offset to zero 
  po.mStart := 0;
   //Define and initialize a TFormatRange structure. This structure is passed 
  //to the TRichEdit with a request to format as much text as will fit on a 
  //page starting with the chrg.cpMin offset and ending with the chrg.cpMax. 
  //Initially, we tell the RichEdit control to start at the beginning 
  //(cpMin = 0) and print as much as possible (cpMax = -1). We also tell it 
  //to render to the printer 
  with fr do
    begin
     hdc := Printer.Handle;
     hdcTarget  := Printer.Handle;
     chrg.cpMin := po.mStart;
     chrg.cpMax := -1;
   end;
   //In order to recognize when the last page is rendered, we need to know how 
  //much text is in the control. 
  if RichEditVersion >= 2 then
    begin
     with TextLenEx do
      begin
       flags := GTL_DEFAULT;
       codepage := CP_ACP;
     end;
     lastOffset := SendMessage(Editor.Handle, EM_GETTEXTLENGTHEX, wParam(@TextLenEx), 0)
   end
   else
      lastOffset := SendMessage(Editor.Handle, WM_GETTEXTLENGTH, 0, 0);
   //As a precaution, clear the formatting buffer 
  SendMessage(Editor.Handle, EM_FORMATRANGE, 0, 0);
   //Printers frequently cannot print at the absolute top-left position on the 
  //page. In other words, there is usually a minimum margin on each edge of the 
  //page. When rendering to the printer, RichEdit controls adjust the top-left 
  //corner of the rendering rectangle for the amount of the page that is 
  //unprintable. Since we are printing with two-inch margins, we are presumably 
  //already within the printable portion of the physical page. 
  SaveDC(fr.hdc);
   SetMapMode(fr.hdc, MM_TEXT);
   xOffset := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
   yOffset := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
   xOffset := xOffset + MulDiv(1440 + 1440, xPPI, 1440);
   yOffset := yOffset + MulDiv(1440 + 1440, yPPI, 1440);
   SetViewportOrgEx(fr.hdc, xOffset, yOffset, nil);
   //Now we build a table of page entries, one entry for each page that would be 
  //printed. 
  while ((fr.chrg.cpMin <> -1) and (fr.chrg.cpMin < lastOffset)) do
    begin
     fr.rc := rendRect;
     fr.rcPage := pageRect;
     po.mStart := fr.chrg.cpMin;
     fr.chrg.cpMin := SendMessage(Editor.Handle, EM_FORMATRANGE, 0, Longint(@fr));
     po.mEnd := fr.chrg.cpMin - 1;
     po.rendRect := fr.rc;
     if High(FPageOffsets) = -1 then SetLength(FPageOffsets, 1)
     else
        SetLength(FPageOffsets, Length(FPageOffsets) + 1);
     FPageOffsets[High(FPageOffsets)] := po
   end;
   pageCount := Length(FPageOffsets);
   ShowMessage(Format('Es wurde %d Seiten ermittelt', [pageCount]));
   SendMessage(Editor.Handle, EM_FORMATRANGE, 0, 0);
   RestoreDC(fr.hdc, - 1);
   //Now, we are almost ready to actually print. 
  Printer.BeginDoc;
   fr.hdc := Printer.Handle;
   fr.hdcTarget := Printer.Handle;
   SaveDC(fr.hdc);
   SetViewportOrgEx(fr.hdc, xOffset, yOffset, nil);
   //Ok, here we go to print 
  firstPage := True;
   //At this point you can select from page and to page 
  currPage := 0;  //Print from the first page 
  pageCount := 1;  //Only One page for testing 
  while (currPage < pageCount) do
    begin
     if firstPage then firstPage := False
     else
        Printer.NewPage;
     SetViewportOrgEx(fr.hdc, xOffset, yOffset, nil);
     fr.rc := FPageOffsets[currPage].rendRect;
     fr.rcPage := pageRect;
     fr.chrg.cpMin := FPageOffsets[currPage].mStart;
     fr.chrg.cpMax := FPageOffsets[currPage].mEnd;
     fr.chrg.cpMin := SendMessage(Editor.Handle, EM_FORMATRANGE, 1, Longint(@fr));
     Inc(currPage);
   end;
   //At this point, we have finished rendering the contents of the RichEdit 
  //control. Now we restore the printer's HDC settings and tell Windows that 
  //we are through printing this document 
  RestoreDC(fr.hdc, - 1);
   Printer.EndDoc;
   //Finally, we clear the RichEdit control's formatting buffer and delete 
  //the saved page table information 
  fr.chrg.cpMin := SendMessage(Editor.Handle, EM_FORMATRANGE, 0, 0);
   Finalize(FPageOffsets);
   //That's it 
end;

 procedure TForm1.PreviewBtnClick(Sender: TObject);
 begin
   PreviewForm.ShowModal
 end;

 procedure TForm1.CloseBtnClick(Sender: TObject);
 begin
   Close
 end;

 procedure TForm1.FormShow(Sender: TObject);
 begin
   Editor.Lines.LoadFromFile('Exceltabelle.rtf');
 end;

 end.





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook