Drukowanie z marginesami

jozkan

Jak w temacie:

delphi
uses Printers;

procedurę DrukujRichEdita(RE:TRichEdit;margL,margT,margR,margB:Extended);//marginesy w mm
var
   log_pixelsX,log_pixelsY,non_printL,non_printT:Integer;//drukarka
   page_rect:TRect;
begin
   log_pixelsX := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
   log_pixelsY := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
   non_printL  := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
   non_printT  := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);

   margL:=margL/25.4;
   margR:=margR/25.4;
   margT:=margT/25.4;
   margB:=margB/25.4;

   page_rect.Left  := Round(log_pixelsX * margL) - non_printL;
   page_rect.Right := Printer.PageWidth-Round(log_pixelsX * margR) - non_printL;
   page_rect.Top   := Round(log_pixelsY * margT) - non_printT;
   page_rect.Bottom:= Printer.PageHeight - Round(log_pixelsY * margB)- non_printT;

   RE.PageRect:=page_rect;
   RE.Print('Drukowanie z marginesami');
end;

4 komentarzy

Poniższy komentarz jest zamieszczony dla tych, co nie rozumieją lub nie wiedzą, jak skorzystać z tego, co jest widoczne powyżej. Ja przedstawiam to trochę inaczej, chyba prościej, posługując się działającym przykładem. Przykład wszystko wyjaśni. Zrób tak.

  1. Otwórz nowy projekt i umieść na formie pole Memo , dwa pola Edit i dwa przyciski. Button
  2. W sekcji Uses umieść Printers .
  3. Teraz przekopiuj obie funkcje widoczne poniżej zaraz po implementation (muszą być wpisane jako pierwsze, inaczej nie będzie działać). Pierwsza funkcja zamienia milimetry na punkty (i dla nas jest najważniejsza), a druga zamienia punkty na milimetry. Obie funkcje uwzględniają rozdzielczość drukarki co oznacza, że wydruk na każdej drukarce będzie wyglądać identycznie z tym, że w funkcji użyłem rozdzielczości drukarki w osi X. Nigdy nie widziałem drukarki, w której rozdzielczości w osiach X i Y są różne, więc śmiało można posługiwać się tylko jedną z nich. Gdybyś jednak chciał to zmienić drobną modyfikacją funkcji łatwo można to zmienić

    function MM_na_DPI(mm:single):integer;
    var
    a,b:integer;
    begin
    a:=GetDeviceCaps(Printer.Handle,LogPixelSX);  // rozdzielczość drukarki
    b:=Round(mm*a/25.4);  // ponieważ dpi jest liczbą całkowitą, stąd funkcja Round, która zaokrągla dzielenie do liczby całkowitej
    
    Result:=b;
    end;

    // oraz

    function DPI_na_MM(cal:integer):single;
    var
    a:integer;
    b:real;
    begin
    a:=GetDeviceCaps(Printer.Handle,LogPixelSX);  // rozdzielczość drukarki
    b:=cal*25.4/a;
    
    Result:=b;
    end; 
  4. Dla Button1 wpisz poniższą procedurę. Dzięki temu w polu Memo uzyskasz informację o wielkości obszaru wydruku oraz o marginesach drukarki. Dzięki funkcji DPI_na_MM() wszystkie te dane podane będą w milimetrach. Tutaj trzeba wiedzieć, że obszar wydruku jest zawsze mniejszy od wielkości kartki o marginesy drukarki. Dlatego punkt(0,0) wypadnie nie na krawędzi kartki, jak może się wydawać, tylko na krawędzi marginesów drukarki (dla drukarek laserowych ten margines wynosi około 5 mm).
    with Printer,Printer.Canvas do         // wpisuje do pola Memo długość, szerokość strony i marginesy drukarki
    begin
      Memo1.Lines.Add('szerokosc strony wydruku - '+FormatFloat('0.00',DPI_na_MM(PageWidth)));
      Memo1.Lines.Add('wysokosc strony wydruku - '+FormatFloat('0.00',DPI_na_MM(PageHeight)));
      Memo1.Lines.Add('boczne marginesy drukarki - '+FormatFloat('0.00',DPI_na_MM(GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX))));
      Memo1.Lines.Add('górny margines drukarki - '+FormatFloat('0.00',DPI_na_MM(GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY))));
    end;
  5. W polu Edit1 wpisz wartość 10, a w pole Edit2 wpisz 50. Dla przycisku Button2 przekopiuj poniższą procedurę

    var
    a,b:single;
    c,d:integer;
    begin
    
    Printer.Title:='Drukowanie w mm';
    
    with Printer,Printer.Canvas do          
    begin
      BeginDoc;
       a:=StrToFloat(Edit1.Text);  // margines wydruku, tutaj 10 mm
       b:=StrToFloat(Edit2.Text);  // wielkość kwadratu, tutaj 50 mm
    
       // W pola Edit można wpisać liczbę z przecinkiem
    
      c:=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);   // marginesy drukarki w osi x
      d:=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);  // marginesy drukarki w osi y
    
      Pen.Width:=3;
    
     // drukuje kwadrat o boku 50 mm, 10 mm od krawędzi kartki
      Rectangle(
                    MM_na_DPI(a)-c, MM_na_DPI(a)-d,
                    MM_na_DPI(a+b)-c, MM_na_DPI(a+b)-d
                     );
    
      EndDoc;
    end;

Klikając w Button2 wydrukujesz kwadrat o boku 50 mm, 10 mm od górnej i lewej krawędzi kartki. Wielkość wydruku można zmieniać zależnie od wartości wstawionych do pól Edit1 i Edit2 . Funkcję MM_na_DPI() można wykorzystać w każdej aplikacji. Jeżeli chcesz wydrukować jakąkolwiek grafikę lub cos innego, 127 milimetrów od lewej krawędzi i 43 milimetrów od górnej krawędzi kartki, to obie wartości przepuszczasz przez funkcję i od uzyskanej wartości odejmujesz margines drukarki, zgodnie z załączonym wzorem. Sprawdź, a zobaczysz jakie to proste.

Jak coś nie rozumiesz pisz na GG-9990906.

mi to jakoś nie włazi...;(

Ja również mam problem z marginesami.

czy to działa na kazdej drukarce, bo prawde powiedziawszy mam problem z uzyskaniem tych marginesów