Drucken mit WinAPI bzw. PrintWinAPI.au3

  • Hallo zusammen,

    bin derzeit dabei für meine Programme auch eine Druckfunktion zu entwickeln. Dies gelingt mir im Ansatz mit WinAPI bzw. PrintWinAPI.au3 bereits ganz gut. So kann ich alle verfügbaren Drucker sehen und einen bestimmten auswählen und mit diesem dann drucken.

    Mein Problem ist derzeit noch, dass ich keine Zeilenumbrüche bzw. neue Zeilen und Absätze bewußt steuern und zum ausdrucken einfügen kann. Frage also, wie kann ich bei sog. Fließtext am Ende einer Zeile einen Zeilenumbruch bewußt und an sinnvoller Stelle herbeiführen und natürlich dann auch zum Ausdruck bringen.

    Bin dankbar für jeden Hinweis zur Lösung. Bin gerne bereit mein erarbeitetes Grundlagenwissen zum Drucken einzubringen.

    Gruß und Danke

    Ynkelonium

  • Grundsätzlich stimme ich dir dabei sogar zu - nur ich habe noch kein Script, geschweige denn einen Ansatz um das Problem zu lösen. Wenn ich sowas hätte, würde ich es selbstverständlich hier reinstellen um die Diskussion zu bereichern.

    So bin ich aber auf Ideen / Erfahrungen der anderen angewiesen.

    Gruß

    Ynkelonium

  • In deinem Ersten Post schreibst du aber das du eins hast!

    EDIT:
    Meinst du sowas?

    [autoit]

    $Text = "Hallo, ich bin die Erste zeile" & @CRLF & "Ich bin die Zweite"
    MsgBox (0,"",$Text)

    [/autoit]

    mfg. Jam00

  • Ich habe hier ein Beispiel für die GDI-UDFs. Sind nur noch nicht ganz fertig.

    Spoiler anzeigen
    [autoit]

    ;This is the script used to produce the graph in the example above.
    #include 'GDI\GDI.au3';the print UDF
    #include 'Constants.au3'
    #include 'WinAPI.au3'
    Global $hp
    Local $mmssgg, $marginx, $marginy
    $File = FileOpenDialog("Textdatei", @WindowsDir, "Textdateien (*.log;*.txt;*.xml)")
    If Not FileExists($File) Then Exit MsgBox(0, '', "Keine Datei ausgewählt")
    $sText = FileRead($File)
    $GUI = GUICreate("")
    $PrinterStruct = _GDI_PrintDlg($GUI)
    If @error Then
    If _WinAPI_CommDlgExtendedError() = 0 Then
    MsgBox(0, '', "Druckdialog abgebrochen")
    Else
    MsgBox(0, '', "Fehler beim Druckdialog")
    EndIf
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $pDC = DllStructGetData($PrinterStruct, "hDC")

    [/autoit] [autoit][/autoit] [autoit]

    If $pDC Then
    $TotalHeight = _GDI_GetDeviceCaps($pDC, $PHYSICALHEIGHT)
    $TotalWidth = _GDI_GetDeviceCaps($pDC, $PHYSICALWIDTH)
    $PrintOffsetX = _GDI_GetDeviceCaps($pDC, $PHYSICALOFFSETX)
    $PrintOffsetY = _GDI_GetDeviceCaps($pDC, $PHYSICALOFFSETY)
    $PrintableWidth = _GDI_GetDeviceCaps($pDC, $HORZRES)
    $PrintableHeight = _GDI_GetDeviceCaps($pDC, $VERTRES)
    If $PrintOffsetX = 0 Then
    $PrintOffsetX = 50
    $PrintableWidth -= 50
    EndIf
    If $PrintOffsetY = 0 Then
    $PrintOffsetY = 50
    $PrintableHeight -= 50
    EndIf

    $tDocInfo = DllStructCreate($tagDOCINFO)
    DllStructSetData($tDocInfo, 1, DllStructGetSize($tDocInfo))
    $DocName = _PrintUDF_CreateTextStruct("Test Doc")
    DllStructSetData($tDocInfo, "lpszDocName", DllStructGetPtr($DocName))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _GDI_StartDoc($pDC, $tDocInfo) ; Dokument beginnen

    [/autoit] [autoit][/autoit] [autoit]

    $Font = _GDI_CreateFont(_FonSizePT($pDC, 12), 0, 0, 0, 700, 0, 1, 0, 0, $OUT_TT_ONLY_PRECIS, 0, 0, 0, "Arial") ; Schrift erstellen
    $OLDFONT = _GDI_SelectObject($pDC, $Font) ; schrift auswählen

    $tRect = _GDI_RectCreate($PrintOffsetX,$PrintOffsetY, $PrintOffsetX+$PrintableWidth-50, $PrintOffsetY+$PrintableHeight) ; Druckbereich festelgen

    $tParams = DllStructCreate($tagDRAWTEXTPARAMS) ; Druckparameter erzeigen
    DllStructSetData($tParams,1,DllStructGetSize($tParams))
    DllStructSetData($tParams,"iTabLength",4) ; Tabstops sind etwa 4 Zeichen lang.

    Do
    _GDI_StartPage($pDC) ; Seite starten
    DllStructSetData($tParams,"uiLengthDrawn",0) ; Gedruckte zeichen auf dieser Seite auf 0 setzen
    $res = _GDI_DrawTextEx($pDC, $sText, $tRect, BitOR($DT_EDITCONTROL, $DT_NOPREFIX, $DT_WORDBREAK, $DT_TABSTOP) , $tParams) ; drucken
    $sText = StringTrimLeft($sText,DllStructGetData($tParams,"uiLengthDrawn") ) ; gedruckte Zeichen aus dem Buffer entfernen
    _GDI_EndPage($pDC) ;Seite beenden
    Until $sText = "" ; wenn kein Text mehr da ist, abbrechen

    _GDI_SelectObject($pDC,$OLDFONT) ; Schrift entfernen
    _GDI_DeleteObject($Font) ; schrift löschen

    _GDI_EndDoc($pDC) ; Dokument beenden
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Schriftgröße für den DeviceContext aus Punkt berechen berechnen
    Func _FonSizePT($pDC, $Pt)
    Return _MulDiv($Pt, _GDI_GetDeviceCaps($pDC, $LOGPIXELSY), 72)
    EndFunc ;==>_FonSizePT
    Func _MulDiv($nNumber, $nNumerator, $nDenominator)
    ; Prog@ndy
    Local $res = DllCall("Kernel32.dll", "int", "MulDiv", "int", $nNumber, "int", $nNumerator, "int", $nDenominator)
    If @error Then Return SetError(1, 0, 0)
    Return $res[0]
    EndFunc ;==>_MulDiv

    [/autoit]
  • Tut mir leid - dann war mein erstes Post wohl leicht mißverständlich.

    Danke für deinen Versuch - aber auf der Ebene von AutoIT ist mir das völlig klar mit den Zeilenumbrüchen etc. Innerhalb von AutoIT komme ich damit problemlos klar.

    Mein Problem beginnt, wenn ich aus meinem AutoIT - Programm heraus Ausdrucke mit Hilfe von WinAPI bzw. PrintWinAPI.au3 auf einen Drucker machen möchte. Im Klartext: Wie sage ich dem Drucker, daß er an einer bestimmten Stelle einen Zeilenumbruch, Absatz oder in der Konsequenz auch eine neue Seite drucken soll ??
    Auf die Steuerzeichen innerhalb von AutoIT wie "@CRLF" etc. reagiert der Drucker nicht.

    Ynkelonium

  • Doch, der Drucker reagiert darauf, aber nur, wenn die Funktion mehrzeilige Texte unterstützt (_GDI_DrawTextEx)

  • Interessant - wenn es auch meinen bisherigen Erfahrungen widerspricht. Aber ich lerne ja gerne dazu ...

    Könntest du mir das ein bißchen näher erläutern oder - wenn das nicht zuviel verlangt ist - an einem kleinen Beispiel verdeutlichen ??

    Danke und Gruß

    Ynkelonium

  • Es gibt in der WinAPI verschiedene Funktionen. Manche können nur einzeilige texte. Andere können auf mehrzeilig umgestellt werden und wieder andere sind mehrzeilig, können aber auf einzeilig umgestellt werden.

    _GDI_DrawTextEx versteht mehrzeilige Texte. Der Text wird in dem Rechteck, das mit übergeben wird, dargestellt, mit Zeilenumbrüchen. Wenn der Stil $DT_WORDBREAK verwendet wird, wird eine Zeile umgebrochen, wenn das Rechteck nicht breit genug ist.
    Wenn die DLLStruct mit den erweiterten Parametern übergeben wird, gibt die Funktion auch die Zahl der gedruckten Zeichen aus. So kann man den Text auf mehrere Seiten verteilen, wenn er nicht auf eine Seite passt.
    Ein Beispiel findest du in meinem Post mit dem Spoiler ;) (Hier)

  • Vielen Dank, ich hoffe und denke daraus kann ich etwas machen. Allerdings fehlt mir die

    #include 'GDI\GDI.au3' ;the print UDF

    Woher bekomm ich die am einfachsten ??

    Ynkelonium