Шаг 39.
Библиотека OWL.
Программа "Печать вкладышей". Печать вкладыша

    На этом шаге мы рассмотрим особенности печати вкладыша.

    После того, как пользователь введет все данные для вкладыша кассеты, он, естественно, захочет их распечатать. Это можно сделать, выбрав кнопку Print, которая вызывает функцию ответа на сообщение CmPrint():

void TWCWnd::CmPrint()
{
  // Скопировать данные из областей ввода
  // диалогового окна в буфер обмена.
  TransferData(tdGetData);
  // Скопировать данные из буфера обмена е
  // соответствукщий буфер, в зависимости от текущей стороны.
  if (sideA) sideAStrgs = dlgStrgs;
  else  sideBStrgs = dlgStrgs;
  // Обработать объект  печати. 
  TCassPrintout printout("Печать вкладышей");
  // Напечатать вкладыш кассеты. 
  printer->Print(this, printout, TRUE);
}

    Программа копирует данные из диалогового окна в буфер обмена, а затем копирует буфер обмена в соответствующее буферное ЗУ, в зависимости от текущей стороны. Затем программа обрабатывает объект печати printout и вызывает функцию Print() объекта printer для того, чтобы напечатать вкладыш для кассеты.

    В этом месте программы начинает работать объект printout, генерируя изображение, которое должно быть послано на принтер. Посмотрите сначала на объявление класса:

class TCassPrintout : public TPrintout
{
  protected:
    // Указатели на названия песен. 
    char *sideAEdits[16],*sideBEdits[16]; 
  public:
    TCassPrintout(const char *title); 
  protected:
    void GetDialoglnfo( int &minPage, int &maxPage,
          int &selFromPage, int &selToPage); 
    void PrintPage( int, TRect&, unsigned);
  private:
    void DrawLabel( int horDots, int verDots); 
    void DrawBodyText( int horDots, int verDots); 
    void DrawTitleText( int horDots, int verDots); 
    TFont* CreateCassFont( int hSize, int vSize);
};

    Этот класс имеет два защщенных члена-данных, которые оба являются массивами указателей на char. Они предназначены для хранения адресов строк с названиями песен для сторон А и В, чтобы программа могла легко получить доступ к этим строкам внутри цикла. Кроме конструктора класса и его функций-членов GetDialogInfo() и PrintPage(), класс TCassPrintout имеет четыре закрытых функции-члена, которые разбивают процесс печати на четыре легко управляемые части. DrawLabel() рисует линии, которые создают форму вкладыша, DrawBodyText() рисует текст, печатаемый мелким шрифтом, DrawTitleText() рисует название кассеты крупным шрифтом и CreateCassFont() создает необходимые шрифты.

    Процесс рисования начинается, как это обычно бывает для объектов TPrintout, в функции класса PrintPage():

void TCassPrintout::PrintPage( int, TRect&, unsigned)
{
  // Получить горизонтальное и вертикальное
  // разрешение для принтера.
  int horDots = DC->GetDeviceCaps(LOGPIXELSX);
  int verDots = DC->GetDeviceCaps(LOGPIXELSY);
  // Нарисовать чертеж вкладыша кассеты.
  DrawLabel(horDots, verDots);
  // Напечатать название стороны и названия песен.
  DrawBodyText(horDots, verDots);
  // Напечатать основные названия кассеты.
  DrawTitleText(horDots, verDots);
}

    Сначала два обращения к функции GetDeviceCaps() из контекста устройства принтера устанавливают горизонтальное и вертикальное разрешение для принтера, задаваемое в точках на дюйм. Затем PrintPage() вызывает функцию для рисования различных элементов вкладыша для кассеты, передавая в качестве параметров горизонтальное и вертикальное разрешение для принтера.

    Первая, предназначенная для рисования, функция DrawLabel() рисует очертания вкладыша с помощью последовательности вызовов MoveTo() и LineTo():

void TCassPrintout::DrawLabel(int horDots, int verDots)
{
  DC->MoveTo(horDots/2, verDots/2);
  DC->LineTo(horDots*4.5, verDots/2);
  DC->LineTo(horDots*4.5, verDots*4.3);
  DC->LineTo(horDots/2, verDots*4.3);
  DC->LineTo(horDots/2, verDots/2);
  DC->MoveTo(horDots/2, verDots*0.75);
  DC->LineTo(horDots*4.5, verDots*0.75);
  DC->MoveTo(horDots/2, verDots*0.93);
  DC->LineTo(horDots*4.5, verDots*0.93);
  DC->MoveTo(horDots/2, verDots*3.1);
  DC->LineTo(horDots*4.5, verDots*3.1);
  DC->MoveTo(horDots/2, verDots*3.62);
  DC->LineTo(horDots*4.5, verDots*3.62);
  DC->MoveTo(horDots*2.5, verDots*0.75);
  DC->LineTo(horDots*2.5, verDots*3.1);
}

    Так как переменные horDots и verDots представляют собой число точек на дюйм по горизонтали и вертикали, вам нетрудно будет представить размеры вывода принтера в дюймах. Например, если вы хотите начать рисовать вкладыш кассеты на расстоянии полдюйма от верхнего левого угла страницы, обратитесь к координатам, заданным horDots/2 и verDots/2. На принтере с разрешением 120 точек на дюйм это будет соответствовать расстоянию в 60 точек от верхнего левого угла, а на принтере с разрешением 300 точек на дюйм - 150 точкам от верхнего левого угла. В обоих случаях именно полдюйма дадут в результате одинаковое расположение на странице для любого принтера. Используя подобные вычисления, программа может нарисовать весь чертеж вкладыша для кассеты без лишних хлопот.

    На следующем шаге мы рассмотрим создание и использование шрифтов.




Предыдущий шаг Содержание Следующий шаг