Tipy a triky v Delphi, díl 25.

Jak jsme si slíbili minule, dnešní díl bude celý věnován tisku. Nejprve si ještě ukážeme několik nastavení tiskárny a poté se již vrhneme na samotný tisk. Ukážeme si, jak vytisknout text s jednoduchou grafikou, dále obrázek a nakonec tabulku.
Rozlišení tiskárny

Následující velmi krátký příklad zjišťuje, jaké je rozlišení výchozí tiskárny v DPI (bodech na palec). Musím bohužel konstatovat, že alespoň na mé tiskárně mi výsledek nepřipadal správný, ale třeba budete mít více štěstí. Opět budeme potřebovat knihovnu Printers. Takže zde je kód:

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(GetDeviceCaps(Printer.Handle, LOGPIXELSX)) + ` x `+IntToStr(GetDeviceCaps(Printer.Handle, LOGPIXELSY))+  ` DPI`);
end;

Zjištění a nastavení aktuální tiskárny

Jestliže máte k dispozici více tiskáren (například při práci v síti), jistě se vám bude hodit následující tip. Ukážeme si jak zjistit, která z tiskáren je nastavena jako výchozí, a také jak ze seznamu dostupných tiskáren jednu vybrat a nastavit ji jako výchozí. Znovu již tradičně využijeme knihovnu Printers a také Messages. První funkce nám zjistí aktuální výchozí tiskárnu, druhá zase zajistí, že tiskárna předaná parametrem bude zvolena jako výchozí. Samotné použití je vidět ze zdrojového kódu. Na formulář přidejte dvě tlačítka, Label a ComboBox. Po stisknutí prvního tlačítka se do Labelu vypíše aktuální výchozí tiskárna, po stisknutí druhého tlačítka bude tiskárna, která je zvolena v ComboBoxu, nastavena jako výchozí. Samotný ComboBox je vyplněn dostupnými tiskárnami v události OnCreate formuláře.

function GetDefaultPrinter : string;
var
  ResStr : array[0..255] of char;
begin
GetProfileString(`Windows`,`device`,``,ResStr,255);
Result := StrPas(ResStr);
end;

procedure SetDefaultPrinter(NewDefPrinter : string);
var
  ResStr : array[0..255] of char;
begin
StrPCopy(ResStr,NewdefPrinter);
WriteProfileString (`windows`, `device`, ResStr);
StrCopy (ResStr, `windows`);
SendMessage (HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(@ResStr));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := GetDefaultPrinter;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Combobox1.Items.Clear;
Combobox1.Items.AddStrings(Printer.Printers);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
SetDefaultPrinter(Combobox1.Text);
end;

Konečně začínáme tisknout

A nyní se již konečně dostáváme k samotnému tisku. Tisknout lze samozřejmě celou řadou způsobů, ale my se budeme držet jednoduchosti. V následující ukázce se pokusíme vytisknout přední stranu obalu na CD s jednoduchým popiskem. Ponechme teď stranou, jak by měl být opravdový obal skutečně velký, pro náš příklad jsem zvolil rozměry 12,1 x 12,1 cm, což se myslím reálu blíží dostatečně. Ten jeden milimetr v každém rozměru je tam zcela úmyslně, protože si ukážeme, že není sebemenší problém tisknout s touto (a lepší) přesností. Popisek je umístěn přibližně (!!) uprostřed našeho pomyslného obalu. Zde je tedy kód:

procedure TForm1.Button1Click(Sender: TObject);
begin
  printer.BeginDoc;
  SetMapMode(printer.Canvas.Handle, MM_LOMETRIC);
  with printer.Canvas do
  begin
    Rectangle(250,-100,1460,-1310);
    Font.Height:=100;
    Font.Name:=`Verdana`;
    TextOut(600,-600,`Zkušební tisk`);
  end;
  printer.EndDoc;
end;

Jak vidíte, kód je velmi jednoduchý a jedná se vlastně o kreslení, na které jste asi zvyklí, s tím rozdílem, že probíhá na papíře a nikoliv na monitoru. Je třeba si uvědomit jen dvě věci. Tou první je, že veškeré jednotky odpovídají desetině milimetru, takže například parametr "250" ve funkci Rectangle odpovídá 2,5 cm (vzdálenost od levého okraje + asi 2 milimetry rezerva pro tiskárnu). Totéž se týká velikosti fontu písma, i když zde je to již nutno brát s určitou rezervou (písmo bude vždy o něco málo menší, než nastavíte, záleží na použitém fontu). Druhou věcí, se kterou je nutné počítat, jsou obrácené souřadnice osy y. Protože horní okraj papíru má nulové souřadnice, musí být souřadnice na ose y záporné, protože jinak bychom kreslili "nad" horní okraj papíru místo na něj. Souřadnice na ose y prostě rostou od horního okraje papíru směrem k dolnímu, ale v záporném smyslu. Deset centimetrů od horního okraje tedy není 1000, nýbrž -1000. Možná to vysvětluji zbytečně podrobně, věřím, že to každý ihned pochopil. :)

Abych nezapomněl, pochopitelně i v tomto případě je nutné použít knihovnu Printers.

Tisk obrázků

Když jsme si ukázali, jak tisknout text a jednoduchou grafiku v podobě čar, ukažme si nyní, jak tisknout již hotové obrázky. I zde máme na výběr z několika možností. Opět použijeme co možná nejjednodušší způsob s pomocí knihovny Printers. Příklad pro zjednodušení předpokládá, že máte na formuláři umístěnu komponentu Image, v níž je načten obrázek, který chcete tisknout. Samozřejmě že způsob, jak určit, který obrázek se má tisknout, si můžete zvolit podle sebe (například výběrem daného souboru přes dialog otevření souboru a podobně), zde je pro zjednodušení použita komponenta Image.

procedure TForm1.Button50Click(Sender: TObject);
const
  X = 800;
  Y = 600;
var
ScaleX, ScaleY : Integer;
RR : TRect;
begin
  with Printer do
  begin
  BeginDoc;
  try
    ScaleX := GetDeviceCaps(Handle,logPixelsX) div PixelsPerInch;
    ScaleY := GetDeviceCaps(Handle,logPixelsY) div PixelsPerInch;
    RR := Rect(X, Y, Image1.picture.width * scaleX + X, Image1.Picture.Height * ScaleY + Y);
    Canvas.StretchDraw(RR,Image1.Picture.Graphic);
  finally
    EndDoc; 
  end;
end;
end;

Konstanty X a Y určují polohu obrázku na stránce. V samotném kódu jsou jednak zjištěny parametry rozlišení tiskárny a na základě toho jsou přepočítány souřadnice na základě rozměrů obrázku.

Tisk tabulky

Na závěr tu máme ukázku tisku tabulky, přesněji řečeno dat uložených v komponentě StringGrid. Už asi nemá cenu připomínat, že opět využijeme knihovny Printers. Na formulář umístěte komponentu StrindGrid, naplňte ji daty a o zbytek se postará následující funkce, jež má dva parametry – StringGrid, který se bude tisknout, a titulek, který bude vytištěn nad tabulkou. Když si prohlédnete zdrojový kód, jistě pro vás nebude problém upravit si výsledný vytištěný vzhled tabulky tak, jak vám vyhovuje. Můžete k tomu využít i poznatky z předchozích příkladů.

procedure PrintGrid(sGrid: TStringGrid; sTitle: String);
var
X1, X2 : Integer;
Y1, Y2 : Integer;
TmpI : Integer;
F : Integer;
TR : TRect;
begin
Printer.Title := sTitle;
Printer.BeginDoc;
Printer.Canvas.Pen.Color := 0;
Printer.Canvas.Font.Name := `Times New Roman`;
Printer.Canvas.Font.Size := 12;
Printer.Canvas.Font.Style := [fsBold, fsUnderline];
Printer.Canvas.TextOut(0, 100, Printer.Title);
For F:=1 to sGrid.ColCount - 1 do
  begin
  X1 := 0;
  For TmpI := 1 to (F-1) do
    X1:=X1 + 5 * (sGrid.ColWidths[TmpI]);
  Y1 := 300;
  X2 := 0;
  For TmpI := 1 to F do
    X2 := X2 + 5 * (sGrid.ColWidths[TmpI]);
  Y2 := 450;
  TR := Rect(X1, Y1, X2-30, Y2);
  Printer.Canvas.Font.Style := [fsBold];
  Printer.Canvas.Font.Size := 7;
  Printer.Canvas.TextRect(TR, X1 + 50, 350, sGrid.Cells[F, 0]);
  Printer.Canvas.Font.Style := [];
  For TmpI := 1 to sGrid.RowCount-1 do
    begin
    Y1 := 150 * TmpI + 300;
    Y2 := 150 * (TmpI+1) + 300;
    TR := Rect(X1, Y1, X2-30, Y2);
    Printer.Canvas.TextRect(TR, X1 + 50, Y1 + 50, sGrid.Cells[F, TmpI]);
    end;
  end;
Printer.EndDoc;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
PrintGrid(StringGrid1, `Titulek tabulky`);
end;

Váš názor Další článek: VIA KT333 již tento týden

Témata článku: Software, Windows, Programování, Trik, TRI, Zjednodušený příklad, Díl, Label, DEL


Určitě si přečtěte

Vybíráme nejlepší monitory: Od úplně levných až po displeje na rozmazlování očí

Vybíráme nejlepší monitory: Od úplně levných až po displeje na rozmazlování očí

** Vybrali jsme nejlepší monitory na práci i pořádné hraní ** Nejlevnější monitor s kvalitním panelem nestojí ani tři tisíce ** Rozlišení 4K a větší obrazovka už není nedostupný luxus

David Polesný | 30

David Polesný
Monitory
Fedora 33 prostě funguje. Linux si zaslouží dobýt laptop, je to ale asi opět marné

Fedora 33 prostě funguje. Linux si zaslouží dobýt laptop, je to ale asi opět marné

** Desktopový Linux funguje a vypadá stále lépe ** Fedora 33 není výjimkou ** Ve stínu Windows a macOS tu vyrostly skvělé alternativy

Jakub Čížek | 162

Jakub Čížek
FedoraOperační systémyLinux
26 užitečných rozšíření pro Chrome: Naučte prohlížeč nové věci

26 užitečných rozšíření pro Chrome: Naučte prohlížeč nové věci

** Prohlížeč Chrome obsahuje širokou škálu funkcí, neumí ale všechno ** Jeho schopnosti můžete rozšířit pomocí rozšíření ** Vybrali jsme pro vás zajímavé a užitečné doplňky

Karel Kilián | 44

Karel Kilián
Doplňky do prohlížečeChromeProhlížeče
Vybrali jsme 12 programovatelných hraček a stavebnic pro děti a jejich rodiče

Vybrali jsme 12 programovatelných hraček a stavebnic pro děti a jejich rodiče

** Získejte děti pro matematiku a základy techniky ** Kupte jim hračku nebo stavebnici, které vdechnou vlastní život ** Vybrali jsme stavebnice pro malé caparty i budoucí experty

Jakub Čížek | 10

Jakub Čížek
Stavebnice
Google chystá funkci, která z chytrého Gmailu udělá hloupý Gmail
Lukáš Václavík
SoukromíGmailGoogle
Google spouští vlastní VPN a konkurenci se to vůbec nelíbí
Lukáš Václavík
SoukromíVPNGoogle
Vodafonu se zhroutila kabelovka. Síť bývalého UPC má výpadky
Lukáš Václavík
VodafoneUPC
Elon Musk podpořil Signal jako náhradu WhatsAppu. Aplikaci okamžitě zavalili uživatelé
Markéta Mikešová
WhatsAppElon MuskFacebook

Aktuální číslo časopisu Computer

Jak prodloužit výdrž notebooku

Velké testy: gamepady a inkoustové tiskárny

Důkladný test Sony Playstation 5