Шаг 33.
Библиотека OWL.
Стандартные диалоговые окна настройки печати

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

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

    В программе предыдущего шага при появлении на экране диалогового окна Print вы могли получить доступ к диалоговому окну Print Setup по нажатию кнопки Setup (Свойства). Однако большинство профессионально сделанных приложений позволяют пользователю отобразить диалоговое окно Print Setup из меню File, без необходимости выбирать команду Print. Библиотека OWL легко организует доступ к этому диалоговому окну через функцию-член Setup(). Следующий пример показывает, как добавить окна диалога Print Setup к вашей программе.

#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\printer.h>
#include <owl\dc.h>
#include <owl\editfile.rh>
#include "pr33_1.rc"

//Класс приложения
class TApp: public TApplication
{
  public:
	 TApp():TApplication(){}
	 void InitMainWindow();
};

//Класс основного окна
class TWndw : public TFrameWindow
{
  public:
        TWndw(TWindow *parent, const char far *title);
        ~TWndw();
  protected:
        TPrinter *printer;
        void Paint(TDC &dc, BOOL, TRect&);
        void CmFilePrint();
        void CmFilePrinterSetup();

        DECLARE_RESPONSE_TABLE(TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)
      EV_COMMAND(CM_FILEPRINT, CmFilePrint), 
      EV_COMMAND(CM_FILEPRINTERSETUP, CmFilePrinterSetup), 
END_RESPONSE_TABLE;

// Класс печати.
class TWndwPrintout : public TPrintout
{
  protected:
       TWindow *window;
  public:
       TWndwPrintout (const char *title, TWindow *w);
       void GetDialogInfo (int &minPage, int &maxPage,
            int &selFromPage, int &selToPage);
       void PrintPage (int, TRect &rect, unsigned);
};

TWndw::TWndw(TWindow *parent, const char far *title):
		  TFrameWindow(parent,title, 0, FALSE)
{
	// Добавить меню к главному окну.
	AssignMenu("MENU_1");
	// Определить расположение и размеры окна.
	Attr.X=50;
	Attr.Y=50;
	Attr.W=400;
	Attr.H=200;
        // Создать объект окна TPrinter. 
        printer = new TPrinter;
}

// TWndw::~TWndw()
// Это деструктор главного окна.
TWndw::~TWndw() 
{
    delete printer;
}

//TWndw::CmFilePrinterSetup()
// Эта функция реагирует на команду Printer Setup меню File.
void  TWndw::CmFilePrinterSetup()
{
  // Если объект принтера существует...
  if (printer)
  {
     // ...вызвать диалоговое окно Print Setup. 
     printer->Setup(this);
  }
}

//TWndw::CmFilePrint()
// Эта функция реагирует на команду Print меню File.
void  TWndw::CmFilePrint()
{
  // Если объект принтера существует...
  if (printer)
  {
     // Создать экземпляр объекта печати. 
     TWndwPrintout printout("Тест принтера", this);
     // Напечатать объект печати. 
     printer->Print(this, printout, TRUE);
  }
}

//TWndw::Paint()
// Эта функция переопределяет функцию Paint() из
// TWindow и реагирует на сообщения WM_PAINT, которые
// Windows посылает окну, если оно должно быть
// перерисовано. Однако, вызывая эту функцию с
// контекстом устройства TPrinter в качестве
// первого параметра, можно ее использовать для
// распечатки содержимого окна на принтере.
void TWndw::Paint(TDC &dc, BOOL, TRect&)
{
  // Нарисовать прямоугольник.
  dc.Rectangle (10,10,100,100);
}

//TWndwPrintout::TWndwPrintout()
// Это конструктор объекта  печати.
TWndwPrintout::TWndwPrintout(const char *title, TWindow *w) :
     TPrintout(title) 
{
  // Сохранить указатель окна для последующего использования.
  window = w;
}

//TWndwPrintout::GetDialogInfо()
// Эта функция обеспечивает значения, используемые
// в окне диалога прерывания принтера.
void TWndwPrintout::GetDialogInfo(int &minPage,int &maxPage, 
        int &selFromPage, int &selToPage)
{
  // Так как этот документ состоит только из одной 
  // страницы, установить значения таким образом,
  // чтобы номера страниц не выбирались 
  // диалога прерывания принтера. 
  minPage = 0; 
  maxPage = 0; 
  selFromPage = 0; 
  selToPage = 0;
}

// TWndwPrintout::PrintPage()
// Эта функция вызывается для каждой страницы
// документа. Именно в этом фрагменте программа
// создает изображение, которое появится на принтере.
void TWndwPrintout::PrintPage (int, TRect &rect, unsigned) 
{
  TSize oldVpExt, oldWndExt;
  // Установить произвольный режим отображения.
  int prevMode = DC->SetMapMode(MM_ISOTROPIC) ;
  // Получить размер рабочей области окна.
  TRect wndSize = window->GetClientRect();
  // Установить window в соотвествии с размерами
  // рабочей области окна.
  DC->SetWindowExt(wndSize.Size(),&oldWndExt);
  // Установить область просмотра в соотвествии
  // с размером страницы.
  DC->SetViewportExt(PageSize, &oldVpExt);
  // Вызвать функцию главного окна Paint(),
  // передавая контекст устройства объекта TPrinter,
  // а не контекст устройства окна.
  window->Paint(*DC, FALSE, rect);
  // Восстановить контекст устройства к начальным значениям.
  DC->SetWindowExt(oldWndExt);
  DC->SetViewportExt(oldVpExt);
  DC->SetMapMode(prevMode);
}

void TApp::InitMainWindow()
{
  TFrameWindow *wndw= new TWndw(0,"Использование принтера 3");
  SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
  return TApp().Run();
}

    Файл ресурсов:

#ifndef WORKSHOP_INVOKED
#include "windows.h"
#endif

#include <owl\printer.rh>

#define CM_EXIT              24310
#define CM_FILEPRINT         24337
#define CM_FILEPRINTERSETUP  24338

#ifdef RC_INVOKED

#include <owl\printer.rc>
#include <owl\except.rc>


MENU_1 MENU
{
 POPUP "&File"
 {
  MENUITEM "&Print...", CM_FILEPRINT
  MENUITEM "P&rint Setup...", CM_FILEPRINTERSETUP
  MENUITEM SEPARATOR
  MENUITEM "E&xit", CM_EXIT
 }
}
#endif

Текст этого приложения можно взять здесь.

    Запустите эту программу и откройте меню File, в котором находится команда Print Setup. При выборе этой команды отобразится диалоговое окно Print Setup, показанное на рисунке 1.


Рис.1. Окно Настройка печати

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

    Первое большое изменение в этой программе можно обнаружить в классе главного окна:

class TWndw : public TFrameWindow
{
  public:
        TWndw(TWindow *parent, const char far *title);
        ~TWndw();
  protected:
        TPrinter *printer;
        void Paint(TDC &dc, BOOL, TRect&);
        void CmFilePrint();
        void CmFilePrinterSetup();

        DECLARE_RESPONSE_TABLE(TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)
      EV_COMMAND(CM_FILEPRINT, CmFilePrint), 
      EV_COMMAND(CM_FILEPRINTERSETUP, CmFilePrinterSetup), 
END_RESPONSE_TABLE;

    Класс главного окна теперь содержит функцию отклика на сообщение CmFilePrinterSetup(), которую библиотека OWL вызовет в том случае, если пользователь выбрал из меню File команду Print Setup. Естественно, таблица откликов класса содержит вход, который связывает сообщение команды CM_FILEPRINTERSETUP с функцией ответа на сообщение CmFilePrinterSetup(). CmFilePrinterSetup() очень короткая:

void  TWndw::CmFilePrinterSetup()
{
  // Если объект принтера существует...
  if (printer)
  {
     // ...вызвать диалоговое окно Print Setup. 
     printer->Setup(this);
  }
}

    Все, что делает эта функция - это проверка существования объекта TPrinter с именем printer. Затем она отображает диалоговое окно Print Setup с обращением к функции Setup() объекта принтера, которая наследуется из класса TPrinter библиотеки OWL. Эта функция имеет единственным параметром указатель на родительское окно. Когда диалоговое окно Print Setup находится на экране, пользователь может сделать любые изменения, причем Windows прекрасно справится со всеми деталями. Диалоговое окно Print Setup так же, как и диалоговое окно Print, является частью библиотеки COMMDLG.DLL. Для его использования вашей программе не требуются дополнительные файлы ресурсов. Класс TPrintout в этой программе также содержит важное изменение:

class TWndwPrintout : public TPrintout
{
  protected:
       TWindow *window;
  public:
       TWndwPrintout (const char *title, TWindow *w);
       void GetDialogInfo (int &minPage, int &maxPage,
		            int &selFromPage, int &selToPage);
       void PrintPage (int, TRect &rect, unsigned);
};

    Здесь TWndwPrintout, который происходит из TPrintout, содержит функцию GetDialogInfo(). GetDialogInfo() переопределяет функцию класса TPrintout и представляет собой функцию, которую библиотека OWL вызывает для получения данных, необходимых для, соответственно, отображения окна диалога Print. До сих пор в рассмотренных ранее программах для GetDialogInfo() устанавливалось поведение по умолчанию. Но так как приводимые программы печатают только одну страницу, почему бы пользователю не попытаться изменить количество страниц? Программа может печатать только одну страницу, независимо от того, сколько установил пользователь. Так почему же не заблокировать раздел Print Range блока диалога?

    Чтобы сделать это, вы должны передать различные параметры в GetDialogInfo(), которые обеспечивают переопределение этой функции в вашем классе, происходящем из TPrintout.

    В примере показано, как это делается:

void TWndwPrintout::GetDialogInfo(int &minPage,int &maxPage, 
         int &selFromPage, int &selToPage)
{
  // Так как этот документ состоит только из одной 
  // страницы, установить значения таким образом,
  // чтобы номера страниц не выбирались 
  // диалога прерывания принтера. 
  minPage = 0; 
  maxPage = 0; 
  selFromPage = 0; 
  selToPage = 0;
}

    Установив параметры minPage, maxPage, selFromPage и selToPage в нуль, мы заблокируем элементы управления Print Range окна диалога Print. Параметры этой функции представляют собой MinPage, MaxPage, FromPage и ToPage из TPrintDialog::TData.

    MinPage - это минимальное число страниц, которое может распечатать пользователь, MaxPage - это максимальное число страниц, которое может распечатать пользователь, FromPage - номер первой распечатываемой страницы, ToPage - номер последней распечатываемой страницы. Кроме этих четырех параметров TPrintDialog::TData включает Copies, который содержит число копий при печати. Конечно, TPrintDialog - это класс библиотеки OWL, представляющий окно диалога общего вида Print в Windows.

    На следующем шаге мы рассмотрим другой подход к печати.




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