Drucken mit HBPrinter - Was geht wie warum ???

Moderator: Moderatoren

Wer kennt, nutzt oder verabscheut HBPrinterX ?

Ich nutze HBPrinterX ausschließlich
6
14%
Ich nutze HBPrinterX gelegentlich bzw. zusätzlich
10
24%
HBPrinterX habe ich früher mal genutzt
1
2%
geprüft, aber für mich ungeeignet
1
2%
der Schrott gehört verboten
0
Keine Stimmen
In nutze grundsätzlich keine Fremdprodukte
0
Keine Stimmen
Noch nie gehört oder kein Interesse
2
5%
Ich nutze Reportgeneratoren oder ähnliches
11
26%
Ich nehme XbpPrinter() pur
11
26%
 
Insgesamt abgegebene Stimmen: 42

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Hi,
was verstehst du unter ZENTRIEREN ?

Du mußt immer mit dem 1. Parameter angeben wo dein Messpunkt liegt.
Normalerweise ist das der linke Rand bei Ausrichtung <L>inks, du kannst aber auch einen in der Mitte (wo du willst) und dann die Ausrichtung C oder Z wählen (zentrieren UM den nPosX).
Das geht schon !

Wenn du bei PrintMemo() Blocksatz meinst, der geht nur wenn eine Zeile auch lang genug ist (also keine kurze Zeile oder mit CRLF am Ende) überstrecken.
Ansonsten geht auch hier Zentrieren, wenn nicht, bitte Quellcode liefern.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Neue Version (1.36 - 29.01.2012) wurde auf der Homepage freigegeben.

Beseitigt:

1. Zeilen mit einem Zeichen werden nicht gedruckt.
2. PrintMemoLinePosY und PrintMemoLinePosX wurden bei einzeiligen Texten nicht richtig gesetzt.
3. PrintMemoPage() => cTextRest - gibt den Text zurück, der nicht gedruckt werden konnte.

http://www.familie-brandel.de/dateien/dat_index_d.html
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Wow, danke, werde ich mir morgen gleich reinziehen, wenns das Tagesgeschäft erlaubt.

Hier mein Code bezüglich zentrieren:

Code: Alles auswählen

::PrintText(::nLinkerRand2, nY += ::LineFeed() * 2, "Dies ist eine zentrierte Textzeile", "Z", 1900)
Wird mit negativen X-Coordinaten gedruckt. Lasse ich das "Z" weg oder zentriere selbst, gehts.

Was mache ich falsch?

Danke.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Ich schrieb doch, dass du mit dem nPosX den Mittelpunkt des Zentrierens selbst festlegen musst.
nY += ::LineFeed() * 2
ich würde das nicht als Parameter übergeben, sondern vorher berechnen.
Häufig braucht man mehrere Aufrufe je Zeile und dann vergisst man schnell ...

Hier ist der Code der Umsetzung ...

Code: Alles auswählen

         case cAusrichtung $ "CZM"                        // zentrieren, mittig, center
              do case
                 case nDrehen = 0 .or. nDrehen = 180
                    aPos := ::PosHBtoXPP(nPosX-nTxtLen/2, nPosY)     // rechts - right
                 case nDrehen = 90 .or. nDrehen = 270
                    aPos := ::PosHBtoXPP(nPosX, nPosY+nTxtLen/2)     // rechts - right
                 otherwise                                           // noch nicht richtig !
                                                                     // not correct yet.
                 aPos := ::PosHBtoXPP(nPosX-nTxtLen/2, nPosY)        // zentrieren      - center
              end case
nPosX ist die linke Druckposition bei Ausrichtung "L"
nPosX ist die gewünschte Mitte bei Ausrichtung "C" (oder Z oder M)
nPosX ist der rechte Druckposition bei Ausrichtung "R"

Beispiel:
Zahlen:

Code: Alles auswählen

::PrintText( nRechtesSpaltenEnde, nPosY, Transform(nWert, ... ), "R" ) ... ein Eventuelle EUR wird dann als extra Zeile geschrieben ...
::PrintText( nRechtesSpaltenEnde+10, nPosY, "EUR", "L" ) ... linksbündig 1mm nach der letzen 0
Zentriert - ja was ist denn die Mitte ? :

Code: Alles auswählen

nMitte :=  ::nPaperSizeX / 2     =>  Standard ist ::nPaperSizeX := 2100    // Zentriert auf physikalische Mitte
nMitte :=  (::nRightMargin - ::nLeftMargin) / 2  + ::nLeftMargin           // Zentriert auf Mitte zwischen den Rändern
nMitte :=  ::nLineLen / 2 + ::nLeftMargin                                  // Zentriert auf Zeilenmitte (eventuell kürzer als Standard Ränder)
nMitte :=  nJederWert >= ::nLeftMargin                                     // Zentriert auf Zeilenmitte (eventuell kürzer als Standard Ränder)
... wie auch immer
::PrintText( nMitte, nPosY, cText ) // ich würde die Länge des Textes nicht über den Längenparameter sondern die Textlänge steuern.
Man könnte meinen, dass die Druckerklasse selbständig immer die Mitte der Zeile wählt, das wäre aber sehr unflexibel.
Auf die bestehende Weise kann man mehrere zentrierte Spalten mit links- und rechstbündig mischen.
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

brandelh hat geschrieben:Ich schrieb doch, dass du mit dem nPosX den Mittelpunkt des Zentrierens selbst festlegen musst.
Sorry, hab ich nirgends gesehen, nicht in diesem Forum und nicht in der Beschreibung in der Klasse selbst.
brandelh hat geschrieben:nY += ::LineFeed() * 2
ich würde das nicht als Parameter übergeben, sondern vorher berechnen.
Häufig braucht man mehrere Aufrufe je Zeile und dann vergisst man schnell ...
Mach ich auch so, nur wenn die gesamte Zeile eh feststeht, "spare" ich hiermit Code.
brandelh hat geschrieben:Hier ist der Code der Umsetzung ...
und da steht eben auch:

// noch nicht richtig !
// not correct yet.
aPos := ::PosHBtoXPP(nPosX-nTxtLen/2, nPosY) // zentrieren - center
brandelh hat geschrieben:nPosX ist die gewünschte Mitte bei Ausrichtung "C" (oder Z oder M)
Ok, werde ich testen, hab ich dann falsch verstanden. Bei PrintMemo ist es mir noch nicht klar, weil ja jede Zeile eine andere Länge des zu druckenden Textes haben kann, ich aber nur 1x die X-Koordinate fürs Zentrieren übergeben kann. Werde es testen.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Werner_Bayern hat geschrieben:
brandelh hat geschrieben:Ich schrieb doch, dass du mit dem nPosX den Mittelpunkt des Zentrierens selbst festlegen musst.
Sorry, hab ich nirgends gesehen, nicht in diesem Forum und nicht in der Beschreibung in der Klasse selbst.
ich hatte zuerst auf deine Frage oben geantwortet und dann die Meldung mit der neuen Version herausgegeben.
Ich meinte also die Nachricht verfasst: So, 29. Jan 2012 23:15 von mir ;-)
BrandelH hat geschrieben: Hi,
was verstehst du unter ZENTRIEREN ?

Du mußt immer mit dem 1. Parameter angeben wo dein Messpunkt liegt.
Normalerweise ist das der linke Rand bei Ausrichtung <L>inks, du kannst aber auch einen in der Mitte (wo du willst) und dann die Ausrichtung C oder Z wählen (zentrieren UM den nPosX).
Das geht schon !
Macht nichts, ich überlese auch einiges, z.B. meine eigenen Quellcode-Kommentare :-)

Gra-Funktionen können seit etwa 1.90 einen Parameter für Ausrichtung verwenden, ältere konnten das nicht, daher verwende ich
die "Abmessen und Verschieben" Methode. Das funktioniert aber wie beschrieben, es sollten aber nicht gerade Blanks am Ende oder Anfang des Strings sein.
(Links nicht am Anfang, Rechts nicht am Ende, Zentriert, nur gleich viele auf beiden Seiten, besser keine ;-) )

Printmemo() kennt nur einen Mittelpunkt für alle Zeilen im String !
Bei Blocksatz werden kurze Zeilen linksbündig, der Rest auf die Ränder gestreckt - in der Vorschau sieht es aus, also ob die erste Zeile nach oben abhaut,
keine Ahnung warum aber gedruckt wird richtig.
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

danke, hatte ich überlesen. Das mit dem Zentrieren klappt, auch bei PrintMemo()! =D>
Hatte ich tatsächlich falsch verstanden, bzw. war mir durch das "Studium" Deines Quelltextes nicht klar geworden.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

hab jetzt Deine aktuelle Version 1.36ansi getestet, scheint alles ok zu sein. Danke nochmals, Du darfst die 1 Flasche leeren :lol:
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Es scheint, als habe so mancher Angst vor den Klassen, daher hier mal ein Beispiel, wie man ohne eigene Klassen
den HBPrinter einsetzen kann. Dann gibt es allerdings nicht meinen Druckerdialog (HBPrintD.PRG), denn der braucht Klassen ;-)

In der beigefügten ZIP ist auch eine PDF mit Druckbeispiel.

Code: Alles auswählen

*#### ANSI .t. äöü ÄÖÜ ß !!!!
#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "Appevent.ch"
#include "Font.ch"
#include "XBPDEV.ch"

procedure AppSys
   SET CHARSET TO ANSI
return

*---------------- Fonts nur einmal erzeugen - create fonts only once ------
procedure main
local oHBP, nPosY, nLR, nSpaNr, x, aDaten, cWindowsDruckerObjekt

aDaten := { {"Text a",         123.12},;
            {"Text bb",         12.54},;
            {"Text ccc",      1234.23},;
            {"Text dddd äöüß",    9.3} }

// cWindowsDruckerObjekt := "Canon iP4500 series" // kann man vorgeben, bei NIL oder keiner Angabe => Standarddrucker

oHBP := HBPrinter():New():create(cWindowsDruckerObjekt) // :create() nutzt Standarddrucker
if oHBP:IsPrinterError()             // Fehler verhindern, avoid errors
   msgbox("Drucker ist nicht verfügbar !")
else
   oHBP:addFont("10.Arial") // hier werden alle benötigten Fonts in ein internes Array geladen
   oHBP:setFont(1)  // hier wird der gewünschte Font gewählt
   oHBP:StartDoc("Drucktest")  // ein LASER wird dies im Display anzeigen, ein PDF Druckertreiber wird es als Dateinamen verwenden.
   nPosY  :=  200   // 2 cm von oberer Papierkante - Einheit 1/10 mm => 1 mm == 10, 1cm = 100
   nLR    :=  200   // 2 cm von linker Papierkante
   nSpaNr := 1200
   for x := 1 to len(aDaten)
       //  :PrintText( nPosX, nPosY, xData, cAusrichtung, nMaxLen, cArt, nFarbe, nDrehen ) - das hilft immer ;-)
       oHBP:PrintText( nLR  , nPosY, aDaten[x,1] ) // Standardausrichtung in Drucklänge, nicht gedreht ...
       oHBP:PrintText(nSpaNr, nPosY, transform(aDaten[x,2],"999,999.99"), "R" ) // Zahlen formartiert rechtsbündig
       nPosY += oHBP:LineFeed()  // eine Zeile weiter (0,0 ist linke obere Papierkante) mit Standardabstand. 50 wären 5 mm ... wie man will.
   next
   oHBP:EndDoc()
endif
msgbox("gedruckt Umlaute äöü")
return
Dateianhänge
DruckenEinfach.zip
(29.72 KiB) 480-mal heruntergeladen
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Man kann auch den XbpPrintDialog() nutzen, hier ein Beispiel, das auch die :SAY() Syntax nutzt.

Code: Alles auswählen

*#### ANSI .t. äöü ÄÖÜ ß !!!!
#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "Appevent.ch"
#include "Font.ch"

#pragma Library( "XppUI2.lib" )

PROCEDURE Main
   LOCAL oXbpPrinter, oDlg, oHBPrinter

   oDlg := XbpPrintDialog():new()
   oDlg:enablePrintToFile := .f.
   oDlg:printToFile       := .f.
   oDlg:create()
   oXbpPrinter := oDlg:display()
   oDlg:destroy()

   if oXbpPrinter # NIL

      oHBPrinter := HBPrinter():New(oXbpPrinter):create()

      if oHBPrinter:IsPrinterError()             // Fehler verhindern, avoid errors

         ? "Standarddrucker ist nicht verfügbar !"
         ? "Standardprinter is not ready !"
         ?
         ? "Status: ",oHBPrinter:printerStatus(),"=",cPrinterStatus(oHBPrinter:printerStatus())

      else

         oHBPrinter:addFont("12.Arial")
         oHBPrinter:setFont(1)

         oHBPrinter:StartDoc()
         oHBPrinter:say(15,30,"Hello World")
         oHBPrinter:say(20,10,"Drucker: ")
         oHBPrinter:say(20,20,oHBPrinter:DevName)
         oHBPrinter:say( 5,70,dtoc(date()))
         oHBPrinter:EndDoc()

      endif

      oXbpPrinter:destroy()
      oHBPrinter:destroy()

   endif

return
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

ich habe den Fehler gefunden, warum es bei mir bei PrintMemo() gekracht hat: Es handelt sich um ein Angebots-Formular, in der :PrintForm() - Methode ist u. a. eine Fußzeile definiert, die über PrintMemo() gedruckt wird. Bei dem Anwender waren jedoch mehr Zeilen in dem Memofeld, als in der Fußzeile Platz ist. Deshalb macht Dein Code ja völlig korrekt:

Code: Alles auswählen

if lNeedNewPage
  ::NewPage()
  ::PrintForm()
  lNeedNewPage := .f.
endif
Was einen rekursiv-verschachtelten Aufruf von :PrintForm in diesem Fall bedeutet. :!: Kaum nach 520 Seiten kracht es mit einer xppfatal...
Also, der Fehler liegt nicht in Deiner Printerklasse, sondern bei mir, ich muss das einfach über PrintMemoPage() machen :wink:
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Hubert,

Deine Methode PrintMemo() hat aktuell noch ein Problem bei MemoStrings, die 2x das CRLF hintereinander enthalten. Passiert meist beim Einfügen über die Zwischenablage in ein Memofeld. Erst ein

Code: Alles auswählen

MemoTran(rtrim(cMemoFeld), " ")
bringt einen besseren Druck, aber Leerzeilen sind damit weg. Ansonsten werden nur mehr Leerzeilen anstatt des Textes gedruckt. :!:
Deine Funktion

Code: Alles auswählen

NoSoftCR(cTxt)
müsste wohl angepasst werden?
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Kannst du mir eine kleine Demo mit Daten machen und per ZIP zusenden ?
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

ist unterwegs, danke.

Muss mich etwas korrigieren, Abhilfe schafft:

Code: Alles auswählen

strtran(rtrim(cMemoFeld), chr(32) + chr(13) + chr(10) + chr(32) + chr(13), CRLF)
Damit werden dann auch Absätze und harte Zeilenumbrüche wieder korrekt gedruckt, beim obigen Beispiel wurde sonst alles ein Absatz.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

2 Sachen für Deine geniale Druckerklasse:

1: Die Methode PrintMemo muss m. M. n. wie folgt geändert werden:

Code: Alles auswählen

::PrintMemoLineCount++
if lNeedNewPage
    ::NewPage()
    ::PrintForm()
    lNeedNewPage := .f.
endif
::PrintMemoLinePosX := nPosX
::PrintMemoLinePosY := nPosY
Die letzten 2 Zeilen dürfen nicht vor dem

Code: Alles auswählen

if lNeedNewPage
stehen, sonst werden die 2 Vars ::PrintMemoLinePos? nicht in jedem Fall korrekt bestückt.


2: Die Abort-Methode wäre für mich hilfreich, hab sie jetzt so implementiert:

Code: Alles auswählen

METHOD _HBPrinter:abort()
       local uReturn := NIL

       if ::oPS:device():isDerivedFrom( "XbpPrinter" )
          uReturn := ::oPS:device():abort()
       endif

       if uReturn = NIL    // zur Zeit PreviewPS kein Drucker angeschlossen ! - PreviewPS is active
          if ::oPrinterPS:device():isDerivedFrom( "XbpPrinter" )
             uReturn := ::oPrinterPS:device():abort()
          endif
       endif
    return uReturn
Ist das so korrekt, hat das Seiteneffekte?

Danke!
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

gibt es eine Möglichkeit, vor einem PrintMemo die Anzahl der zu druckenden Zeilen feststellen zu lassen?
Hintergrund ist, dass ich zeilenweise prüfe, ob eine neue Position gedruckt werden muss, wenn ja, dann wird ein Bild gedruckt. Hab ich nun ein längeres PrintMemo, das evtl. sogar eine neue Seite druckt, bekomme ich das ja so nicht mit, sondern erst im Nachhinein. Dann ist aber bereits die neue Seite in Bearbeitung und ich kann auf der vorherigen ja nichts mehr drucken.

Danke.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Ich glaube so eine Methode habe ich (noch) nicht, sollte nicht so schwierig sein, man muss nur den Ausdruck verhindern aber sonst alles berechnen.

Den Ausdruck auf die aktuelle Seite zu begrenzen, dafür habe ich :PrintMemoPage() vorgesehen.
Anstatt eine neue Seite anzufangen, druckt :PrintMemoPage() alle Zeilen die in den vorgegebenen Bereich auf der aktuellen Seite passen und gibt den Rest als String zurück.
Nach dem Ende der sonstigen Ausdrucke der Seite und nach dem newPage() kann man dann den Rest auf diese und folgende Seiten drucken - wenn man möchte.
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Servus Hubert,

printMemoPage kenne ich, ist ja noch ziemlich neu. Es geht aber darum, vorab festzustellen, wieviele Zeilen mit dem nächsten PrintMemo* gedruckt würden.
Dein Vorschlag ist gut, ich werde mir Deine Methode mal ansehen und ggf. um einen Simulationsparameter erweitern.

Danke.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Diese Funktion wäre sehr nützlich, ich werde mir morgen Zeit nehmen und die Sache ansehen.
:PrintMemo() gibt ja nicht die Zeilen zurück, den Rüchgabewert zu ändern würde bestehenden Code brechen. Das geht nicht :!:
Wenn man die Methode kopiert und die Druckbefehle weg läßt, könnte man zwar den Rückgabewert passend gestallten und den Namen schön wählen, aber man müsste in Zukunft immer nachpflegen ...
Deine Idee mit dem Simulationsparameter in Verbindung mit der vorhandenen Variable :PrintMemoLineCount ist sinnvoll, aber die Anzahl der Parameter wird immer länger.

Ich denke ich setze es so um:
  1. Interne Var für Simulationsflag.
  2. neue Methode :PrintMemoCountLines(...) // gleiche Parameter wie PrintMemo(), da diese durchgereicht werden müssen
  3. Simulationsflag := .t.
  4. :PrintMemo() ausführen
  5. :PrintMemoLineCount speichern
  6. Simulationsflag := .f.
  7. den gespeicherten Wert von :PrintMemoLineCount zurückgeben.


das ist keine große Sache und ich sollte Morgen dazu kommen, dann arbeite ich auch deine beiden Korrekturen ein.
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2120
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 29 Mal
Danksagung erhalten: 70 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Werner_Bayern »

Das erspart mir eine lange Nacht und bringt mehr Schlaf! :sleepy1:
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Auf der Homepage steht die neue Version 1.37 vom 04.04.2013

Sie enthält die diskutierten Änderungen ;-)
Gruß
Hubert
Benutzeravatar
mini990
1000 working lines a day
1000 working lines a day
Beiträge: 592
Registriert: Sa, 28. Jan 2006 9:44
Wohnort: Berg-Richtheim bei Neumarkt i.d.Opf.
Danksagung erhalten: 1 Mal

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von mini990 »

Hallo,
arbeite mit Deiner Druckerklasse und bin begeistert.
Ein Frage hätte ich:
Ist eine Vorschau ohne Druckerauswahl möglich?

Gruß Stefan
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

Du meinst ob ich ein Beispielfenster anbiete ohne die Druckerliste ?
Nein, denn dieses Fenster soll ja gerade der Druckerauswahl dienen.

Aber du kannst hingehen und das Fenster nutzen und alles entfernen was du nicht benötigst.
Grundsätzlich wird der HBPrinter intern dann den Standarddrucker auswählen, aber das angezeigte Fenster ist auf keinen angewiesen.
Gruß
Hubert
Benutzeravatar
Schorsch
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 45
Registriert: So, 21. Sep 2008 19:21
Wohnort: Sinsheim im Kraichgau

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von Schorsch »

Hallo Hubert,
ich benutze deine Druckerklasse um vom klassischen "DOS" drucken auf LPTx wegzukommen und die Windowsumgebung dafür zu nutzen. Ich möchte jetzt gerne einen Formular-Nadeldrucker durch einen Farblaser ersetzen und dort die unterschiedlichen (farbigen ) Durchschläge nachbauen. Als grundsätzliche Lösung wird ein farbiger Streifen auf dem rechten Blattrand akzeptiert und ein "individueller" Text, der den Empfänger der Kopie dieser Farbe benennt.
Ich habe mir folgende Lösung jetzt überlegt:
Ich erstelle das Formular (Inhalt ist ja für alle Farben identisch) und gebe beim Aufruf die "Farbe" als Parameter mit und würde das im variablen Teil Methode PrintForm() einbauen . Der Empfänger soll aber in den konstanten Kopf/Fuß Teil Methode Print() untergebracht werden. Ich möchte auch den Printingdialog() nur einmal aufrufen und dann alle 5 Exemplare (5 Farben 5 Empfänger) drucken. Ich muss gestehen, dass ich die Struktur bzw. die Anwendung deiner Klasse noch nicht so verstanden habe, dass ich weiß ob meien Überlegung richtig ist an welcher Stelle ich dies bewerkstelligen kann.
Für Tipps und Hinweise diesbezüglich wäre ich sehr dankbar.
Gruß
Schorsch
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Drucken mit HBPrinter - Was geht wie warum ???

Beitrag von brandelh »

PrintForm() druckt die fixen Texte, Bilder, Linien der Seiten, die Farbe bzw. Seiten-Art würde ich nicht per Parameter sondern per Instanzvariable deiner abgeleiteten Klasse übergeben.
Print() regelt grundsätzlich den kompletten Ausdruck und steuert auch die nötigen Seitenumbrüche, vor dem PrintForm() aufruf könnte man dann die ART setzen, damit Printform die Texte und Farben wählen kann.
Printingdialog() - meinst du meine Methode die HBPrintDialog() aufruft oder den XbpPrintDialog() ?

Grundsätzlich geht alles ;-)

Mein HBPrintDialog() bietet eine Druckerauswahl mit Vorschau und Begrenzung auf Druckseiten etc. er steuert direkt :Print() an.
Falls man den XbpPrintDialog() nutzen will um Systemeinstellungen anzupassen geht das auch, aber man muss dann auf Vorschau etc. verzichten.

Test.PRG zeigt den grundsätzlichen Aufbau, ich persönlich nutze abgeleitete Klassen mit den Werten für Absender etc. - auch als Array oder nun DataObject.
Lade die Infos vor dem Aufruf von oHB:PrintingDialog() und nutze diese in :Print() oder :PrintForm() ... Beispiel:

Code: Alles auswählen

...
SET CHARSET TO ANSI // OEM geht aber auch
...
procedure drucken
   local oHBPrinter

   oHBPrinter := MyHBPrinter():New():create() // Standarddrucker als Vorgabe - Auswahl über PrintingDialog() möglich
   if oHBPrinter:IsPrinterError()             // Fehler verhindern, avoid errors
      Fehlermeldung
   else
      // defines verwenden, das hält flexibel, muss aber mit AddFont() übereinstimmen. 
      #define HB_FONT_14Arial 1
      #define HB_FONT_12Arial 2
      oHBPrinter:addFont("14.Arial")  // was man so braucht
      oHBPrinter:addFont("12.Arial")
      oHBPrinter:cVorgabeSeiten := "1-2" // man kann dem Printerdialog auch die Seitenauswahl vorgeben ...
      oHBPrinter:icon  := NIL // := ICON_APPLICATION // das ICON der Anwendung sieht besser aus als Standard Xbase++

      oHBPrinter:Adressen := { { "Herrn", "XYZ", "Str. 4", "12345 Orts"}, { "Frau", "Qwert", "Str. 2", "12345 Niers"}, ... }
      ... eventuell weitere Daten

      oHBPrinter:PrintingDialog( .t. ,;   // ESC -> close
                              .t. ,;   // ALT+Enter and Enter will Print
                              xbeK_ALT_P)  // ALT+P will print
endif
return

*-----------------------------------------------------------------------------------------------------
Eventuell mehrere Ableitungen um z.B. Gemeinsamkeiten der Firmenformulare zentral zu halten.
*-----------------------------------------------------------------------------------------------------
CLASS  MyHBPrinter from HBPrinter
   EXPORTED:
      METHOD Print                 // Alle variablen Druckausgaben werden hier definiert, wenn nötig wird ein
                                   // Seitenwechsel durchgeführt, der Seitenzähler erhöht und ::PrintForm() aufgerufen.
      METHOD PrintForm             // Alle fixen Bestandteile einer Seite, egal ob unten oder oben werden hier definiert,
                                   // hier wird KEIN Seitenumbruch aufgerufen, denn der könnte unnötig sein (1.Seite).

      VAR aAdressen      // ein Adresse je Dokument ?
      VAR nDokument     // wenn mehre in einem Druckjob sind, muss man sie sich merken
      VAR FormularArt     // hier würde z.B. in Print "F1", "F2" eingetragen werden und PrintKopf() reagiert mit Titel und Farbe
                                // oder 1, 2, 3, als Index für ein Array in FormularFarbe, FormularTitel etc. 
      oder 
      VAR FormularFarbe // als Farbwert vor dem Aufruf von PrintKopf() oder als Array wenn FormularArt als Index dient.
      VAR FormularTitel // { "Formular Eins", "Formular Zwei", ..} wenn FormularArt = 1 => ::FormularTitel[::FormularArt] => "Formular Eins" 
      
      VAR SeiteImDokument // falls man mehrere Anschreiben in einem Druckjob erledigt, passt der eingebaute Seitenzähler nicht mehr, selbst verwalten !
ENDCLASS

*-------------------------------------------------------------
* die folgenden Methoden anpassen - folowing methods has to be modified
*-------------------------------------------------------------
METHOD MyHBPrinter:PrintForm()        // Alle fixen Bestandteile einer Seite, egal ob unten oder oben werden hier definiert,
                                      // hier wird KEIN Seitenumbruch aufgerufen, denn der könnte unnötig sein (1.Seite).
   local altFont, x,y
   ::HBPrinter:PrintForm()           // falls Vorgabeformulare benötigt werden sonst kann es weggelassen werden 

   altFont := ::SetFont(HB_FONT_14Arial) // Wert vor Aufruf sichern und am Ende wieder setzen ! 

   ::PrintText( ... ) // Absender ?

   // wenn FormularArt als eindeutige ID ausgeführt wird
   do case
      case ::FormularArt = "F1"
           ::PrintText(.... "Formular Eins")
           ::PrintText(.... "Seite: "+alltrim(str(::SeiteImDokument )))
           ... FarbBox oder Linie drucken ...
      case ::FormularArt = "F2"
           ::PrintText(.... "Formular Zwei")
           ::PrintText(.... "Seite: "+alltrim(str(::SeiteImDokument ))) // falls immer gleich,  nur einmalig außerhalb von do case
           ... FarbBox oder Linie drucken ...
   end

   // wenn FormularArt als numerischer Index ausgeführt wird:
   ::PrintText(....  ::FormularTitel[::FormularArt] )
   ::PrintText(.... "Seite: "+alltrim(str(::SeiteImDokument )))
   ... FarbBox oder Linie drucken mit ::FormularFarbe[::FormularArt]

   ...

   ::SetFont(altFont)

   // LOGO ?

   ::PrintBmp(1730,600,200,,"BILD.BMP")  // auch JPEG oder PNP z.B. als Logo

return self

*-------------------------------------------------------------
METHOD MyHBPrinter:Print()            // Alle variablen Druckausgaben werden hier definiert, wenn nötig wird ein
                                      // Seitenwechsel durchgeführt, der Seitenzähler erhöht und ::PrintForm() aufgerufen.
   local  x,  nPosX, nPosY 
   ::nPageNo := 1
   ::lFirstPageForm := .f.         // Formular 1. Seite noch nicht gedruckt - form 1. page not printed
   ::nFirstLine := 250
   ::SetFont(HB_FONT_12ARIAL)
   // entweder 
   ::FormularArt := "F1"
   // oder 
   ::FormularArt := 1

   ::nDokument   := 1  // wählt Adresse für Anschreiben
   ::SeiteImDokument := 1
   ::PrintForm()      // erste Seite Formular drucken

   nPosX := ... //  Erste Zeile der Adresse festlegen 
   nPosY := ...
   for x := 1 to len( ::aAdresse[::nDokument] )
      ::PrintText(nPosX, nPosY, ::aAdresse[::nDokument, x ]
      nPosY += ::LineFeed()
   next 
   ...
   weiterer Text 
   ...
   if nPosY > ... // neue Seite im gleichen Dokument nötig !
      nPosY := ::nFirstLine
      ::SeiteImDokument++
      ::NewPage()
      ::PrintForm()
   ...

   // das nächste Formular ist nötig, aber gleiche Adresse
   ::FormularArt := "F2" oder 2  // eventuell neue Seitennummerierung ? Ich denke nicht, da gleiche Adresse (wird nicht gedruckt)
   nPosY := ::nFirstLine
   ::SeiteImDokument++
   ::NewPage()
   ::PrintForm()
   ...

   // das nächste Dokument ist nötig - Falls der Aufbau es erlaubt kann man auch eine For-Next Schleife für Dokumente erstellen und mit Do Case das jeweilige Dokument auswählen

   ::nDokument ++  // wählt Adresse für Anschreiben
   ::FormularArt := "F1" oder 1  
   ::SeiteImDokument := 1
   ::PrintForm()      // erste Seite Formular drucken

   nPosX := ... //  Erste Zeile der Adresse festlegen 
   nPosY := ...
   for x := 1 to len( ::aAdresse[::nDokument] )
      ::PrintText(nPosX, nPosY, ::aAdresse[::nDokument, x ]
      nPosY += ::LineFeed()
   next 
   ...
   weiterer Text 
       
   und so weiter und so fort

return self

*--------------------- allgemeine Funktionen - einmalig im Programm --------------------------
*                      used functions, usefull for other Programms too

Function ErrBox(uText,cTitel)
   local cText,x,xMax
   DEFAULT cTitel TO "Fehlermeldung"
   do case
      case valtype(uText) = "A"
           cText := uText[1]
           xMax  := len(uText)
           for x := 2 to xMax
               cText += chr(13) + uText[x]
           next
      case valtype(uText) = "C"
           cText := uText
      otherwise
           cText := "ErrBox wurde mit falschem Parameter "+;
                    " uText  aufgerufen ! Type "+valtype(uText)+;
                    " statt C oder A"+chr(13)+;
                    "Bitte diesen Fehler melden."
   endcase
   MsgBox(cText,cTitel)
return NIL

*---------------------------------------------------------------------------
function ntrim( nVar )
return strTran(alltrim( str( nVar ) ),".",",")
*----------------------------------------------------------




Gruß
Hubert
Antworten