Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Programming_Windows_95_Part_II.pdf
Скачиваний:
41
Добавлен:
05.06.2014
Размер:
3.02 Mб
Скачать

92

AbortDoc(hdcPrn);

else

if(EndPage(hdcPrn))

EndDoc(hdcPrn);

}

if(!bUserAbort)

{

EnableWindow(hwnd, TRUE);

DestroyWindow(hDlgPrint);

}

DeleteDC(hdcPrn);

return bError || bUserAbort;

}

Рис. 15.13 Программа PRINT4

Программа PRINT4 отличается от программы PRINT3 только несколькими особенностями. Обратите внимание, что вместо прямоугольника, проходящего по границе страницы в целом, функция Rectangle печатает его для каждой полосы. Это позволяет вам увидеть то, как для конкретного принтера реализуется разбиение на полосы. Структура кода, выполняющего печать, такова:

if(StartDoc(hdcPrn, &di) > 0 && StartPage(hdcPrn) > 0 &&

ExtEscape(hdcPrn, NEXTBAND, 0, NULL, sizeof(rect),(LPSTR) &rect) > 0)

{

while(!IsRectEmpty(&rect) && !UserAbort)

{

[вызовы функций GDI]

if(ExtEscape(hdcPrn, NEXTBAND, 0, NULL, sizeof(rect),(LPSTR)&rect) < 0)

{

// если ошибка, установить флаг и

bError = TRUE;

break;

// выйти из цикла

}

 

}

}

else

bError = TRUE;

Цикл while выполняется только в том случае, если прямоугольник не пуст и, если пользователь не отказался от печати в окне диалога. Программа PRINT4 должна проверять возвращаемое значение каждого вызова функции ExtEscape с параметром подфункции NEXTBAND и устанавливать флаг bError, если это возвращаемое значение отрицательно. Если ни один вызов функции ExtEscape не возвратит ошибки, то задание на печать должно быть закончено либо с помощью вызова функции EndDoc, либо прервано с помощью вызова функции AbortDoc. Этот код представлен ниже:

if(!bError)

{

if(bUserAbort)

AbortDoc(hdcPrn);

else

if(EndPage(hdcPrn))

EndDoc(hdcPrn);

}

Принтер и шрифты

В главе 4 имеется программа JUSTIFY, в которой для вывода на экран отформатированного текста используются шрифты GDI. Программы, которые работают с форматированным текстом на экране, обычно имеют возможность печати этого текста. Действительно, в программах обработки текстов и настольных издательских системах экран используется главным образом только для предварительного просмотра выводимых на печать данных.

Шрифты типа TrueType предоставляют простейший путь точного представления текста на экране так, как если бы он был напечатан. Этот подход ограничивает возможности программы использованием только шрифтов типа True Type. Если выбор шрифта осуществляется с помощью функции EnumFontFamilies, то вы можете установить бит

93

TRUETYPE_FONTTYPE параметра iFontType функции обратного вызова. В этом случае будет использоваться окно списка только тех шрифтов, у которых установлен бит TRUETYPE_FONTTYPE.

Если в программе предоставить пользователю возможность выбора шрифта в диалоговом окне, которое отображается при вызове функции ChooseFont из библиотеки диалоговых окон общего пользования (как показано в программе JUSTIFY в главе 4), то для ограничения списка шрифтов только шрифтами типа TrueType можно включить в поле Flags структуры CHOOSEFONT флаг CF_TTONLY.

Однако, ограничение возможности выбора шрифта только шрифтами типа TrueType может не удовлетворить тех пользователей, кто вложил деньги в дополнительные принтерные шрифты, загружаемые или на картриджах. Такие шрифты не будут перечислены в предлагаемом пользователю списке. Для того, чтобы такие шрифты оказались в окне диалога, созданном с помощью функции ChooseFont, необходимо включить в поле Flags структуры

CHOOSEFONT константу CF_PRINTERFONTS.

Необходимо также установить поле hDC структуры CHOOSEFONT равным описателю контекста принтера. Тогда список шрифтов, выводимых в окне списка будет ограничен внутренними шрифтами принтера, шрифтами типа TrueType и векторными шрифтами. (Чтобы исключить появление в списке векторных шрифтов, используйте флаг

CF_NOVECTORFONTS.)

Если пользователю дается возможность выбора принтерных шрифтов, то вид шрифтов на экране будет только примерно соответствовать тому, что будет напечатано. Например, если для принтера предлагается 15-точечный шрифт Zapf Chancery, он может быть апроксимирован 15-точечным шрифтом типа TrueType, но при этом ширина символа шрифта типа TrueType будет отличаться от ширины символа шрифта Zapf Chancery. Даже для шрифтов типа TrueType ширина символа на экране и принтере может отличаться на величину ошибки округления, возникающую из-за отличий экрана и принтера.

Короче говоря, при написании программы, в которой на экране должен выводиться отформатированный текст, предназначенный для печати, придется сделать дополнительные усилия. Вот несколько указаний для начала.

При выводе отформатированного текста на экране желательно, чтобы текст выглядел так, как он в конце концов будет напечатан. Для определения размера бумаги и размера области печати можно использовать функции GetDeviceCaps и DeviceCapabilities. Например, если ширина бумаги равна 8,5 дюймов, и пользователь задает размер левого и правого отступов по одному дюйму, то желательно выводить текст в область экрана шириной 6,5 дюймов. Для такого вывода подходит режим отображения "logical twips", о котором говорилось в главе 4. Однако, будьте осторожны. Если пользователь выбирает 15-точечный шрифт, который поддерживает принтер, этот шрифт пришлось бы приспособить к ширине области экрана и подобрать вместо него, скажем, 14-точечный экранный шрифт, но такой 14-точечный шрифт нельзя использовать для определения того, сколько может занять одна напечатанная 15-точечным шрифтом строка. Это надо определять на основе принтерного шрифта. Подобным образом принтерный шрифт необходимо использовать для определения количества строк на странице.

Для форматирования текста на экране понадобится описатель контекста экрана и описатель информационного контекста принтера. До того, как фактически начать печатать, описатель контекста принтера не нужен. Проделайте следующие шаги:

1. В структуру логического шрифта объедините имя шрифта, его размер и выбранные пользователем атрибуты, и этот логический шрифт выберите в информационный контекст принтера.

2.Для определения действительных размера и характеристик выбранного шрифта для принтера используйте вызов функции GetTextMetrics. Для получения имени шрифта используйте вызов функции GetTextFace.

3.Информацию, полученную на втором шаге, используйте для создания другой структуры логического шрифта, основанного на размере и характеристиках принтерного шрифта, выберите этот логический шрифт в контекст экрана. Теперь шрифт, выбранный в контексте экрана, приблизительно соответствует шрифту, выбранному в информационном контексте принтера.

4.При отображении текста на экране следуйте общей схеме, которая использовалась в функции Justify программы JUSTIFY. Однако, при этом выполните функции GetTextExtent и SetTextJustification, используя информационный контекст принтера, но остановитесь перед функцией TextOut. Такой подход позволяет определить количество символов в строке и число строк на странице.

5.Когда для принтера сформирована каждая строка текста, то вызовите функцию GetTextExtent и (возможно) SetTextJustification, используя контекст экрана. Затем, для вывода строки на экран используйте вызов функции TextOut.

Для печати текста вы, вероятно, будете использовать код, похожий на код из файла POPPRINT.C в сочетании с логикой функции Justify файла JUSTIFY.С. Получите контекст принтера и снова выполните функции GetTextExtent и SetTextJustification, на этот раз для печати каждой строки, используя функцию TextOut.

Часть V

Связи и обмен данными

Соседние файлы в предмете Операционные системы