Мастер — это тип листа свойств, который предоставляет простой и эффективный способ руководства пользователям с помощью процедуры.
Мастера — это один из ключей для упрощения взаимодействия с пользователем. Они позволяют выполнять сложную операцию, например конфигурацию приложения, и разбить ее на ряд простых шагов. В каждой точке процесса можно указать описание необходимых элементов управления и отобразить элементы управления, позволяющие пользователю выбирать и вводить текст.
Мастер на самом деле является типом листа свойств. Лист свойств по сути является контейнером для коллекции страниц, где каждая страница является отдельным диалоговым окном. В то время как обычные листы свойств позволяют пользователю получать доступ к любой странице в любое время, мастера представляют страницы в последовательности. Вместо вкладок кнопки используются для перехода вперед и назад. Порядок отображения страниц контролируется приложением и может быть изменен на основе ввода пользователем.
Существует два основных стиля мастера: старый стиль Wizard97 и стиль Aero, представленный в Windows Vista. Иллюстрации см. в разделе "Сведения о листах свойств". (Третий стиль, использующий только флаг PSH_WIZARD или PSH_WIZARD_LITE, представляет простую последовательность листов свойств без заголовков или подложок.)
Примечание
Подложка в контексте мастера — это растровое изображение, которое отображается в левом поле некоторых страниц.
В большинстве этого документа предполагается, что вы реализуете мастер для системы с 5.80 или более поздней версией общих элементов управления. Если вы пытаетесь использовать стиль Wizard97 с более ранними версиями распространенных элементов управления, приложение может скомпилироваться, но оно не будет отображаться должным образом. Дополнительные сведения о создании мастера, совместимого с Wizard97 в более ранних системах, см. в разделе "Мастера обратной совместимости" далее в этом разделе.
Программирование пользовательского интерфейса Windows
Instructions
Реализация мастера
Реализация мастера аналогична реализации регулярного листа свойств. На самом базовом уровне это вопрос настройки одного из следующих флагов или сочетаний флагов в структуре PROPSHEETHEADER , которая определяет лист свойств.
Флаг
Стиль
PSH_WIZARD
Простой мастер без заголовков или растровых изображений.
PSH_WIZARD_LITE
Как и PSH_WIZARD, с некоторыми незначительными различиями в внешнем виде; Например, разделитель над кнопками имеет полную ширину окна.
PSH_WIZARD97
Мастер мастер97 с заголовками (необязательно), растровыми изображениями заголовков и подложками.
PSH_WIZARD | PSH_AEROWIZARD
Мастер Аэро. Мастеры аэро не используют подложки или растровые изображения заголовков. Для них требуется модель однопоточной квартиры (STA).
Базовая процедура реализации мастера выглядит следующим образом:
Создайте шаблон диалогового окна для каждой страницы.
Определите страницы, создав структуру PROPSHEETPAGE для каждой страницы. Эта структура определяет страницу и содержит указатели на шаблон диалогового окна и любые растровые изображения или другие ресурсы.
Определите мастер, создав для него структуру PROPSHEETHEADER .
Передайте структуру PROPSHEETHEADER функции PropertySheet, чтобы отобразить мастер.
Реализуйте процедуры диалогового окна для каждой страницы для обработки сообщений уведомлений из элементов управления страницы и кнопок мастера и обработки других сообщений Windows.
Создание шаблонов диалогового окна
Существует два основных типа страницы мастера: внешний и внутренний. Внешние страницы — это введение (приветствие) и страницы завершения. Все остальные — внутренние страницы.
Шаблоны диалоговых окон внешней страницы
Базовый макет страниц внедрения и завершения идентичен. На следующем рисунке показан пример страницы внедрения Wizard97 с подложкой заполнителя.
Для внешних страниц Wizard97 шаблон диалогового окна — 317x193. Он заполняет все мастера, за исключением подпись и полосы в нижней части, содержащей кнопки "Назад", "Далее" и "Отмена". Левая часть шаблона, зарезервированная для растрового изображения "водяного знака", не должна содержать элементов управления. Подложка указывается в структуре PROPSHEETHEADER мастера и автоматически добавляется на страницу. При разработке шаблона ресурса необходимо разрешить пространство.
При создании растрового изображения водяного знака следует помнить, что диалоговое окно может увеличить размер, если, например, пользователь выбирает большой системный шрифт. Разные языки также обычно имеют разные метрики шрифта. Когда страница растет, область, зарезервированная для подложки, получает пропорционально больше. Однако вы не можете изменить растровое изображение водяного знака и не растянуто растровое изображение, чтобы заполнить большую область. Вместо этого растровое изображение остается в исходном размере в левой верхней части зарезервированной области. Часть большей зарезервированной области, которая не охватывается подложкой, автоматически заполняется цветом верхнего левого пикселя растрового изображения.
Если у вас должны быть точечные изображения разных размеров подложки для разных метрик шрифтов, возможны два возможных решения.
Получите метрики шрифта перед созданием мастера и укажите соответствующее размер растровое изображение водяного знака.
Не указывайте растровое изображение водяного знака при создании мастера. Мастер97 останется пустой областью водяного знака. Затем нарисуйте растровое изображение соответствующего размера в области, зарезервированной для подложки.
Элементы управления можно поместить в область справа от водяного знака, как и для обычного диалогового окна. Цвет фона этой области определяется системой и не требует никаких действий в вашей части. Обычно в этой области помещают два статических элемента управления. Верхняя часть содержит заголовок и использует большой полужирный шрифт (12 точек Verdana Полужирный для Wizard97). Другой, который предназначен для пояснительных текста, использует стандартный шрифт диалогового окна.
Основное различие между страницами внедрения и завершения — это кнопки мастера и текст в статических элементах управления. Страницы введение обычно имеют кнопку "Далее " и "Назад " с включенным только кнопкой "Далее ". Страницы завершения включают кнопку "Назад ", а кнопка "Далее " заменена кнопкой "Готово ".
Примечание
В мастерах Аэро кнопка "Назад" заменяется кнопкой со стрелкой на панели подпись.
Вы можете изменить текст на кнопке "Готово ", отправив мастеру сообщение PSM_SETFINISHTEXT . По умолчанию кнопка "Готово" не включает акселератор клавиатуры. Чтобы определить акселератор клавиатуры, включите амперсанд в текстовую строку, передаваемую в PSM_SETFINISHTEXT. Например, "&Finish" определяет "F" в качестве акселератора клавиатуры.
Шаблоны диалоговых окон внутренней страницы
Внутренние страницы имеют несколько отличается от внешнего вида страниц. На следующем рисунке показана пример страницы интерьера Wizard97 с растровым изображением заголовка заполнителя.
Область заголовка в верхней части страницы обрабатывается листом свойств, поэтому он не включен в шаблон. Содержимое заголовка указывается в структуре PROPSHEETPAGE страницы и структуре PROPSHEETHEADER мастера. Так как внутренняя страница должна соответствовать заголовку и кнопкам, шаблон диалогового окна Wizard97 составляет 317x143, что несколько меньше шаблона для внешних страниц.
На следующем рисунке показан мастер Аэро, созданный на основе того же шаблона.
Определение страниц мастера
После создания шаблонов диалоговых окон и связанных ресурсов, таких как растровые изображения и строковые таблицы, можно создать страницы листа свойств. Процедура аналогична процедуре для стандартных листов свойств. Сначала заполните соответствующие элементы структуры PROPSHEETPAGE. (Некоторые члены относятся к мастерам.) Затем вызовите функцию CreatePropertySheetPage, чтобы создать дескриптор HPROPSHEETPAGE страницы.
Задайте этот флаг для внешних страниц в Мастер97. Заголовок не отображается, и можно показать подложку.
PSP_USEHEADERTITLE
Задайте этот флаг для внутренних страниц, чтобы поместить заголовок в область заголовка в Wizard97 или в верхней части клиентской области в мастере Аэро.
PSP_USEHEADERSUBTITLE
Задайте этот флаг для внутренних страниц, чтобы поместить подзаголовок в область заголовка в Мастер97.
Если вы установили PSP_USEHEADERTITLE или PSP_USEHEADERSUBTITLE, назначьте текст заголовка и субтитра членам pszHeaderTitle и pszHeaderSubtitle соответственно. При назначении текстовых строк членам структур PROPSHEETPAGE и PROPSHEETHEADER можно назначить указатель строки или использовать макрос MAKEINTRESOURCE для назначения значения из строкового ресурса. Строковый ресурс загружается из модуля, указанного в элементе hInstance структуры PROPSHEETHEADER мастера.
Альтернативным способом создания страниц является использование отдельных структур PROPSHEETPAGE для каждой страницы и создание массива структур. Этот массив используется вместо массива дескрипторов HPROPSHEETPAGE при создании листа свойств. Использование отдельных структур PROPSHEETPAGE устраняет необходимость вызова CreatePropertySheetPage, но использует больше памяти. В противном случае нет существенной разницы между двумя подходами.
В следующем примере определяется страница "Внутренний мастер97", назначая значения структуре PROPSHEETPAGE. В этом примере заголовок, подзаголовок и шаблон диалогового окна страницы определяются идентификаторами ресурсов. Затем вызывается функция CreatePropertySheetPage, чтобы создать дескриптор HPROPSHEETPAGE страницы. Так как она будет второй страницей для отображения, дескриптор назначается массиву дескрипторов, ahpsp с индексом 1.
// g_hInstance is the global HINSTANCE of the application.
// IntPage1DlgProc is the dialog procedure for this page.
// ahpsp is an array of HPROPSHEETPAGE handles.
PROPSHEETPAGE psp = { sizeof(psp) };
psp.hInstance = g_hInstance;
psp.dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
psp.lParam = (LPARAM) &wizdata;
psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TITLE1);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUBTITLE1);
psp.pszTemplate = MAKEINTRESOURCE(IDD_INTERIOR1);
psp.pfnDlgProc = IntPage1DlgProc;
ahpsp[1] = CreatePropertySheetPage(&psp);
Пользовательские данные страницы
При создании страницы можно назначить пользовательские данные с помощью элемента lParam структуры PROPSHEETPAGE, обычно назначая ему указатель на определяемую пользователем структуру.
При первом выборе страницы процедура диалогового окна получает сообщение WM_INITDIALOG . Значение lParam сообщения указывает на копию структуры PROPSHEETPAGE страницы, из которой можно получить пользовательские данные. Затем эти данные можно хранить в последующих сообщениях с помощью SetWindowLongPtr с GWL_USERDATA в качестве параметра индекса. Несколько страниц могут иметь указатель на одни и те же данные, и любые изменения данных, сделанные одной страницей, доступны другим страницам в их процедурах диалога.
Определение листа свойств мастера
Как и в обычных листах свойств, вы определяете лист свойств мастера, заполняя элементы структуры PROPSHEETHEADER. Эта структура позволяет указать страницы, составляющие мастер и порядок по умолчанию, в котором они отображаются, а также несколько связанных параметров. Затем вы запустите мастер, вызвав функцию PropertySheet .
В стиле Wizard97 член pszCaption структуры PROPSHEETHEADER игнорируется. Вместо этого мастер отображает подпись, указанные в шаблоне диалогового окна текущей страницы. Если шаблон отсутствует подпись, отображается подпись из предыдущей страницы. Таким образом, чтобы отобразить одинаковые подпись на всех страницах, укажите подпись в шаблоне для вводной страницы.
В стиле "Мастер аэро" диалоговое окно подпись взято из pszCaption.
В следующем примере присваивается значения psh, структуре PROPSHEETHEADER и вызывается функция PropertySheet для запуска мастера. Мастер стилей Wizard97 содержит как подложку, так и графические заголовки, указанные идентификаторами ресурсов. Массив ahpsp содержит все дескрипторЫ HPROPSHEETPAGE и определяет порядок по умолчанию, в котором они отображаются.
// g_hInstance is the global HINSTANCE of the application.
// ahpsp is an array of HPROPSHEETPAGE handles.
PROPSHEETHEADER psh = { sizeof(psh) };
psh.hInstance = g_hInstance;
psh.hwndParent = NULL;
psh.phpage = ahpsp;
psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
psh.pszbmHeader = MAKEINTRESOURCE(IDB_BANNER);
psh.nStartPage = 0;
psh.nPages = 4;
PropertySheet(&psh);
Процедура диалогового окна
На каждой странице мастера требуется процедура диалогового окна для обработки сообщений Windows, особенно уведомлений из его элементов управления и мастера. Три сообщения, которые почти все мастера должны иметь возможность обрабатывать, являются WM_INITDIALOG, WM_DESTROY и WM_NOTIFY.
Сообщение WM_NOTIFY получено до отображения страницы и при нажатии любой из кнопок мастера. Параметр lParam сообщения — это указатель на структуру заголовка NMHDR. Идентификатор уведомления содержится в элементе кода структуры. Четыре уведомления, которые большинство мастеров должны обрабатывать, приведены ниже.
При первом отображении страницы процедура диалогового окна получает WM_INITDIALOG сообщение. Обработка этого сообщения позволяет мастеру выполнять все необходимые задачи инициализации, такие как хранение пользовательских данных или настройка шрифтов.
При уничтожении листа свойств вы получите сообщение WM_DESTROY. Мастер автоматически уничтожается системой, но обработка этого сообщения позволяет выполнять любую необходимую очистку.
Обработка PSN_SETACTIVE
Код уведомления PSN_SETACTIVE отправляется каждый раз, когда страница будет видна. При первом посещении страницы PSN_SETACTIVE следует WM_INITDIALOG сообщению. Если страница впоследствии пересматривается, она получает только уведомление PSN_SETACTIVE. Обычно это уведомление обрабатывается для инициализации данных для страницы и включения соответствующих кнопок.
По умолчанию мастер отображает кнопки "Назад", "Далее" и "Отмена " со всеми включенными кнопками. Чтобы отключить кнопку или отобразить "Готово ", а не "Далее", необходимо отправить сообщение PSM_SETWIZBUTTONS . После отправки этого сообщения состояние кнопок сохраняется до изменения другим PSM_SETWIZBUTTONS сообщением, даже если выбрана новая страница. Как правило, все обработчики PSN_SETACTIVE отправляют это сообщение, чтобы убедиться, что каждая страница имеет правильное состояние кнопки.
Состояние кнопки можно изменить в любое время. Например, может потребоваться, чтобы начальная кнопка "Далее " была отключена. После ввода всех необходимых сведений пользователь может отправить еще одно сообщение PSM_SETWIZBUTTONS, чтобы включить кнопку "Далее" и разрешить пользователю перейти на следующую страницу.
Следующий фрагмент кода использует макрос PropSheet_SetWizButtons для включения кнопок "Назад" и "Далее" на внутренней странице перед отображением.
case WM_NOTIFY :
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
...
case PSN_SETACTIVE :
...
// This is an interior page.
PropSheet_SetWizButtons(hwnd, PSWIZB_NEXT | PSWIZB_BACK);
...
}
...
}
Обработка PSN_WIZNEXT, PSNWIZBACK и PSN_WIZFINISH
При нажатии кнопки "Далее" или "Назад" вы получаете код уведомления PSN_WIZNEXT или PSN_WIZBACK. По умолчанию мастер автоматически переходит на следующую или предыдущую страницу в том порядке, который определяется при создании листа свойств. Распространенной причиной обработки этих уведомлений является предотвращение переключения страниц пользователем или переопределение порядка страниц по умолчанию.
case PSN_WIZNEXT :
...
// Go straight to the completion page.
SetWindowLong(hwnd, DWL_MSGRESULT, IDD_FINISH);
return TRUE;
...
После нажатия кнопки "Готово" или "Отмена" вы получаете код уведомления PSN_WIZFINISH или PSN_RESET соответственно. При нажатии любой из этих кнопок мастер автоматически уничтожается системой. Однако эти уведомления можно обрабатывать, если необходимо выполнить задачи очистки перед уничтожением мастера. Чтобы предотвратить уничтожение мастера при получении уведомления PSN_WIZFINISH, вызовите SetWindowLong со значением DWL_MSGRESULT значение TRUE и возвращает значение TRUE. Например:
case PSN_WIZFINISH :
...
// Not finished yet.
SetWindowLong(hwnd, DWL_MSGRESULT, TRUE);
return TRUE;
...
Мастера обратной совместимости
В предыдущем разделе предполагается, что вы реализуете мастер для системы с версией 5 или более поздними общими элементами управления.
Если вы пишете мастер для систем с более ранними версиями общих элементов управления, многие функции, описанные в предыдущем разделе, не будут доступны. Ряд членов структур PROPSHEETHEADER и PROPSHEETPAGE, используемых стилем Wizard97, поддерживаются только общими элементами управления версии 5 и более поздних версий. Однако по-прежнему можно реализовать мастер обратной совместимости с внешним видом, похожим на стиль Wizard97. Для этого необходимо явно реализовать следующее:
Добавьте рисунок водяного знака в шаблон диалогового окна для страниц внедрения и завершения.
Сделайте все шаблоны одинаковым размером. Для внутренних страниц нет отдельной системной области заголовков.
Явным образом создайте область заголовка внутренней страницы в шаблонах.
Не используйте рисунок заголовка, так как он может конфликтуть с заголовком или подзаголовоком, если мастер изменяет размер.
Полное обсуждение вопросов разработки для Wizard97 см . в спецификации Wizard97 в другом месте пакета SDK для Windows. В этом документе приведены рекомендации по таким аспектам, как измерения для диалоговых окон, размеров растровых изображений и цветов, а также размещение элементов управления.
Do you want to know an effective way to let a user perform the installation steps of your extension by using an efficient and accessible wizard in Microsoft Dynamics 365 Business Central? If so, this module is for you. In this module, you'll learn how to add a wizard page by using a navigate page object.