Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


Код: Выделить весь код
    Sub PrintDocumentOnPrintPage(ByVal obj As Object, _
                             ByVal ppea As Printing.PrintPageEventArgs)
        Dim grfx As Graphics = ppea.Graphics    'Задаём контекст печати. Через объект grfx будет формироватся страница
        Dim szf As SizeF = grfx.VisibleClipBounds.Size    'взять допустимые размеры страницы
        DoPage(grfx, Color.Black, CInt(szf.Width), CInt(szf.Height))    'передать контекст, цвет шрифта и допустимые размеры в процедуру DoPage, сейчас там рисуется только Х, однако данную процедуру можно переназначить в наследниках
    End Sub
Пример ниже берёт текст из ячеек ListView, аналогично можно работать и с TextBox. Форматировать страницу можно через табуляцию (vbTab) и перенос строки (vbLf).
Пример использования PrintableForm к ранее написанной форме >>

Предположим есть некая форма (в примере ниже собирающая информацию о локальных дисках)
>>
Код: Выделить весь код
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Class AbstractForm
    Inherits Form
    Dim VolumeListView As New ListView
    Shared Sub Main()
        Application.Run(New AbstractForm)
    End Sub
    Sub New()
        Text = "Sample"
        BackColor = SystemColors.Window
        ForeColor = SystemColors.WindowText
        ResizeRedraw = True

        With VolumeListView
            .Parent = Me
            .Location = Point.Empty
            .Size = New Size(ClientSize.Width, ClientSize.Height \ 2)
            .View = View.Details
            .HeaderStyle = ColumnHeaderStyle.Clickable
            .FullRowSelect = True
            .MultiSelect = True
            .BorderStyle = BorderStyle.Fixed3D
            '.Dock = DockStyle.Fill
            .Columns.Add("Volume")
            .Columns.Add("Layout")
            .Columns.Add("Type")
            .Columns.Add("File System")
            .Columns.Add("Status")
            .Columns.Add("Capacity")
            .Columns.Add("Free Space")
            .Columns.Add("% Free")
        End With

        Dim Drives As IO.DriveInfo() = IO.DriveInfo.GetDrives()
        For Each Drive In Drives
            If Drive.IsReady Then
                Dim item1 As ListViewItem = New ListViewItem(New String() {Drive.Name})
                With item1.SubItems
                    .Add("") '.Add("Simple") 'ToDo
                    .Add(Drive.DriveType.ToString) 'Some other type req(see diskmgmt.msc)
                    .Add(Drive.DriveFormat)
                    .Add("") 'ToDo'.Add("Healthy") 'ToDo
                    .Add(Math.Ceiling(Drive.TotalSize / 1024) & " KB")
                    .Add(Math.Ceiling(Drive.AvailableFreeSpace / 1024) & " KB") ' (Drive.TotalFreeSpace)
                    .Add(Math.Ceiling(100 * Drive.AvailableFreeSpace / Drive.TotalSize) & " %")
                End With
                VolumeListView.Items.AddRange(New ListViewItem() {item1})
            End If
        Next
    End Sub
    Protected Overrides Sub OnResize(ByVal re As EventArgs)
        VolumeListView.Size = New Size(ClientSize.Width, VolumeListView.Size.Height)
    End Sub
End Class

Допустим потребовалось вывести изображаемую информацию на печать. Код формы был создан вручную, а не сгенерирован студией, по этому переделываем приложение по первому способу - заменяем наследование от Form на наследование от PrintableForm. В этом случаи в точки входа потребуется добавить ключевое слово Shadows выйдет так Shared Shadows Sub Main(). В свойствах проекта так же нужно поменять точку входа на имя класса (в данном примере на AbstractForm).
Если сейчас запустить проект кроме "Х" на всей форме ничего не поменяет (а на печать только этот Х и будет отправлен). Поэтому переназначаем процедуру DoPage для формы.
Именно здесь будет формироваться страница. Помимо этого она будет отображаться на самой форме - очень удобно если нужна форма предварительного просмотра.
В данном пример, сам сформированный текст будет скрыт за ListView, а вот картинка %WinDir%\Gone Fishing.bmp будет видна из ListView.
Если в системной директории данного файла нет (система не ХР или файл просто удалён) данную строчку надо закомментировать, проверка на отсутствие не проводится, или указать путь к своему графическому файлу.

Если на рабочей формы никакого предварительного просмотра не надо, просто переназначаем событие OnPaint (в примере ниже раскомментируем соответственные строчки, кроме MyBase.OnPaint(pea)).
В результате получим
Код: Выделить весь код
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Class AbstractForm
    Inherits PrintableForm
    Dim VolumeListView As New ListView
    Shared Shadows Sub Main()
        Application.Run(New AbstractForm)
    End Sub
    Sub New()
        Text = "Sample"
        BackColor = SystemColors.Window
        ForeColor = SystemColors.WindowText
        ResizeRedraw = True

        With VolumeListView
            .Parent = Me
            .Location = Point.Empty
            .Size = New Size(ClientSize.Width, ClientSize.Height \ 2)
            .View = View.Details
            .HeaderStyle = ColumnHeaderStyle.Clickable
            .FullRowSelect = True
            .MultiSelect = True
            .BorderStyle = BorderStyle.Fixed3D
            '.Dock = DockStyle.Fill
            .Columns.Add("Volume")
            .Columns.Add("Layout")
            .Columns.Add("Type")
            .Columns.Add("File System")
            .Columns.Add("Status")
            .Columns.Add("Capacity")
            .Columns.Add("Free Space")
            .Columns.Add("% Free")
        End With

        Dim Drives As IO.DriveInfo() = IO.DriveInfo.GetDrives()
        For Each Drive In Drives
            If Drive.IsReady Then
                Dim item1 As ListViewItem = New ListViewItem(New String() {Drive.Name})
                With item1.SubItems
                    .Add("") '.Add("Simple") 'ToDo
                    .Add(Drive.DriveType.ToString) 'Some other type req(see diskmgmt.msc)
                    .Add(Drive.DriveFormat)
                    .Add("") 'ToDo'.Add("Healthy") 'ToDo
                    .Add(Math.Ceiling(Drive.TotalSize / 1024) & " KB")
                    .Add(Math.Ceiling(Drive.AvailableFreeSpace / 1024) & " KB") ' (Drive.TotalFreeSpace)
                    .Add(Math.Ceiling(100 * Drive.AvailableFreeSpace / Drive.TotalSize) & " %")
                End With
                VolumeListView.Items.AddRange(New ListViewItem() {item1})
            End If
        Next
    End Sub
    Protected Overrides Sub OnResize(ByVal re As EventArgs)
        VolumeListView.Size = New Size(ClientSize.Width, VolumeListView.Size.Height)
    End Sub
    Protected Overrides Sub DoPage(ByVal grfx As System.Drawing.Graphics, ByVal clr As System.Drawing.Color, ByVal cx As Integer, ByVal cy As Integer)

        Dim text2Print As String = vbNullString
        For Each Column As ColumnHeader In VolumeListView.Columns
            text2Print = text2Print & Column.Text & vbTab
        Next

        text2Print = text2Print & vbLf

        For Each ListItem As ListViewItem In VolumeListView.Items
            For Each SubItem As ListViewItem.ListViewSubItem In ListItem.SubItems
                text2Print = text2Print & SubItem.Text & vbTab
            Next SubItem
            text2Print = text2Print & vbLf
        Next ListItem

        grfx.DrawString(text2Print, Font, New SolidBrush(clr), New Point(cx / 20, cy / 20))

        grfx.DrawImage(New Bitmap(System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "Gone Fishing.bmp")), New Point(cx / 2, cy / 6))

    End Sub
    'Protected Overrides Sub OnPaint(ByVal pea As System.Windows.Forms.PaintEventArgs)
    ''MyBase.OnPaint(pea)
    'End Sub
End Class


P.S.
PrintableForm печатает только на одну страницу. Разбивку по страницам не производит. Всё что не поместилось отсекается.
Это сообщение посчитали полезным следующие участники:

Отправлено: 15:28, 05-10-2010 | #6