Announcement

Collapse
No announcement yet.

Printing More Than One Line

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Printing More Than One Line

    Hello All:

    I'm writing to find out if anyone has been able to tell a printer
    to print more than one line. I know, it sounds insain, but the
    code below works great, except for one minor problem. It refuses
    to wrap text when it won't fit on the line, and it prints $CRLF as
    2 box-like things instead of going to a new line as it should. Any
    ideas? I should mention that I save the printer handle in
    LastPrint so when I call the code again, it can use the previous
    handle to access the printer. Also, would one of you programming
    geniuses mind telling me if the below code is compatible with Windows NT?
    Thanks!

    -----CODE-----
    #compile exe
    #include "win32api.inc"
    %NOFILEDLG=1
    #INCLUDE "COMDLG32.INC"
    DECLARE FUNCTION FontMaker (fh&, fw&) AS LONG
    GLOBAL LastPrint AS LONG, NewContents AS ASCIIZ*35000

    Function pbMain
    NewContents="This is a test print to see if the printer will wrap text when it needs to." & $CRLF
    NewContents=NewContents & "What's more, it doesn't seem to recognize $CRLF's, either."
    Call PrintFile
    End Function

    FUNCTION PrintFile() AS LONG
    LOCAL hPrnDC AS LONG, hOrigFont AS LONG, hdc AS LONG, flags AS LONG,_
    hFont AS LONG, di AS DOCINFO, lpSize AS SIZEL, Dud as Long, hWnd&
    Dud=0
    IF LastPrint=0 THEN
    flags = %PD_RETURNDC OR %PD_RETURNDEFAULT
    Dud=PrinterDialog(hWnd,flags,hPrnDC,0,0,0,0,0)
    LastPrint=hPrnDC
    ELSE
    hPrnDC=LastPrint
    Dud=1
    END IF
    IF Dud THEN
    Dud=16*5
    hFont=FontMaker(Dud, Dud)
    hOrigFont = SelectObject (hPrnDC, hFont)
    GetTextExtentPoint32 hPrnDC, NewContents, 11, lpSize
    IF StartDoc(hPrnDC, di) > 0 THEN
    IF StartPage(hPrnDC) > 0 THEN
    hOrigFont = SelectObject(hPrnDC, hFont)
    TextOut hPrnDC, 20, 100, NewContents, LEN(NewContents)
    IF EndPage(hPrnDC) > 0 THEN
    EndDoc hPrnDC
    FUNCTION=1
    ELSE
    FUNCTION=-3
    END IF
    ELSE
    FUNCTION=-2
    END IF
    ELSE
    FUNCTION=-1
    END IF
    'DeleteObject SelectObject(hPrnDC, hOrigFont)
    'DeleteDC hPrnDC
    ELSE
    FUNCTION=0
    END IF
    END FUNCTION

    FUNCTION FontMaker(fh&, fw&) AS LONG
    DIM Font AS logfont
    Font.lffacename="TIMES NEW ROMAN"
    Font.lfheight=fh&
    Font.lfwidth=fw&
    Font.lfitalic=0
    Font.lfunderline=0
    Font.lfstrikeout=0
    Font.lfweight=500
    FUNCTION=createfontindirect(Font)
    END FUNCTION
    Thanks again! Danny.

    ------------------


    [This message has been edited by Danny Faris (edited October 12, 2000).]

  • #2
    Danny,
    First the good news! You are not at fault for line wrap not working on your printer.
    Now the bad news. Windows doesn't know what you are talking about when you ask for
    $CRLF. Windows (or at least the Windows GDI) treats every device as a randomly accessible
    surface. You will have to "paint" the text on to your printer DC, just as you do on the
    monitor (display screen) DC. You have to adjust the lines of text by coding. You are
    almost there. Stick with it.

    Regards,

    ------------------
    [email protected]
    :) IRC :)

    Comment


    • #3
      Danny,

      Actually it's the TextOut line that doesn't recognize $CRLF.
      You might want to investigate using DrawText instead.

      Your sample code is missing a double quote just before the first $CRLF, but that's not the real problem.

      I'm not sure about NT, but I think it should work.

      Peter.


      ------------------
      [email protected]

      Comment


      • #4
        Danny another possibility might be to use an array for your text,
        and print it by item rather than appending a $CRLF and the rest
        of the text.

        you could then copy each line into an asciiz string before
        printing it.

        ------------------
        Client Writeup for the CPA

        buffs.proboards2.com

        Links Page

        Comment


        • #5
          TextOut is not alone function
          The DrawText function draws formatted text in the specified rectangle. It formats the text according to the specified method (expanding tabs, justifying characters, breaking lines, and so forth).
          To specify additional formatting options, use the DrawTextEx function


          ------------------
          E-MAIL: [email protected]

          Comment


          • #6
            Thank you so much for your responses. This printing thing has me
            really puzzled, and your help is so greatly appreciated.
            \
            Ian: "You will have to "paint" the text on to your printer DC, just as you
            do on the monitor (display screen) DC. You have to adjust the
            lines of text by coding."
            Sounds tricky. How would I do that?

            Peter: "Actually it's the TextOut line that doesn't recognize $CRLF.
            You might want to investigate using DrawText instead."
            I've tried to get DrawText to act differently than TextOut, but it
            doesn't seem to want to recognize CRLF's either.
            Perhaps I am calling it incorrectly?

            Fred: "another possibility might be to use an array for your text,
            and print it by item rather than appending a $CRLF and the rest
            of the text.
            you could then copy each line into an asciiz string before
            printing it."
            Good idea. For some reason though, multiple calls to TextOut seem to be
            ignored.

            Semen: "The DrawText function draws formatted text in the specified
            rectangle. It formats the text according to the specified method
            (expanding tabs, justifying characters, breaking lines, and so
            forth).
            To specify additional formatting options, use the DrawTextEx
            function."
            I've tried, but all I can get this one to do is output a blank
            page. It doesn't seem to accept any text at all.

            Like I said above, I do so appreciate all your help and suggestions. I think
            I'm missing something pretty obvious, but I just can't seem to
            figure out what that might be. Would any of you happen to have any
            suggestions?
            Thanks again! Danny.

            ------------------

            Comment


            • #7
              Danny,
              This might set you off in the right direction. You should do some
              research on printing from this BBS. Better yet, get the POFFS database
              of the PB forums (address on the 3rd party forum) and look through that.
              You have to account for things like "non-square" "pixels".

              It is quite likely that the entire first line won't fit on your page.
              If you want to do standard text output, then try out Lance Edmonds
              DLLPrint program.
              Code:
              #COMPILE EXE
              #INCLUDE "win32api.inc"
              %NOFILEDLG=1
              #INCLUDE "COMDLG32.INC"
              DECLARE FUNCTION FontMaker (fh&, fw&) AS LONG
              GLOBAL LastPrint AS LONG, NewContents AS ASCIIZ*35000
              
              FUNCTION PBMAIN
                STATIC noLines AS LONG
                noLines = 2
                DIM PrintData(1:noLines) AS STATIC STRING
                
                PrintData(1) = "This is a test print to see if the printer will wrap text when it needs to."
                PrintData(2) = "What's more, it doesn't seem to recognize $CRLF's, either."
                CALL PrintFile(PrintData(),noLines)
              END FUNCTION
              
              FUNCTION PrintFile(PrintData() AS STRING, noLines AS LONG) AS LONG
                LOCAL hPrnDC AS LONG, hOrigFont AS LONG, hdc AS LONG, flags AS LONG,_
                      hFont AS LONG, di AS DOCINFO, lpSize AS SIZEL, Dud AS LONG, hWnd&
                LOCAL tm AS textMetric, txtSpacing AS LONG, cxPos AS LONG, cyPos AS LONG, i AS LONG
                
                Dud=0
                IF LastPrint=0 THEN
                  flags = %PD_RETURNDC OR %PD_RETURNDEFAULT
                  Dud=PrinterDialog(hWnd,flags,hPrnDC,0,0,0,0,0)
                  LastPrint=hPrnDC
                ELSE
                  hPrnDC=LastPrint
                  Dud=1
                END IF
                IF Dud THEN
                  Dud=16*5
                  hFont=FontMaker(Dud, Dud)
                  hOrigFont = SelectObject (hPrnDC, hFont)
                  CALL GetTextMetrics (hPrnDC, tm)        'Get font parameters
                  txtSpacing = tm.tmHeight + tm.tmExternalLeading
                  GetTextExtentPoint32 hPrnDC, NewContents, 11, lpSize
                  cxPos = 20
                  cyPos = 100
                  IF StartDoc(hPrnDC, di) > 0 THEN
                    IF StartPage(hPrnDC) > 0 THEN
                      hOrigFont = SelectObject(hPrnDC, hFont)
                      FOR i = 1 TO noLines
                        TextOut hPrnDC, cxPos, cyPos, BYCOPY PrintData(i), LEN(PrintData(i))
                        cyPos = cyPos + txtSpacing
                      NEXT i
                      IF EndPage(hPrnDC) > 0 THEN
                        EndDoc hPrnDC
                        FUNCTION=1
                      ELSE
                        FUNCTION=-3
                      END IF
                    ELSE
                      FUNCTION=-2
                    END IF
                  ELSE
                    FUNCTION=-1
                  END IF
                  DeleteObject SelectObject(hPrnDC, hOrigFont)
                  DeleteDC hPrnDC
                ELSE
                  FUNCTION=0
                END IF
              END FUNCTION
              
              FUNCTION FontMaker(fh&, fw&) AS LONG
                DIM Font AS logfont
                Font.lffacename="TIMES NEW ROMAN"
                Font.lfheight=fh&
                Font.lfwidth=fw&
                Font.lfitalic=0
                Font.lfunderline=0
                Font.lfstrikeout=0
                Font.lfweight=500
                FUNCTION=createfontindirect(Font)
              END FUNCTION
              ----------
              regards,

              ------------------
              [email protected]
              :) IRC :)

              Comment


              • #8
                About DrawText. I reconstructed a little Lance sample with Enum Fonts.
                Works fine, at least on my PC.
                Code:
                    #Compile Exe
                    #Register None
                    #Dim All
                    #Include "WIN32API.INC"
                
                    Function PbMain
                       Dim hDC As Long, tm As TEXTMETRIC, di As docinfo
                       Dim szText As Asciiz * 1024, PrinterName As Asciiz * 255
                       Dim i As Long, rc As RECT, rcc As RECT
                       
                       GetProfileString "WINDOWS", "DEVICE", ",,,", PrinterName, SizeOf(PrinterName)
                       PrinterName = Left$(PrinterName, Instr(PrinterName, ",") - 1)
                       If PrinterName = "" Then Exit Function
                
                       hDC = CreateDC(ByVal %Null, PrinterName, ByVal %Null, ByVal %Null)
                       di.cbsize = SizeOf(di)
                       szText = "DrawText": di.lpszDocName = VarPtr(szText)
                       StartDoc hDC, di: StartPage hDC
                
                       rcc.nBottom = 100: rcc.nLeft = 100
                       For i = 1 To 3
                          szText = "Printer name is " + PrinterName + $CRLF + _
                                   "This is a test for DrawText" + $CRLF + _
                                   "Cross #" + Format$(i) + $CRLF + _
                                   "_____________________________________"
                          DrawText hDC, szText, -1, rc, %DT_CALCRECT
                          rcc.nTop = rcc.nBottom
                          rcc.nBottom = rcc.nTop + rc.nBottom
                          rcc.nRight = rcc.nLeft + rc.nRight
                          DrawText hDC, szText, -1, rcc, 0
                       Next
                       EndPage hDC: EndDoc hDC: DeleteDC hDC
                    End Function
                PS. It's not a layout. In real program it's necessary to select a font, to control end of page and so on.

                [This message has been edited by Semen Matusovski (edited October 12, 2000).]

                Comment


                • #9
                  Hi Ian and Semen:
                  Thank you both for your quick and helpful replies. I'm totally
                  baffled when it comes to printing, there's so many things that
                  can, and DO, go wrong!

                  Ian: Your modification now prints a whole page! I have the text
                  I'm trying to print in a multiline edit box, so I just get each
                  line and send it to the textout function one by one. Like I said,
                  though, it works
                  great until the bottom line. Then it prints half of the next line
                  instead of going to a new page and won't continue. I need to tell
                  it to go to a new page by doing a EndPage then a StartPage, right?
                  But how do I know when the page is full? I could work out that at
                  10 point it fits X number of lines, at 15 point it fits Y
                  number and so on. But different fonts have slightly different sizes of
                  print, I'd have to perform hundreds of calculations to get it
                  just right. Is there, by any chance, an easier way?

                  Semen: Thank you for your responce. It, too, prints more than one
                  line (There's so much more to look at now!), but it won't go to a
                  new page when it needs to, either. I actually looked into Lance's
                  DLLPrint, but I need to be able to print different sizes of text,
                  different weights, Etc.

                  Any ideas how I can query Windows or the
                  printer or something.. Anything!... and find out when to go to a new
                  page? Thank you ever so much! Danny.

                  ------------------

                  Comment


                  • #10
                    check out this item on finding out print capabilities.
                    http://www.powerbasic.com/support/pb...ad.php?t=17502
                    you need to use gettextextentpoint32 to determine whether or not
                    a given line will fit in your left-to-right print margins.
                    you need to use gettextmetrics to determine print height.
                    keep track of where you are on the page and start a new page
                    before you run out of room.
                    re-run gettextmetrics whenever you change fonts.
                    i strongly recommend that you get a good win32 bible. purchase petzold,
                    or richter&newcomer. i own both. they are well worth the investment.
                    petzold is easier but r&n goes into printing in more depth.

                    regards,

                    ------------------
                    [email protected]
                    :) IRC :)

                    Comment


                    • #11
                      Ian:
                      Yes! That did it! The page you referred me to had a fancy little API call to get the phisical length of the page, which I used to check cyPos against. When it came too close, I reset cyPos, ended the current page, started the next one and reset the font. Incase you're interested, here's what I wrote. (GetLine is a function that gets a specified line from an edit box.)
                      Local Ended as Long, TempL as Long
                      cyPos = 100
                      IF StartDoc(hPrnDC, di) > 0 THEN
                      IF StartPage(hPrnDC) > 0 THEN
                      hOrigFont = SelectObject(hPrnDC, hFont)
                      CONTROL SEND hWnd&, 101, %EM_GETLINECOUNT, 0, 0 TO Ended
                      Dud=GetDeviceCaps(hPrnDC, %PHYSICALHEIGHT)
                      FOR Ended=0 TO Ended-1
                      NewContents=GetLine(Ended)
                      TextOut hPrnDC, cxPos, cyPos, BYCOPY NewContents, LEN(NewContents)
                      cyPos = cyPos + txtSpacing
                      IF cyPos>Dud-300 THEN
                      cyPos=100
                      Templ=EndPage(hPrnDC): Templ=StartPage(hPrnDC)
                      hOrigFont = SelectObject(hPrnDC, hFont)
                      END IF
                      NEXT
                      IF EndPage(hPrnDC) > 0 THEN
                      EndDoc hPrnDC
                      It's so incredibly nice to have so many pages sitting on the printer tray. Just yesterday, there was but one lonely page, with only one line on it... Sort of! I'll never be able to thank you enough, This is simply wonderful! Have a GREAT day!
                      Take care. Danny.

                      ------------------

                      Comment


                      • #12
                        Originally posted by Danny Faris:
                        I actually looked into Lance's DLLPrint, but I need to be able to print different sizes of text, different weights, Etc.
                        JFYI, DLLPrint does all of that and more...

                        Regards,
                        Lance

                        Please note I have two new URL's for my printing products: www.dllprint.com www.dosprint.com

                        Lance
                        mailto:[email protected]

                        Comment

                        Working...
                        X