Go Back  Xtreme Visual Basic Talk > Legacy Visual Basic (VB 4/5/6) > Interface and Graphics > GDI+ Printing Lines


Reply
 
Thread Tools Display Modes
  #1  
Old 08-08-2012, 10:29 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,665
Default GDI+ Printing Lines


I'm trying to print a fixed number of lines per printed page.

The first page however, I want to have a lesser number of lines, starting
further down the page than the subsequent pages
(space at top to be equal to number of lines not printed X spacing between the lines).

I would think this should be an easy thing to do, but I am coming up totally blank.

I guess this is more a coding algorithm problem than a GDI+ problem.

This is my code to print the same number of lines on each page
(3 printed pages with 8 lines each and the last page with 1 line).

Code:
Private Sub Command1_Click()

    Dim hdcPrint As Long
    hdcPrint = CreateDC(Printer.DriverName, Printer.DeviceName, 0, 0)

    Dim myDocInfo As DOCINFO
    myDocInfo.cbSize = Len(myDocInfo)
    myDocInfo.lpszDocName = "GdiplusPrint"
    
    Call StartDoc(hdcPrint, myDocInfo)
    Call StartPage(hdcPrint)

    Dim stat As Long
    
    Dim graphics As Long
    stat = GdipCreateFromHDC(hdcPrint, graphics)
    
    Dim pen As Long
    stat = GdipCreatePen1(&HFF000000, 1, UnitPixel, pen)

    Dim i As Long
    Dim offsetY As Single
    Dim lineSpacing As Single
    Dim linesToPrint As Long
    Dim linesPerPage As Long
    Dim linesFirstPage As Long
    
    offsetY = 10
    lineSpacing = 10
    linesPerPage = 8
    linesToPrint = 25
    
    linesFirstPage = 7

    For i = 0 To (linesToPrint - 1)
        
        If (i Mod linesPerPage = 0) And i <> 0 Then
    
            Call EndPage(hdcPrint)
            
            offsetY = offsetY - (linesPerPage * lineSpacing)
    
        End If

        stat = GdipDrawLine(graphics, pen, _
                            0, offsetY + (i * lineSpacing), _
                            500, offsetY + (i * lineSpacing))

    Next i

    Call EndPage(hdcPrint)
    Call EndDoc(hdcPrint)
    
    Call DeleteDC(hdcPrint)
    
    stat = GdipDeletePen(pen)
    stat = GdipDeleteGraphics(graphics)
    
End Sub
Reply With Quote
  #2  
Old 08-08-2012, 11:39 AM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,714
Default

I'm not really clear on the question, but I'll assume the code you posted works, and what you want is to modify it in some way to meet your new requirement.

It sounds like you want to "print" empty lines on the first page, and I believe you're calculating offset based on the line number, so I think you could just add an offset of how many blank lines you want and it would take care of itself.

If ((i-linesFirstPage) Mod linesPerPage = 0) Then

I'll have to test that to see if that works. It may have an "off by 1" problem and you have to carry the adjustment through to your other calculations.

My initial thought was to use the number of blank lines you wanted on the first page and you would add that to your loop index to create a virtual YLinePosition.
You would use the YLinePosition for all your placement calculations.

Again, untested:
Code:
    For i = 0 To (linesToPrint - 1)
        YLinePosition = i + NumberOfBlankLinesFirstPage
        If (YLinePosition Mod linesPerPage = 0) Then
            Call EndPage(hdcPrint)
            offsetY = offsetY - (linesPerPage * lineSpacing)
        End If
        stat = GdipDrawLine(graphics, pen, _
                            0, offsetY + (YLinePosition * lineSpacing), _
                            500, offsetY + (YLinePosition * lineSpacing))
    Next i
I think that will work, but to be honest, I don't think I would have done it that way,
Rather than have to calculate an ever decreasing offsetY to compensate for the page you're on, I would used the mod position of the line so it's coordinates are local to the page
Code:
        ModYLinePosition = YLinePosition Mod linesPerPage 
        stat = GdipDrawLine(graphics, pen, _
                            0, ModYLinePosition * lineSpacing, _
                            500, ModYLinePosition * lineSpacing)
but, perhaps offseting the "coordinate system" by page suits the way you are drawing other objects.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #3  
Old 08-08-2012, 02:27 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,665
Default

You understood the question correctly, and the code you posted (both methods) produces printed output exactly as I wanted.

Thank you!!

I want to use your second method (the one you said was best) with the PrintClip function you wrote for me a while back, and don't see why this won't work.

I had come up with some code (finally) that worked, trouble is, it is so cumbersome that in a few weeks time I would never remember what I was doing.
I have this (unwanted) ability to produce code that is overly complicated.

This is what I came up with:

Code:
    Dim modCheck As Long
    modCheck = linesFirstPage
   
    Dim firstPageAdjustment As Long
    'firstPageAdjustment = linesPerPage - linesFirstPage
    
    Dim pageNum As Long

    For i = 0 To (linesToPrint - 1)

        If (i Mod modCheck = 0) And i <> 0 Then
    
            Call EndPage(hdcPrint)
            offsetY = offsetY - (linesPerPage * lineSpacing) + (firstPageAdjustment * lineSpacing)
            pageNum = pageNum + 1
            
            Debug.Print i & "," & modCheck & "," & pageNum & "," & offsetY
    
        End If

        If i >= 0 And i < linesFirstPage Then
            modCheck = linesFirstPage
            firstPageAdjustment = linesPerPage - linesFirstPage
        Else
            modCheck = pageNum * linesPerPage + linesFirstPage
            firstPageAdjustment = 0
        End If

        stat = GdipDrawLine(graphics, pen, _
                            0, offsetY + ((firstPageAdjustment + i) * lineSpacing), _
                            500, offsetY + ((firstPageAdjustment + i) * lineSpacing))
        
        Debug.Print offsetY + ((firstPageAdjustment + i) * lineSpacing)
        
    Next i
Reply With Quote
  #4  
Old 08-09-2012, 07:49 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,665
Default

Your code works perfectly in the context of my main program where I use the PrintClip function.

A problem with Windows7 Print Dialog;
It reports 1 page printed when in fact 4 pages were sent to the printer.
The correct document name is displayed (GdiplusPrint).

myDocInfo.lpszDocName = "GdiplusPrint" from in Post #1 sets this.

How then to display the correct number of pages if this is not tracked automatically?
Attached Images
File Type: png PrintDialog.png (19.3 KB, 2 views)
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->