Проблема:
Нам нужна помощь в том, как использовать возможность WinForms для автоматического масштабирования до различных DPI, чтобы мы могли печатать наши формы с разрешением 600 точек на дюйм, а не с разрешением экрана.
Для печати «Что видишь, то и получаешь» мы просто брали красиво оформленное окно и печатали его (отключая полосы прокрутки, кнопки и тому подобное). Это прекрасно работает, ЗА ИСКЛЮЧЕНИЕМ одного: разрешение экрана составляет 96 или 120 точек на дюйм (независимо от разрешения экрана)… любое из этих значений выглядит зернистым и непрофессиональным (наши клиенты жалуются). И хотя он такой же читаемый, как и на экране, вы ожидаете, что печатные документы будут БОЛЕЕ читаемы, чем на экране… вы ожидаете, что сможете увидеть дополнительные детали, сможете прочитать меньший текст и т. д.
Рассматриваемые альтернативы:
Учитывая, что у нас прекрасно работает автоматическое масштабирование, так что наше окно выглядит хорошо при разрешении 96 dpi, 120 dpi, 144 dpi и т. д., мы надеялись, что сможем просто нарисовать наше окно с разрешением 600 dpi, а затем распечатать его.
ИЛИ, мы рассмотрели рисование окна за пределами экрана в 5-6 раз больше, чем обычно, чтобы у нас было то же количество пикселей, что и при разрешении 600 точек на дюйм, но с разрешением 96 или 120 точек на дюйм… но затем рисование этого гигантского окна на печатной странице с разрешением 300 или 600 точек на дюйм. dpi (независимо от принтера).
Если вы можете рассказать нам, как сделать любой из этих вариантов, ИЛИ если вы можете дать нам другой способ достижения нашей цели, мы будем очень признательны.
Текущий код:
В случае, если это имеет значение, наша форма состоит из FlowLayoutPanel, укладывающего другие меньшие FlowLayoutPanels в столбцы, эти меньшие FlowLayoutPanels размещают один столбец TextBox, RichTextBox, стороннего RichTextEditor, PictureBox и DataGridView. Мы используем класс, производный от PrintDocument, реализующий OnBeginPrint, OnPrintPage и OnEndPrint. В OnPrintPage он манипулирует нашим обычным окном за пределами экрана (ниже и справа от фактических экранов), чтобы соответствовать размеру страницы, затем запрашивает нашу главную панель (верхнюю FlowLayoutPanel) для DrawToBitmap, затем использует объект Graphics, переданный в PrintEventArgs, для DrawImage это растровое изображение. Мы также используем Graphics.DrawString для применения нижнего колонтитула к каждой странице. Основной код:
using (Bitmap bm = new Bitmap(sz.Width, sz.Height))
{
Rectangle rect = new Rectangle(0, 0, sz.Width, sz.Height);
mp.DrawToBitmap(bm, rect);
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; // so footer is anti-aliased
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // so when we scale up, we smooth out the jaggies somewhat
e.Graphics.DrawImage(bm, this.MarginBounds, rect, GraphicsUnit.Pixel);
if (this.Footer != null)
e.Graphics.DrawImage(this.Footer, this.FooterLocation);
if (!string.IsNullOrEmpty(pageNumber))
{
e.Graphics.DrawString(pageNumber, KBStyle.Normal.Font, Brushes.Black,
this.MarginBounds.X, this.FooterLocation.Y + FooterOffset);
}
}
Как мы должны это сделать, чтобы получить 600 dpi на печатной странице? (Или даже 300 dpi было бы здорово!)
Когда мы печатаем это, оно выглядит намного лучше при печати на машине с разрешением 120 точек на дюйм, чем при печати на машине с разрешением 96 точек на дюйм, поэтому мы знаем, что это печатается с разрешением экрана. Но также заставляет нас задаться вопросом, есть ли какой-нибудь простой способ сказать ей, что «эта форма должна рисоваться с разрешением 600 dpi», и тогда весь остальной код выше просто работает.
Примечание: если мы возьмем EMF (расширенный метафайл) и распечатаем его на принтере в приведенном выше коде, этот EMF выйдет с разрешением 600 точек на дюйм. К сожалению, мы не нашли метод DrawToEMF, который можно было бы вызывать для FlowLayoutPanel вместо DrawToBitmap. Изменение растрового изображения на 600 dpi не помогает… метод DrawToBitmap по-прежнему рисует растровое изображение с разрешением экрана.
Спасибо!!