Tisk v Delphi 4. - převod délkových jednotek a ladění tisku - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Tisk v Delphi 4. - převod délkových jednotek a ladění tisku

tisk

15. března 2002, 00.00 | Dnešní díl bude problémově orientovaný - nejdříve se podíváme na problémy spojené s délkovými jednotkami a poté si ukážeme, jak efektivně ladit tisk.

Délkové jednotky

Pokud budete ve svém programu implementovat funkci tisku, pravděpodobně dáte uživateli možnost nastavit různé parametry stránky - okraje, velikosti záhlaví a zápatí apod. Zde je ovšem skryt malý háček - zatímco při vykreslování stránky na tiskárně je používanou jednotkou tiskový bod, uživatel by nejspíš chtěl parametry zadávat v přirozenějších jednotkách, jako jsou centimetry, milimetry nebo v anglosaských krajích palce. Jak mu to umožnit?

Nejdříve dva jednoduché vzorečky:

px = inch * res
1 inch = 2,54 cm = 25,4 mm

První vzorec říká, že délku v tiskových bodech spočítáme z délky v palcích vynásobením rozlišením tiskárny. To je celkem jasné už jenom z dešifrování zkratky jednotky pro rozlišení (DPI = dots per inch = body na palec). Druhý řádek jen uvádí do vztahu palce, centimetry a milimetry.

Jedinou neznámou zůstává rozlišení tiskárny. Na jeho zjištění existuje API funkce GetDeviceCaps. Ta umí vracet hodnoty různých parametrů zobrazovacích zařízení připojených k počítači, rozlišení je jen jeden z mnoha. Prvním parametrem této funkce je handle kontextu zařízení, o kterém chceme zjišťovat informace, druhým je pak speciální konstanta identifikující, co chceme vědět. Výsledek nám funkce předá jako svou návratovou hodnotu.

V našem případě použijeme jako druhý parametr konstanty LOGPIXELSX a LOGPIXELSY. Proč dvě? Protože potřebujeme zjistit jak horizontální tak i vertikální rozlišení dané tiskárny a ty nemusí být vždy stejné.

Výsledkem naší snahy jsou dvě jednoduché funkce pro převod z milimetrů na tiskové body jak ve vodorovném tak ve svislém směru:

function MMToPrinterPixelX(MM: Integer): Integer;
begin
  Result:=Round((MM * GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSX))/25.4);
end;

function MMToPrinterPixelY(MM: Integer): Integer;
begin
  Result:=Round((MM * GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY))/25.4);
end;

Ještě malé upozornění: Tyto funkce používejte až po zavolání BeginDoc, protože do té doby není jisté, na které tiskárně se rozhodnete tisknout, takže použitá vlastnost Printer.Canvas.Handle ještě není inicializována.

DebugPrint

Pokud budete někdy ladit tisk v nějakém větším programu (což se mi už dvakrát v životě přihodilo), spotřebujete tuny papíru a inkoustu (či toneru, pásek a já nevím čeho ještě) a navíc většinu doby budete jen čekat, až se vytiskne váš poslední pokus. Jelikož jsem tohle nepovažoval za produktivní způsob práce, udělal jsem si kdysi pomocnou unitu DebugPrint, kterou vám tu teď představím, protože si myslím, že by vám mohla podstatně ulehčit práci. Je open source a můžete si ji stáhnout z mých stránek a používat dle libosti.

Princip unity je v tom, že místo TPrinter definuje objekt TDebugPrinter (a proměnnou DebugPrinter), které jsou z vnějšku naprosto shodné s TPrinter a Printer. Podstatný rozdíl je ale "vevnitř" - pokud jimi totiž nahradíte právě tyto standardní objekty, výsledky tisku nepoputují na tiskárnu, ale do metasouboru (přípona .emf) umístěného na ploše Windows (případně kdekoliv jinde - můžete zvolit pomocí vlastnosti OutputDir). Pro každou stránku je vytvořen nový metasoubor, který pak můžete prohlížet prakticky jakýmikoliv prohlížečem obrázků (třeba mým oblíbeným AcdSee).

Výhody jsou zřejmé - ušetřený papír a čas. Celý tisk se tak dá odladit za minimálních nákladů a když všechno funguje, stačí vytisknout jednu dvě stránky pro ověření.

Unita se nejlépe používá spolu s podmíněným překladem - pak stačí pro přepnutí mezi laděním a ostrou verzí jen přepsat jedno $define na $undef:

{$define DebugPrint}
    // zapne ladící verzi (pro ostrou napište {$undef DebugPrint})
.
.
.
{$ifdef DebugPrint}  // ladící verze
uses
  DebugPrint;
{$else}              // ostrá verze
uses
  Printers;
{$endif}
.
.
.
procedure PrintSomething;
begin
  with {$ifdef DebugPrint} DebugPrinter {$else} Printer {$endif} do 
  begin
    // samotný tisk probíhá úplně stejně v obou verzích
    BeginDoc;
    Canvas.MoveTo(0, 0);
    Canvas.LineTo(PageWidth, PageHeight);
    NewPage;
    Canvas.MoveTo(0, 0);
    Canvas.LineTo(PageWidth, PageHeight);
    EndDoc;
  end;
end;

Příště

Příště se podíváme na to, jak ve Windows přepnout výchozí tiskárnu, což rozhodně není tak jednoduchý úkol, na jaký to vypadá.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: