Как изменить стандартный диалог печати
В статье объясняется, как можно модифицировать
стандартный дилог печати и использовать его в
приложении MFC. Настройка диалога печати, влечёт
за собой изменение шаблона стандартного диалога
печати Window, при этом, Вы можете добавлять новые
элементы управления и/или удалять существующие.
Итак, по шагам
- Копируем шаблон диалога PRINTDLGORD из COMMDLG.RC в .RC файл
приложения. (В Visual C++ 4.x и 5.0, этот блок шаблона
постоянно находится в файле INCLUDE\PRNSETUP.DLG). Для
этого сделайте:
- При помощи редактора ресурсов, откройте
MSVC\MFC\SAMPLES\APSTUDIO\COMMDLG.RC и ресурсный файл Вашего
приложения. Для 32-bit Visual C++ этот файл находится в
\msdev\samples\mfc\general\clipart. Для Visual C++ 6.0, Вы можете найти
этот файл в ..\samples\vc98\mfc\general\clipart на диске MSDN,
который поставляется с Visual C++ 6.0.
Если Вы используете Visual C++ 4.x или 5.0, то добавьте
строку #include "windows.h" в начало файла
INCLUDE\PRNSETUP.DLG. Сохраните и закройте файл. Откройте
его заново как "Ресурс". (См. "Open As" в
диалоговом окне File Open.)
- В окне проводника ресурсов файла "from",
выберите ресурс диалога PRINTDLGORD (id 1538).
- Если удерживать клавишу CTRL, то можно перетащить
ресурс в окно проводника ресурсов файла "to".
ЗАМЕЧАНИЕ: Если перетащить ресурс не удерживая
клавишу CTRL, то ресурс перемещён вместо того,
чтобы быть скопированным.
- Сделайте необходимые изменения в скопированном
шаблоне диалога.
ЗАМЕЧАНИЕ: Не один из элементов управления в
изначальном шаблоне диалога не должен быть
удалён. Удаление контролов вызовет проблемы в
функции DoDataExchange класса CPrintDialog. Вместо этого,
ненужный элемент управления надо запретить и/или
скрыть в переопределённой функции OnInitDialog Вашего
класса, наследованного от CPrintDialog.
- Чтобы добавить C++ класс (скажем, CMyPrintDialog) для
этого шаблона диалога, воспользуйте визардом (ClassWizard).
Наследуйте этот новый класс от CDialog с PRINTDLGORD в
качестве диалогового ID. (ЗАМЕЧАНИЕ: В Visual C++ 4.x и 5.0
этот класс может быть наследован прямо от
CPrintDialog.)
- Измените все ссылки с CDialog на CPrintDialog как в
заголовочных файлах, так и в исходниках вновь
созданного класса. (Если Вы наследовали свой
класс от CPrintDialog, то данный шаг необязателен.)
- Поскольку конструктор CPrintDialog отличается от
CDialog, то измените конструктор CMyPrintDialog используя
следующий код:
(ЗАМЕЧАНИЕ: Если Вы наследовали свой класс от
CPrintDialog, то данный шаг необязателен.) // Заголовочный файл CMyPrintDialog
class CMyPrintDialog : public CPrintDialog
{
// Construction
public:
// Параметры следующего конструктора очень похожи на
// CPrintDialog. Обратите внимание на отличие второго аргумента.
CMyPrintDialog(BOOL bPrintSetupOnly,
// TRUE для настройки печати, FALSE для диалога печати
DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES |
PD_HIDEPRINTTOFILE,
// Комбинация флагов. Полное описание возможных
// флагов для структуры PRINTDLG находится в
// документации Windows SDK.
CWnd* pParentWnd = NULL);
// Остатки объявления класса
...
DECLARE_MESSAGE_MAP()
};
// Исходник для CMyPrintDialog
CMyPrintDialog::CMyPrintDialog(BOOL bPrintSetupOnly,
DWORD dwFlags /* = PD_ALLPAGES | PD_USEDEVMODECOPIES |
PD_HIDEPRINTTOFILE */,
CWnd* pParentWnd /* = NULL */)
: CPrintDialog(bPrintSetupOnly, dwFlags, pParentWnd)
{
//{{AFX_DATA_INIT(CMyPrintDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
- Измените класс, наследованный от CView (скажем,
CMyView) используя следующий код:
// Исходник для вида (скажем, в myview.cpp)
...
#include "myprintd.h" // Включаем заголовочный файл CMyPrintDialog
...
// Переопределяем OnPreparePrinting класса, наследованного от
// CView как показано ниже:
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
// Удаляем объект CPrintDialog, созданный в конструкторе
// CPrintInfo, и подставляем его нашим диалогом печати.
delete pInfo->m_pPD;
// Создаём наш диалог печати.
pInfo->m_pPD = new CMyPrintDialog(FALSE);
// Устанавливаем диапазон страницы.
pInfo->m_pPD->m_pd.nMinPage = 1; // one based page numbers
pInfo->m_pPD->m_pd.nMaxPage = 0xffff; // количество страниц неизвестно
// Изменяем структуру PRINTDLG, чтобы использовать наш диалог
// печати.
pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
pInfo->m_pPD->m_pd.lpPrintTemplateName =
MAKEINTRESOURCE(PRINTDLGORD);
// Устанавливаем флаги структуры PRINTDLG как показано ниже,
// иначе изменения не будут иметь эффекта
pInfo->m_pPD->m_pd.Flags |= PD_ENABLEPRINTTEMPLATE;
// Более подробно об этих флагах можно узнать из документации SDK
// по структуре PRINTDLG.
return DoPreparePrinting(pInfo);
}
ССЫЛКИ
Более подробную информацию о структуре PRINTDLG
можно получить в документации Windows SDK, а так же в
документации MFC можно подробнее ознакомиться с
OnPreparePrinting и CPrintDialog.
|