В статье объясняется, как можно модифицировать стандартный дилог печати и использовать его в приложении 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. |