VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsPrint"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
Attribute VB_Ext_KEY = "Member0" ,"clsCollection"
Option Explicit

Public Tables As clsTables
Public Labels As clsLabels
Public LabelsEx As clsLabelsEx
Public Lines As clsLines
Public Images As clsImages
Public Rectangles As clsRectangles
Public Points As clsPoints
Public PageBreaks As clsPageBreaks
Public Repeats As clsRepeats

Public Enum PrintRangeConstants
    AllPages& = 0
    OddPages& = 1
    EvenPages& = 2
End Enum

Public Enum PageOrientationConstants
    OPortrait& = 1
    OLandscape& = 2
End Enum

Public Enum PageSizeConstants
    sizeA3& = vbPRPSA3
    sizeA4& = vbPRPSA4
    sizeA5& = vbPRPSA5
    sizeB4& = vbPRPSB4
    sizeB5& = vbPRPSB5
    sizeLetter& = vbPRPSLetter
    sizeCustom& = vbPRPSUser
End Enum

Public Enum TextAlignConstants
    DT_LEFT& = &H0
    DT_CENTER& = &H1
    DT_RIGHT& = &H2
    DT_EXPANDTABS& = &H40
    DT_NOCLIP& = &H100
    DT_NOPREFIX& = &H800
    DT_SINGLELINE& = &H20
    DT_TOP& = &H0 Or &H20
    DT_VCENTER& = &H4 Or &H20
    DT_BOTTOM& = &H8 Or &H20
End Enum

Private Const DT_WORDBREAK& = &H10

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Const LOGPIXELSX& = 88
Private Const LOGPIXELSY& = 90

Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function DrawAnimatedRects Lib "user32" (ByVal hWnd As Long, ByVal idAni As Long, lprcFrom As RECT, lprcTo As RECT) As Long
Private Declare Function EnableWindow Lib "user32" (ByVal hWnd As Long, ByVal fEnable As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long

Public Collate As Boolean
Private pOrientation As PageOrientationConstants
Private pPageSize As PageSizeConstants
Private pCopies As Integer
Private pQuality As Integer
Private pFromPage As Integer
Private pToPage As Integer
Private pRange As PrintRangeConstants

Private pHeight As Single, pWidth As Single
Private pPrintableWidth As Single, pPrintableHeight As Single
Private pLeftMargin As Single, pTopMargin As Single
Private pRightMargin As Single, pBottomMargin As Single
Private sngMaxMargin As Single

Private blnKillDoc As Boolean, blnViewPaginateStatus As Boolean

Private pOwner_hWnd As Long
Private intCurrentPage As Integer, sngCurrentPos As Single


Private Sub Class_Initialize()
On Error GoTo err
    With Printer
        .TrackDefault = False
        .ScaleMode = vbMillimeters
        pOrientation = .Orientation
        pPageSize = .PaperSize
        pCopies = .Copies
        pQuality = .PrintQuality
    End With

    PageChanged pPageSize, pOrientation

    Set Tables = New clsTables
    Set Labels = New clsLabels
    Set LabelsEx = New clsLabelsEx
    Set Lines = New clsLines
    Set Images = New clsImages
    Set Rectangles = New clsRectangles
    Set Points = New clsPoints
    Set PageBreaks = New clsPageBreaks
    Set Repeats = New clsRepeats
    Set CQueue = New clsQueue
err:
    
    If err.Number = 482 Then
        MsgBox "Aucune Imprimante n'est installé sur le PC", vbExclamation + vbOKOnly
        Exit Sub
    End If
End Sub

Private Sub Class_Terminate()
    Set Tables = Nothing
    Set Labels = Nothing
    Set LabelsEx = Nothing
    Set Lines = Nothing
    Set Images = Nothing
    Set Rectangles = Nothing
    Set Points = Nothing
    Set PageBreaks = Nothing
    Set Repeats = Nothing
    Set CQueue = Nothing

    Erase colPage()
End Sub

Public Property Let Copies(ByVal c As Integer)
    If c < 1 Or c > 999 Then
        err.Raise 9, , "Valid range is from 1 to 999"
    Else
        pCopies = c
    End If
End Property

Public Property Get Copies() As Integer
    Copies = pCopies
End Property

Public Property Let FromPage(ByVal f As Integer)
    If f < 0 Or f > 999 Then
        err.Raise 9, , "Valid range is from 0 to 999"
    Else
        pFromPage = f
    End If
End Property

Public Property Get FromPage() As Integer
    FromPage = pFromPage
End Property

Public Property Let ToPage(ByVal t As Integer)
    If t < 0 Or t > 999 Then
        err.Raise 9, , "Valid range is from 0 to 999"
    Else
        pToPage = t
    End If
End Property

Public Property Get ToPage() As Integer
    ToPage = pToPage
End Property

Public Property Let Range(ByVal r As PrintRangeConstants)
    If r < 0 Or r > 2 Then
        err.Raise 9, , "Valid range is from 0 to 2"
    Else
        pRange = r
    End If
End Property

Public Property Get Range() As PrintRangeConstants
    Range = pRange
End Property

Public Property Get Orientation() As PageOrientationConstants
    Orientation = pOrientation
End Property

Public Property Let Orientation(ByVal o As PageOrientationConstants)
    If o > 0 And o < 3 Then
        If PageChanged(pPageSize, o) Then
            pOrientation = o
        End If
    Else
        err.Raise 9, , "Valid value is 1 or 2"
    End If
End Property

Public Property Get PageSize() As PageSizeConstants
    PageSize = pPageSize
End Property

Public Property Let PageSize(ByVal ps As PageSizeConstants)
    If PageChanged(ps, pOrientation) Then
        pPageSize = ps
    End If
End Property

Private Function PageChanged(ps As PageSizeConstants, po As PageOrientationConstants) As Boolean
Dim RetVal As Boolean
Const MarginFactor As Single = 0.4

    RetVal = True
    On Error GoTo hErr:
    With Printer
        .Orientation = po
        .PaperSize = ps
        pHeight = .ScaleY(.Height, vbTwips, vbMillimeters)
        pWidth = .ScaleX(.Width, vbTwips, vbMillimeters)
        pPrintableHeight = .ScaleHeight
        pPrintableWidth = .ScaleWidth
    End With
    If pWidth > pHeight Then
        sngMaxMargin = pHeight * MarginFactor
    Else
        sngMaxMargin = pWidth * MarginFactor
    End If
    If pLeftMargin > sngMaxMargin Then pLeftMargin = sngMaxMargin
    If pTopMargin > sngMaxMargin Then pTopMargin = sngMaxMargin
    If pRightMargin > sngMaxMargin Then pRightMargin = sngMaxMargin
    If pBottomMargin > sngMaxMargin Then pBottomMargin = sngMaxMargin

    PageChanged = RetVal
    Exit Function

hErr:
    RetVal = False
    Resume Next
End Function

Public Property Let LeftMargin(ByVal m As Single)
    If m < 0 Or m > sngMaxMargin Then
        err.Raise 9, , "Valid range is from 0 to " & sngMaxMargin
    Else
        pLeftMargin = m
    End If
End Property

Public Property Get LeftMargin() As Single
    LeftMargin = pLeftMargin
End Property

Public Property Let RightMargin(ByVal m As Single)
    If m < 0 Or m > sngMaxMargin Then
        err.Raise 9, , "Valid range is from 0 to " & sngMaxMargin
    Else
        pRightMargin = m
    End If
End Property

Public Property Get RightMargin() As Single
    RightMargin = pRightMargin
End Property

Public Property Let TopMargin(ByVal m As Single)
    If m < 0 Or m > sngMaxMargin Then
        err.Raise 9, , "Valid range is from 0 to " & sngMaxMargin
    Else
        pTopMargin = m
    End If
End Property

Public Property Get TopMargin() As Single
    TopMargin = pTopMargin
End Property

Public Property Let BottomMargin(ByVal m As Single)
    If m < 0 Or m > sngMaxMargin Then
        err.Raise 9, , "Valid range is from 0 to " & sngMaxMargin
    Else
        pBottomMargin = m
    End If
End Property

Public Property Get BottomMargin() As Single
    BottomMargin = pBottomMargin
End Property

Public Property Get MaxMargin() As Single
    MaxMargin = sngMaxMargin
End Property

Public Property Get Width() As Single
    Width = pWidth
End Property

Public Property Get Height() As Single
    Height = pHeight
End Property

Public Property Get PrintableWidth() As Single
    PrintableWidth = pPrintableWidth
End Property

Public Property Get PrintableHeight() As Single
    PrintableHeight = pPrintableHeight
End Property

Public Property Get Owner_hWnd() As Long
    Owner_hWnd = pOwner_hWnd
End Property

Public Sub KillDoc()
    blnKillDoc = True
End Sub

Public Sub PreviewDoc(ByVal Owner_hWnd As Long, Optional ByVal ViewPaginateStatus As Boolean = False)
    pOwner_hWnd = Owner_hWnd
    blnViewPaginateStatus = ViewPaginateStatus

    InitLineWidthCoefficient (frmPreview.picPage.hDC)

    Paginate

    frmPreview.Show vbModal

    Call SetForegroundWindow(pOwner_hWnd)
End Sub

Public Sub PrintDoc(ByVal Owner_hWnd As Long, Optional ShowPrinterWindow As Boolean = True)
Const conSeparator As String = " / "
Dim i As Integer, j As Integer, fPrint As Boolean
Dim hw As Long, f As RECT, t As RECT
Dim ErrNum As Long
Dim intPages As Integer, intStart As Integer, intEnd As Integer, intStep As Integer

    pOwner_hWnd = Owner_hWnd
    blnViewPaginateStatus = False
    Call EnableWindow(pOwner_hWnd, 0)

    On Error GoTo ErrH
    If ShowPrinterWindow Then
        With frmPrint
            .chkCollate.Value = Abs(CInt(Collate))
            .udCopies.Value = pCopies
            .cboRange.ComboItems(pRange + 1).Selected = True
            If pFromPage = 0 Or pToPage = 0 Then
                .optAll.Value = True
                .udFrom.Value = 1
                .udTo.Value = 1
            Else
                .optPages.Value = True
                .udFrom.Value = pFromPage
                .udTo.Value = pToPage
            End If
            hw = .hWnd
            Call GetWindowRect(hw, t)
            Call OffsetRect(t, (Screen.Width / Screen.TwipsPerPixelX - (t.Right - t.Left)) \ 2, _
                                            (Screen.Height / Screen.TwipsPerPixelY - (t.Bottom - t.Top)) \ 2)
            Call DrawAnimatedRects(hw, 3, f, t)
            .Show vbModal
            fPrint = .isPrint
        End With
        Unload frmPrint
    Else
        fPrint = True
    End If

    If fPrint Then
        With Printer
            .ScaleMode = vbMillimeters
            PageChanged pPageSize, pOrientation
            .Copies = IIf(Collate, 1, pCopies)
            .FontTransparent = False
            InitLineWidthCoefficient (.hDC)
        End With
        Paginate
        intPages = UBound(colPage)

        If pFromPage = 0 And pToPage = 0 Then
            intStart = 1
            intEnd = intPages
        Else
            intStart = pFromPage
            intEnd = pToPage
            If intEnd > intPages Then intEnd = intPages
            If intStart > intEnd Then
                CInteraction.ShowMsgBox , "Invalid print range.", , , , , imgExclamationEx, , 1
                GoTo Finally:
            End If
        End If

        For j = 1 To IIf(Collate, pCopies, 1)
            blnKillDoc = False
            frmPrinterStatus.lblPrinter.Caption = Printer.DeviceName
            frmPrinterStatus.Show

            Select Case pRange
                Case OddPages
                    i = intStart
                    If i Mod 2 = 0 Then
                        i = i + 1
                    End If
                    intStep = 2
                Case EvenPages
                    i = intStart
                    If i Mod 2 > 0 Then
                        i = i + 1
                    End If
                    intStep = 2
                Case Else
                    i = intStart
                    intStep = 1
            End Select

            Do Until blnKillDoc Or i > intEnd
                frmPrinterStatus.lblStatus(0).Caption = CStr(i & conSeparator & intPages)
                DoEvents
                SendPage Printer, i
                i = i + intStep
                If i < intEnd Then
                    Printer.NewPage
                End If
            Loop

            If blnKillDoc Then
                Printer.KillDoc
            Else
                Printer.EndDoc
            End If
        Next j
    End If
    GoTo Finally:

ErrH:
    ErrNum = err.Number
    If ErrNum = 482 Or ErrNum = 484 Then
        CInteraction.ShowMsgBox , "Printer error.", , , , , imgCriticalEx, , 1
    Else
        MsgBox ErrNum & "  " & err.Description, vbCritical + vbOKOnly, "Printer error"
    End If
    Printer.KillDoc

Finally:
    Unload frmPrinterStatus
    Call EnableWindow(pOwner_hWnd, 1)
    Call SetForegroundWindow(pOwner_hWnd)
End Sub

Private Sub Paginate()
Dim CPointA As clsPointAttributes
Dim CLineA As clsLineAttributes
Dim CLabelA As clsLabelAttributes
Dim CRectangleA As clsRectangleAttributes
Dim CLabelExA As clsLabelExAttributes
Dim CImageA As clsImageAttributes
Dim CTableA As clsTableAttributes

Dim CnPointA As clsPointAttributes
Dim CnLineA As clsLineAttributes
Dim CnLabelA As clsLabelAttributes
Dim CnRectangleA As clsRectangleAttributes
Dim CnLabelExA As clsLabelExAttributes
Dim CnImageA As clsImageAttributes
Dim CnTableA As clsTableAttributes

Dim strTmp As String, sngPageRectBottom As Single
Dim strItem As String, intObj As Integer, intObjIndex As Integer

Dim x1_ As Single, y1_ As Single, x2_ As Single, y2_ As Single
Dim i As Long, j As Long, k As Long, Align As Long, intBorderWidth As Integer

Dim availHeight As Single, sngAvailHeight As Single
Dim TextArray() As String, TextArrayN() As String, sngTableTop As Single, FirstRowIsTitle As Boolean
Dim sngTitleHeight As Single, sngBodyHeight As Single
Dim lngTotalColumns As Long, lngColumnsCount As Long
Dim Row_ As Long, Col_ As Long
Dim lngRowsOnPage As Long, lngTotalRows As Long
Dim lngStartRow As Long, lngEndRow As Long, lngCurrentRow As Long
Dim ly As Long, uy As Long

Dim PointArray() As Single

    If CQueue.Count > 0 Then
        availHeight = pPrintableHeight - pTopMargin - pBottomMargin
        sngPageRectBottom = pTopMargin + availHeight

        sngCurrentPos = pTopMargin + 1
        intCurrentPage = 0
        If blnViewPaginateStatus Then frmPaginateStatus.Show
        NewPage

        For i = 1 To CQueue.Count
            strItem = CQueue(i)
            intObj = Val(Left(strItem, InStr(1, strItem, "/") - 1))
            intObjIndex = Val(Mid(strItem, InStr(1, strItem, "/") + 1))
            Select Case intObj
                Case objTypePoint
                    Set CPointA = Points(intObjIndex)
                    With CPointA
                        PointArray() = .PointArray

                        If .PositionIsAbsolute Then
                            y1_ = pTopMargin
                        Else
                            y1_ = PointArray(2, 1)
                            If sngPageRectBottom < y1_ + sngCurrentPos Then
                                y1_ = sngCurrentPos - sngPageRectBottom + pTopMargin
                                If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                NewPage
                            Else
                                y1_ = sngCurrentPos
                            End If
                        End If

                        For j = 1 To UBound(PointArray, 2)
                            PointArray(1, j) = PointArray(1, j) + pLeftMargin
                            PointArray(2, j) = PointArray(2, j) + y1_
                        Next j

                        Set CnPointA = New clsPointAttributes
                        CnPointA.Color = .Color
                        CnPointA.Size = Abs(Int(-(.Size / 10) * sngLineWidthCoefficient))
                        CnPointA.PointArray = PointArray

                        sngCurrentPos = .PointArray(2, 1) + y1_
                    End With

                    colPage(intCurrentPage).Add CnPointA
                    Set CnPointA = Nothing
                Case objTypeLine
                    Set CLineA = Lines(intObjIndex)
                    With CLineA
                        x1_ = .X1 + pLeftMargin
                        y1_ = .Y1
                        x2_ = .X2 + pLeftMargin
                        y2_ = .Y2
                        If .PositionIsAbsolute Then
                            y1_ = y1_ + pTopMargin
                            y2_ = y2_ + pTopMargin
                        Else
                            If y1_ < y2_ Then
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y1_ = y1_ + sngCurrentPos - sngPageRectBottom
                                    y2_ = y1_ + (.Y2 - .Y1)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y1_ = 0
                                    y2_ = .Y2 - .Y1
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            Else
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y2_ = y2_ + sngCurrentPos - sngPageRectBottom
                                    y1_ = y2_ + (.Y1 - .Y2)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y2_ = 0
                                    y1_ = .Y1 - .Y2
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            End If

                            y1_ = y1_ + sngCurrentPos
                            y2_ = y2_ + sngCurrentPos
                        End If

                        Set CnLineA = New clsLineAttributes
                        CnLineA.Color = .Color
                        CnLineA.Size = Abs(Int(-(.Size / 10) * sngLineWidthCoefficient))
                        CnLineA.X1 = x1_
                        CnLineA.Y1 = y1_
                        CnLineA.X2 = x2_
                        CnLineA.Y2 = y2_
                    End With

                    colPage(intCurrentPage).Add CnLineA
                    Set CnLineA = Nothing

                    If y1_ > y2_ Then
                        sngCurrentPos = y1_
                    Else
                        sngCurrentPos = y2_
                    End If
                Case objTypeRectangle
                    Set CRectangleA = Rectangles(intObjIndex)
                    With CRectangleA
                        x1_ = .Left + pLeftMargin
                        y1_ = .Top
                        x2_ = .Right + pLeftMargin
                        y2_ = .Bottom
                        If .PositionIsAbsolute Then
                            y1_ = y1_ + pTopMargin
                            y2_ = y2_ + pTopMargin
                        Else
                            If y1_ < y2_ Then
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y1_ = y1_ + sngCurrentPos - sngPageRectBottom
                                    y2_ = y1_ + (.Bottom - .Top)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y1_ = 0
                                    y2_ = .Bottom - .Top
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            Else
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y2_ = y2_ + sngCurrentPos - sngPageRectBottom
                                    y1_ = y2_ + (.Top - .Bottom)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y2_ = 0
                                    y1_ = .Top - .Bottom
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            End If

                            y1_ = y1_ + sngCurrentPos
                            y2_ = y2_ + sngCurrentPos
                        End If

                        Set CnRectangleA = New clsRectangleAttributes
                        CnRectangleA.BorderColor = .BorderColor
                        CnRectangleA.BorderWidth = Abs(Int(-(.BorderWidth / 10) * sngLineWidthCoefficient))
                        CnRectangleA.FillColor = .FillColor
                        CnRectangleA.FillStyle = .FillStyle
                        CnRectangleA.Left = x1_
                        CnRectangleA.Top = y1_
                        CnRectangleA.Right = x2_
                        CnRectangleA.Bottom = y2_
                    End With

                    colPage(intCurrentPage).Add CnRectangleA
                    Set CnRectangleA = Nothing

                    If y1_ > y2_ Then
                        sngCurrentPos = y1_
                    Else
                        sngCurrentPos = y2_
                    End If
                Case objTypeLabel
                    Set CLabelA = Labels(intObjIndex)
                    With CLabelA
                        x1_ = .Left + pLeftMargin
                        y1_ = .Top
                        x2_ = .Right + pLeftMargin
                        y2_ = .Bottom

                        If .PositionIsAbsolute Then
                            y1_ = y1_ + pTopMargin
                            y2_ = y2_ + pTopMargin
                        Else
                            If y1_ < y2_ Then
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y1_ = y1_ + sngCurrentPos - sngPageRectBottom
                                    y2_ = y1_ + (.Bottom - .Top)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y1_ = 0
                                    y2_ = .Bottom - .Top
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            Else
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y2_ = y2_ + sngCurrentPos - sngPageRectBottom
                                    y1_ = y2_ + (.Top - .Bottom)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y2_ = 0
                                    y1_ = .Top - .Bottom
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            End If

                            y1_ = y1_ + sngCurrentPos
                            y2_ = y2_ + sngCurrentPos
                        End If

                        Align = .Align
                        If .WordWrap Then Align = Align Or DT_WORDBREAK

                        Set CnLabelA = New clsLabelAttributes
                        CnLabelA.Align = Align
                        CnLabelA.BorderColor = .BorderColor
                        CnLabelA.BorderWidth = Abs(Int(-(.BorderWidth / 10) * sngLineWidthCoefficient))
                        CnLabelA.Caption = .Caption
                        CnLabelA.CellSpacing = .CellSpacing
                        CnLabelA.FillColor = .FillColor
                        CnLabelA.FillStyle = .FillStyle
                        CnLabelA.FontBold = .FontBold
                        CnLabelA.FontItalic = .FontItalic
                        CnLabelA.FontName = .FontName
                        CnLabelA.FontSize = .FontSize
                        CnLabelA.FontStrikethru = .FontStrikethru
                        CnLabelA.FontUnderline = .FontUnderline
                        CnLabelA.ForeColor = .ForeColor
                        CnLabelA.Left = x1_
                        CnLabelA.Top = y1_
                        CnLabelA.Right = x2_
                        CnLabelA.Bottom = y2_
                    End With

                    colPage(intCurrentPage).Add CnLabelA
                    Set CnLabelA = Nothing

                    If y1_ > y2_ Then
                        sngCurrentPos = y1_
                    Else
                        sngCurrentPos = y2_
                    End If
                Case objTypeLabelEx
                    Set CLabelExA = LabelsEx(intObjIndex)
                    With CLabelExA
                        x1_ = .Left + pLeftMargin
                        y1_ = .Top
                        x2_ = .Right + pLeftMargin
                        y2_ = .Bottom

                        If .PositionIsAbsolute Then
                            y1_ = y1_ + pTopMargin
                            y2_ = y2_ + pTopMargin
                        Else
                            If y1_ < y2_ Then
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y1_ = y1_ + sngCurrentPos - sngPageRectBottom
                                    y2_ = y1_ + (.Bottom - .Top)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y1_ = 0
                                    y2_ = .Bottom - .Top
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            Else
                                If sngPageRectBottom < y2_ + sngCurrentPos Then
                                    y2_ = y2_ + sngCurrentPos - sngPageRectBottom
                                    y1_ = y2_ + (.Top - .Bottom)
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                                If sngPageRectBottom < y1_ + sngCurrentPos Then
                                    y2_ = 0
                                    y1_ = .Top - .Bottom
                                    If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                    NewPage
                                End If
                            End If

                            y1_ = y1_ + sngCurrentPos
                            y2_ = y2_ + sngCurrentPos
                        End If

                        Align = .Align
                        If .WordWrap Then Align = Align Or DT_WORDBREAK

                        Set CnLabelExA = New clsLabelExAttributes
                        CnLabelExA.Align = Align
                        CnLabelExA.Angle = .Angle
                        CnLabelExA.BorderColor = .BorderColor
                        CnLabelExA.BorderWidth = Abs(Int(-(.BorderWidth) / 10 * sngLineWidthCoefficient))
                        CnLabelExA.Caption = .Caption
                        CnLabelExA.CellSpacing = .CellSpacing
                        CnLabelExA.CharHeight = .CharHeight * sngLabelExCoefficient
                        CnLabelExA.CharWeight = .CharWeight
                        CnLabelExA.CharWidth = .CharWidth * sngLabelExCoefficient
                        CnLabelExA.FillColor = .FillColor
                        CnLabelExA.FillStyle = .FillStyle
                        CnLabelExA.FontItalic = .FontItalic
                        CnLabelExA.FontName = .FontName
                        CnLabelExA.FontStrikeOut = .FontStrikeOut
                        CnLabelExA.FontUnderline = .FontUnderline
                        CnLabelExA.ForeColor = .ForeColor
                        CnLabelExA.Left = x1_
                        CnLabelExA.Top = y1_
                        CnLabelExA.Right = x2_
                        CnLabelExA.Bottom = y2_
                    End With

                    colPage(intCurrentPage).Add CnLabelExA
                    Set CnLabelExA = Nothing

                    If y1_ > y2_ Then
                        sngCurrentPos = y1_
                    Else
                        sngCurrentPos = y2_
                    End If
                Case objTypeImage
                    Set CImageA = Images(intObjIndex)
                    With CImageA
                        x1_ = .Left + pLeftMargin
                        y1_ = .Top
                        If IsMissing(.Height) Then
                            y2_ = .Image.Height / 100
                        Else
                            y2_ = CSng(.Height)
                        End If
                        If .PositionIsAbsolute Then
                            y1_ = y1_ + pTopMargin
                        Else
                            If sngPageRectBottom < y1_ + sngCurrentPos Then
                                y1_ = y1_ + sngCurrentPos - sngPageRectBottom
                                If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                NewPage
                            End If
                            If sngPageRectBottom < y1_ + y2_ + sngCurrentPos Then
                                y1_ = 0
                                If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                NewPage
                            End If

                            y1_ = y1_ + sngCurrentPos
                        End If

                        Set CnImageA = New clsImageAttributes
                        Set CnImageA.Image = .Image
                        CnImageA.Left = x1_
                        CnImageA.Top = y1_
                        CnImageA.Width = .Width
                        CnImageA.Height = .Height
                    End With

                    colPage(intCurrentPage).Add CnImageA
                    Set CnImageA = Nothing

                    sngCurrentPos = y1_ + y2_
                Case objTypeTable
                    Set CTableA = Tables(intObjIndex)
                    With CTableA
                        sngTitleHeight = .TitleHeight
                        sngBodyHeight = .BodyHeight
                        FirstRowIsTitle = .FirstRowIsTitle
                        lngTotalColumns = .TotalColumns
                        lngColumnsCount = .Columns.Count - 1
                        intBorderWidth = Abs(Int(-(.BorderWidth / 10) * sngLineWidthCoefficient))
                        If .PositionIsAbsolute Then
                            sngTableTop = pTopMargin + .Top
                        Else
                            sngTableTop = sngCurrentPos + .Top
                        End If

                        TextArray() = .TextArray
                        ReDim TextArrayN(0)

                        ly = LBound(TextArray, 2): uy = UBound(TextArray, 2)
                        lngCurrentRow = 0
                        lngTotalRows = uy - ly + 1
                        lngStartRow = 0: lngEndRow = ly - 1
                        If FirstRowIsTitle Then
                            lngTotalRows = lngTotalRows - 1
                            lngEndRow = lngEndRow + 1
                        End If

                        sngAvailHeight = pPrintableHeight - sngTableTop - pBottomMargin
                        If FirstRowIsTitle Then sngAvailHeight = sngAvailHeight - sngTitleHeight
                        y1_ = 0
                        Row_ = ly

                        Do Until Row_ >= uy
                            lngRowsOnPage = Int(sngAvailHeight / sngBodyHeight)
                            If lngRowsOnPage < 1 Then
                                If sngCurrentPos = pTopMargin Then sngCurrentPos = sngCurrentPos + 1
                                NewPage
                                sngAvailHeight = availHeight
                                If FirstRowIsTitle Then sngAvailHeight = sngAvailHeight - sngTitleHeight
                                sngTableTop = pTopMargin
                                lngRowsOnPage = Int(sngAvailHeight / sngBodyHeight)
                                If lngRowsOnPage = 0 Then lngRowsOnPage = 1
                            End If
                            If lngRowsOnPage * lngTotalColumns >= lngTotalRows - lngCurrentRow Then
                                lngRowsOnPage = Abs(Int(-(lngTotalRows - lngCurrentRow) / lngTotalColumns))
                                Do While lngRowsOnPage * (lngTotalColumns - 1) >= lngTotalRows - lngCurrentRow
                                    lngTotalColumns = lngTotalColumns - 1
                                Loop
                            End If

                            lngStartRow = lngEndRow + 1
                            If lngStartRow > uy Then Exit Do
                            lngEndRow = lngEndRow + lngRowsOnPage * lngTotalColumns
                            If lngEndRow > uy Then
                                lngEndRow = uy
                            End If
                            lngCurrentRow = lngCurrentRow + lngEndRow - lngStartRow + 1

                            ReDim TextArrayN(1 To lngColumnsCount + 1, 1 To lngEndRow - lngStartRow + 1 + IIf(FirstRowIsTitle, 1, 0))

                            j = 1
                            If FirstRowIsTitle Then
                                For Col_ = 1 To lngColumnsCount + 1
                                    TextArrayN(Col_, j) = TextArray(Col_, j)
                                Next Col_
                                j = j + 1
                            End If

                            For k = lngStartRow To lngEndRow
                                For Col_ = 1 To lngColumnsCount + 1
                                    TextArrayN(Col_, j) = TextArray(Col_, k)
                                Next Col_
                                j = j + 1
                            Next k

                            sngAvailHeight = 0
                            Row_ = lngEndRow
                            If UBound(TextArrayN()) > 0 Then
                                Set CnTableA = New clsTableAttributes
                                CnTableA.FirstRowIsTitle = FirstRowIsTitle
                                CnTableA.Left = .Left + pLeftMargin

                                CnTableA.TitleHeight = sngTitleHeight
                                CnTableA.TitleForeColor = .TitleForeColor
                                CnTableA.TitleFontName = .TitleFontName
                                CnTableA.TitleFontSize = .TitleFontSize
                                CnTableA.TitleFontBold = .TitleFontBold
                                CnTableA.TitleFontItalic = .TitleFontItalic
                                CnTableA.TitleFontUnderline = .TitleFontUnderline
                                CnTableA.TitleFontStrikethru = .TitleFontStrikethru
                                CnTableA.TitleWordWrap = .TitleWordWrap

                                CnTableA.BodyHeight = sngBodyHeight
                                CnTableA.BodyForeColor = .BodyForeColor
                                CnTableA.BodyFontName = .BodyFontName
                                CnTableA.BodyFontSize = .BodyFontSize
                                CnTableA.BodyFontBold = .BodyFontBold
                                CnTableA.BodyFontItalic = .BodyFontItalic
                                CnTableA.BodyFontUnderline = .BodyFontUnderline
                                CnTableA.BodyFontStrikethru = .BodyFontStrikethru
                                CnTableA.BodyWordWrap = .BodyWordWrap

                                CnTableA.TotalColumns = lngTotalColumns
                                CnTableA.ColumnSpacing = .ColumnSpacing
                                CnTableA.CellSpacing = .CellSpacing
                                CnTableA.BorderWidth = intBorderWidth
                                CnTableA.BorderColor = .BorderColor

                                For j = 1 To lngColumnsCount
                                    With .Columns(j)
                                        CnTableA.Columns.Add .ColumnWidth, .TitleAlign, .BodyAlign
                                    End With
                                Next j
                                CnTableA.Columns.Add

                                CnTableA.Top = sngTableTop
                                CnTableA.TextArray = TextArrayN

                                colPage(intCurrentPage).Add CnTableA
                                Set CnTableA = Nothing
                            End If
                        Loop
                    End With

                    sngCurrentPos = sngTableTop + lngRowsOnPage * sngBodyHeight
                    If FirstRowIsTitle Then sngCurrentPos = sngCurrentPos + sngTitleHeight
                Case objTypePageBreak
                    NewPage
            End Select
        Next i

        If blnViewPaginateStatus Then Unload frmPaginateStatus
    Else
        err.Raise 18, , "There is no job for print, before you must create a job."
    End If
End Sub

Private Sub NewPage()
    If sngCurrentPos > pTopMargin Then
        sngCurrentPos = pTopMargin

        intCurrentPage = intCurrentPage + 1
        If blnViewPaginateStatus Then
            frmPaginateStatus.lblStatus.Caption = "Page: " & CStr(intCurrentPage)
            frmPaginateStatus.lblStatus.refresh
        End If

        ReDim Preserve colPage(1 To intCurrentPage)
        Set colPage(intCurrentPage) = New Collection
    End If
End Sub

Private Sub InitLineWidthCoefficient(hDC As Long)
    sngLabelExCoefficient = GetDeviceCaps(hDC, LOGPIXELSY) / 72
    sngLineWidthCoefficient = GetDeviceCaps(hDC, LOGPIXELSX) / 25.4
End Sub
