|
Программирование >> Вывод графики
documentLines.Add(nextLineInfo); ++nLines; sr.Close(); if (nLines > 0) { documentHasData = true; menuFilePrint.Enabled = true; menuFilePrintPreview.Enabled = true; else documentHasData = false; menuFilePrint.Enabled = false; menuFilePrintPreview.Enabled = false; CalculateLineWidths(); CalculateDocumentSize(); Text = standardTitle + - + FileName; Invalidate(); Здесь выделен новый код, добавленный к методу. Далее добавим поле-член в класс Form1: public partial class Form1 : Form private int pagesPrinted = 0; Это поле будет использоваться для указания номера текущей печатаемой страницы. Мы объявляем его полем-членом, потому что информацию о текущей странице нужно держать в памяти между вызовами обработчика событий PrintPage. Далее следуют обработчики событий команд меню Print и PrintPreview: private void menuFilePrintPreview Click(object sender, System.EventArgs e) this.pagesPrinted = 0; PrintPreviewDialog ppd = new PrintPreviewDialog(); PrintDocument pd = new PrintDocument(); pd.PrintPage += new PrintPageEventHandler (this.pd PrintPage); ppd.Document = pd; ppd.ShowDialog(); private void menuFilePrint Click(object sender, System.EventArgs e) this.pagesPrinted = 0; PrintDocument pd = new PrintDocument(); pd.PrintPage += this.pd PrintPage); pd.Print(); Мы уже описали шаги, которые необходимо выполнить для осуществления печати, и можно видеть, что эти обработчики событий просто реализуют описанную процедуру. В обоих случаях создается экземпляр объекта PrintDocument и к его событию PrintPage присоединяется обработчик. В случае печати вызывается PrintDocument. Print() , в то время как для предварительного просмотра объект PrintDocument присоединяется к PrintPreviewDialog, и вызывается метод ShowDialog() диалогового окна предварительного просмотра. Реальная работа события PrintPage выполняется в обработчике события, который выглядит следующим образом: private void pd PrintPage(object sender, PrintPageEventArgs e) float yPos = 0; float leftMargin = e.MarginBounds.Left; float topMargin = e.MarginBounds.Top; string line = null; Вхчислить количество строк на страницу. int linesPerPage = (int)(e.MarginBounds.Height / mainFont.GetHeight(e.Graphics)); int lineNo = pagesPrinted * linesPerPage; Печатать каждую строку файла. int count = 0; while(count < linesPerPage && lineNo < this.nLines) line = ((TextLineInformation)this.documentLines[lineNo]).Text; yPos = topMargin + (count * mainFont.GetHeight(e.Graphics)); e.Graphics.DrawString(line, mainFont, Brushes.Blue, leftMargin, yPos, new StringFormat()); lineNo++; count++; Если еще остались строки, печатать другую страницу. if(this.nLines > lineNo) e.HasMorePages = true; else e.HasMorePages = false; pagesPrinted++; После объявления нескольких локальных переменных первое, что мы здесь делаем - это вычисляем количество строк, которое может быть отображено на одной странице, как высоту страницы, деленную на высоту строки с округлением в меньшую сторону. Высоту страницы можно получить из свойства PrintPageEventArgs.MarginBounds. Это свойство представляет собой структуру RectangleF, которая инициализирована размерами страницы. Высота строки получается из поля Form1.mainFont, представляющего шрифт, используемый для отображения текста. Нет причин использовать для печати какой-то другой шрифт. Обратите внимание, что в примере PrintingCapsEditor количество строк на страницу всегда одно и то же, поэтому имело бы смысл его запомнить после первого вычисления. Однако эти вычисления не особенно сложны, к тому же в более развитом приложении это значение может меняться, поэтому ничего плохого не случится, если мы станем повторно вычислять его при печати каждой страницы. Мы также инициализируем здесь переменную с именем lineNo. Она представляет начинающийся с нуля индекс строки документа, которая будет первой на странице. Эта информация важна, поскольку в принципе метод pd PrintPage() может быть вызван для печати любой страницы, а не только первой. Значение lineNo вычисляется как количество строк на странице, умноженное на количество уже напечатанных страниц. Далее запускается цикл, печатающий каждую строку. Этот цикл прерывается либо когда обнаруживается, что уже напечатаны все строки текста документа, либо когда будут напечатаны все строки, помещающиеся на текущей страницы - в зависимости от того, что произойдет раньше. И, наконец, мы проверяем, остались ли еще строки документа для печати, и соответствующим образом устанавливаем свойство HasMorePages аргумента PrintPageEventArgs, а также увеличиваем на единицу значение поля pagesPrinted, чтобы знать, какую страницу следует напечатать, когда в следующий раз будет вызван обработчик события PrintPage. Следует отметить один момент относительно этого обработчика событий, а именно: нам не нужно беспокоиться о том, как выполняются команды рисования. Мы просто используем объект Graphics, который получаем из PrintPageEventArgs. Класс PrintDocument, разработанный Microsoft, сам позаботится о том, что если мы собираемся печатать, то объект Graphics должен быть прикреплен к принтеру. Если же речь идет о предварительном просмотре, он прикрепляется к форме предварительного просмотра на экране. И, наконец, мы должны убедиться, что пространство имен System.Drawing.Printing включено для поиска определений типов: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Printing; using System.Text; using System.Windows.Forms; using System.IO; Все, что остается - скомпилировать проект и проверить, как он работает. На рис. 33.19 показано то, что мы увидим, если запустим CapsEdit, загрузим текстовый документ (как и раньше - файл исходного кода на C# из проекта) и выберем команду меню Print Preview (Предварительный просмотр). Рис. 33.19. Результат работы примера CapsEdit На рис. 33.19 показан документ, прокрученный до 5-й страницы, и установлен нормальный размер для предварительного просмотра. PrintPreviewDialog предлагает множество средств, что видно в панели инструментов в верхней части формы. Доступные опции включают печать документа, увеличение его, отображение двух, трех, четырех или шести страниц сразу. Все эти опции полностью функциональны, и нам не приходится ничего делать. На рис. 33.20 можно видеть результат переключения масштаба на автоматический режим и выбора одновременного отображения четырех страниц (третья справа кнопка в линейке инструментов).
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |