Сведения о страницах свойств

Лист свойств — это окно, позволяющее пользователю просматривать и изменять свойства элемента. Например, приложение электронной таблицы может использовать лист свойств, чтобы разрешить пользователю задавать свойства шрифта и границы ячейки или просматривать и задавать свойства устройства, например диска, принтера или мыши.

В этом разделе рассматриваются следующие разделы.

Основные сведения о листе свойств

Чтобы реализовать листы свойств в приложении, добавьте в проект файл заголовка Prsht.h. Prsht.h содержит все идентификаторы, используемые с листами свойств.

Лист свойств содержит одну или несколько перекрывающихся дочерних окон, называемых страницами, каждый из которых содержит окна управления для задания группы связанных свойств. Например, страница может содержать элементы управления для настройки свойств шрифта элемента, включая стиль типа, размер точки, цвет и т. д. Каждая страница имеет вкладку, которую пользователь может выбрать, чтобы переместить страницу на передний план листа свойств. Например, приложение панели управления date-Time отображает следующий лист свойств.

screen shot of a property sheet with two tabs, one of which shows a clock and a monthly calendar control

Стандартный лист свойств с несколькими страницами табуляции позволяет пользователю случайный доступ ко всем свойствам. Если лучше иметь свойства, заданные в последовательности, можно использовать мастер.

Диалоговое окно "Лист свойств"

Лист свойств и страницы, содержащиеся в нем, фактически являются диалоговым окнами. Лист свойств — это системное диалоговое окно, которое управляет страницами и предоставляет общий контейнер для них. Диалоговое окно листа свойств может быть модальным или без режима. Он включает кадр, строку заголовка и четыре кнопки: ОК, Отмена, Применение и (необязательно) Справка. Процедуры диалогового окна для страниц получают коды уведомлений в виде WM_NOTIFY сообщений, когда пользователь нажимает кнопки.

Примечание.

Не все сведения в этом разделе применяются к мастерам, которые имеют несколько другой внешний вид и поведение. Например, мастера имеют другой набор кнопок и нет вкладок. Дополнительные сведения см. в разделе "Создание мастеров".

Каждая страница в листе свойств — это диалоговое окно без режима приложения, которое управляет окнами управления, используемыми для просмотра и редактирования свойств элемента. Вы предоставляете шаблон диалогового окна, используемый для создания каждой страницы, а также процедуры диалогового окна, которая управляет элементами управления и задает свойства соответствующего элемента.

Лист свойств отправляет коды уведомлений в процедуру диалогового окна для страницы при получении или потере активации, а также при нажатии кнопки "ОК", "Отмена", "Применить" или "Справка". Уведомления отправляются в виде WM_NOTIFY сообщений. Параметр lParam — это адрес структуры NMHDR, которая включает дескриптор окна в диалоговое окно листа свойств.

Для некоторых кодов уведомлений требуется, чтобы страница возвращала значение TRUE или FALSE в ответ на сообщение WM_NOTIFY . Для этого страница должна использовать функцию SetWindowLong, чтобы задать значение DWL_MSGRESULT для диалогового окна страницы значение TRUE или FALSE.

Страницы

Лист свойств должен содержать по крайней мере одну страницу, но не может содержать больше значения MAXPROPPAGES , как определено в файлах заголовков Windows. Каждая страница имеет отсчитываемый от нуля индекс, который лист свойств назначается в соответствии с порядком добавления страницы на лист свойств. Индексы используются в сообщениях, отправляемых на лист свойств.

Страница свойств может содержать вложенный диалог. Если это так, необходимо включить стиль WS_EX_CONTROLPARENT для диалогового окна верхнего уровня и вызвать функцию IsDialogMessage с дескриптором родительского диалогового окна. Это гарантирует, что пользователь может использовать mnemonics и клавиши навигации диалогового окна для перемещения фокуса в элементы управления в вложенном диалоговом окне.

Каждая страница имеет соответствующий значок и метку. Лист свойств создает вкладку для каждой страницы и отображает значок и метку на вкладке. Ожидается, что все страницы листов свойств будут использовать неболдный шрифт. Чтобы убедиться, что шрифт не является полужирным, укажите стиль DS_3DLOOK в шаблоне диалогового окна.

Процедура диалогового окна для страницы не должна вызывать функцию EndDialog . Это приведет к уничтожению всего листа свойств, а не только страницы.

Минимальный размер страницы листа свойств составляет 212 диалоговых единиц по горизонтали и 114 единиц диалоговых окон по вертикали. Если диалоговое окно страницы меньше этого, страница будет увеличена, пока она не соответствует минимальному размеру. Файл заголовка Prsht.h содержит три набора рекомендуемых размеров для страниц листов свойств, как показано в следующей таблице.

Размер Description
PROP_SM_CXDLG Ширина в диалоговых единицах на небольшой странице листа свойств.
PROP_SM_CYDLG Высота в диалоговых блоках на небольшой странице листа свойств.
PROP_MED_CXDLG Ширина в диалоговых единицах страницы листа свойств среднего размера.
PROP_MED_CYDLG Высота в диалоговых блоках страницы листа свойств среднего размера.
PROP_LG_CXDLG Ширина в диалоговых единицах страницы листа большого свойства.
PROP_LG_CYDLG Высота в диалоговых блоках страницы большого листа свойств.

Использование этих рекомендуемых размеров поможет обеспечить визуальную согласованность между приложением и другими приложениями Microsoft Windows.

В редакторе ресурсов Microsoft Visual Studio можно создать страницу соответствующего размера в диалоговом окне "Добавление ресурса ". Разверните узел диалогового окна и выберите IDD_PROPPAGE_LARGE, IDD_PROPPAGE_MEDIUM или IDD_PROPPAGE_SMALL.

Лист свойств автоматически размером, чтобы разместить самую большую страницу.

Создание листа свойств

Перед созданием листа свойств необходимо определить одну или несколько страниц. Это включает заполнение структуры PROPSHEETPAGE сведениями о странице — его значком, меткой, шаблоном диалогового окна, процедурой диалогового окна и т. д., а затем указанием адреса структуры в вызове функции CreatePropertySheetPage. Функция возвращает дескриптор типу HPROPSHEETPAGE, который однозначно идентифицирует страницу.

Чтобы создать лист свойств, необходимо указать адрес структуры PROPSHEETHEADER в вызове функции PropertySheet. Структура определяет значок и заголовок листа свойств, а также содержит адрес массива дескрипторов HPROPSHEETPAGE, которые вы получаете с помощью CreatePropertySheetPage. Когда PropertySheet создает лист свойств, он включает страницы, определенные в массиве. Страницы отображаются на листе свойств в том же порядке, что и в массиве.

Другой способ назначить страницы листу свойств — указать массив структур PROPSHEETPAGE вместо массива дескрипторов HPROPSHEETPAGE. В этом случае PropertySheet создает дескриптор для страниц, прежде чем добавлять их на лист свойств.

При создании страницы процедура диалогового окна получает сообщение WM_INITDIALOG . Параметр lParam сообщения — это указатель на копию структуры PROPSHEETPAGE, определяемой при создании страницы. В частности, при создании страницы член структуры lParam можно использовать для передачи определяемых приложением сведений в процедуру диалогового окна. За исключением члена lParam , эта структура должна рассматриваться как доступная только для чтения. Изменение ничего, кроме lParam , будет иметь непредсказуемые последствия.

Когда система впоследствии передает копию структуры PROPSHEETPAGE страницы приложению, она использует тот же указатель. Все изменения структуры будут переданы вместе. Так как член lParam игнорируется системой, его можно изменить для отправки информации другим частям приложения. Например, можно использовать lParam для передачи информации в функцию обратного вызова PropSheetPageProc страницы.

PropertySheet автоматически задает размер и начальную позицию листа свойств. Позиция основана на позиции окна владельца, а размер основан на самой большой странице, указанной в массиве страниц при создании листа свойств. Если вы хотите, чтобы страницы соответствовали ширине четырех кнопок в нижней части листа свойств, задайте ширину самой широкой страницы 190 диалоговых единиц.

Размер листа свойств вычисляется из свойств ширины и высоты шаблона диалогового окна в файле ресурсов. Дополнительные сведения см. в разделе "Ресурс DIALOG" или "Ресурс DIALOGEX". Обратите внимание, что по соображениям совместимости измерения вычисляются относительно шрифта MS Shell Dlg, а не шрифта, используемого страницей. Если вы разрабатываете страницу, использующую другой шрифт, можно использовать одно из следующих предложений.

  • Измените размеры шаблона диалогового окна, чтобы компенсировать разницу в размере между шрифтом MS Shell Dlg и шрифтом, который фактически используется страницей. Например, если выбрать шрифт, который в два раза больше, чем MS Shell Dlg, то задайте для свойства ширины шаблона диалогового окна два раза больше обычного использования.
  • Используйте шаблон DIALOGEX и задайте стиль диалогового окна DS_SHELLFONT. В этом случае диспетчер листов свойств интерпретирует размеры шаблона диалогового окна относительно шрифта, используемого шаблоном диалога.

Добавление и удаление страниц

После создания листа свойств приложение может добавить страницу в конец существующего набора страниц, отправив PSM_ADDPAGE сообщение. Чтобы вставить страницу между существующими страницами, отправьте PropSheet_InsertPage сообщение. Обратите внимание, что размер листа свойств не может измениться после его создания. Все добавленные или вставленные страницы не должны быть больше, чем самая большая страница в настоящее время на листе свойств. Чтобы удалить страницу, отправьте сообщение PSM_REMOVEPAGE.

При определении страницы можно указать адрес функции обратного вызова PropSheetPageProc , вызываемой листом свойств при создании или удалении страницы. Использование PropSheetPageProc позволяет выполнять операции инициализации и очистки отдельных страниц.

Примечание.

Во время управления списком страниц выполняется ряд сообщений и один вызов функции. Хотя это действие происходит, попытка изменить список страниц будет иметь непредсказуемые результаты. Не добавляйте, вставляйте или удаляйте страницы в реализации PropSheetPageProc или обрабатывайте следующие уведомления и сообщения Windows.

Если возникает необходимость изменить страницу листа свойств при обработке одного из этих сообщений или во время работы PropSheetPageProc , опубликуйте частное сообщение Windows. Приложение не получит это сообщение до тех пор, пока диспетчер листов свойств завершит свои задачи, в какой момент будет безопасно изменять список страниц.

При уничтожении листа свойств он автоматически уничтожает все страницы, добавленные в него. Страницы уничтожаются в обратном порядке из того, что указано в массиве, используемом для создания страниц. Чтобы уничтожить страницу, созданную функцией CreatePropertySheetPage, но не добавленную на лист свойств, используйте функцию DestroyPropertySheetPage.

Заголовки и метки страницы листа свойств

Вы указываете название листа свойств в структуре PROPSHEETHEADER , используемой для создания листа свойств. Если элемент dwFlags включает значение PSH_PROPTITLE, лист свойств добавляет суффикс "Свойства" или префикс "Свойства для", в зависимости от версии. Вы можете изменить заголовок после создания листа свойств с помощью сообщения PSM_SETTITLE. В мастере Аэро это сообщение можно использовать для динамического изменения заголовка внутренней страницы.

По умолчанию лист свойств использует строку имени, указанную в шаблоне диалогового окна, в качестве метки для страницы. Можно переопределить строку имени, включив значение PSP_USETITLE в элемент dwFlags структуры PROPSHEETPAGE, которая определяет страницу. При указании PSP_USETITLE элемент pszTitle должен содержать адрес строки метки для страницы.

Активация страницы

Лист свойств может одновременно содержать только одну активную страницу. Страница с активацией находится на переднем плане перекрывающегося стека страниц. Пользователь активирует страницу, выбрав ее вкладку; приложение активирует страницу с помощью сообщения PSM_SETCURSEL.

Лист свойств отправляет код уведомления PSN_KILLACTIVE на страницу, которая будет терять активацию. В ответ на страницу необходимо проверить все изменения, внесенные пользователем на страницу. Если для страницы требуются дополнительные входные данные пользователя перед потерей активации, используйте функцию SetWindowLong, чтобы задать значение DWL_MSGRESULT страницы значение TRUE. Кроме того, страница должна отображать окно сообщения, описывающее проблему и предоставляющее рекомендуемое действие. Установите для DWL_MSGRESULTзначение FALSE , если это нормально, чтобы потерять активацию.

Перед тем как страница, получающая активацию, отображается, лист свойств отправляет код уведомления PSN_SETACTIVE на страницу. Страница должна отвечать путем инициализации его окон управления.

Кнопка справки

Листы свойств могут отображать две кнопки справки: кнопку справки листа свойств, отображаемую в нижней части кадра, рядом с кнопкой "Отмена отмены"// и стандартной кнопкой подпись панели, которая предоставляет контекстно-конфиденциальную справку.

Кнопка справки по листу свойств является необязательной и может быть включена на странице по страницам. Чтобы отобразить кнопку справки по листу свойств для одной или нескольких страниц:

  • Задайте флаг PSH_HASHELP в элементе dwFlags структуры PROPSHEETHEADER листа свойств.
  • Для каждой страницы, отображающей кнопку справки, задайте флаг PSP_HASHELP в элементе dwFlags структуры PROPSHEETPAGE страницы.

Когда пользователь нажимает кнопку справки, активная страница получает код уведомления PSN_HELP . Страница должна отвечать, отображая сведения справки, обычно вызывая функцию WinHelp .

Удаление кнопки справки панели заголовков

Кнопка справки подпись панели отображается по умолчанию, поэтому контекстно-конфиденциальная справка всегда доступна для кнопок "ОК/Отмена", "Применить". Однако при необходимости эту кнопку можно удалить. Чтобы удалить кнопку справки подпись панели свойств листа свойств, выполните приведенные ниже действия.

  • Для версий общих элементов управления до версии 5.80 необходимо реализовать функцию обратного вызова листа свойств.
  • Для 5.80 и более поздних версий общих элементов управления можно просто задать флаг PSH_NOCONTEXTHELP в элементе dwFlags структуры PROPSHEETHEADER листа свойств. Однако если вам нужна обратная совместимость с более ранними версиями общих элементов управления, необходимо реализовать функцию обратного вызова.

Чтобы реализовать функцию обратного вызова листа свойств, которая удаляет кнопку справки подпись панели:

  • Задайте флаг PSH_USECALLBACK в элементе dwFlags структуры PROPSHEETHEADER листа свойств.
  • Задайте элемент pfnCallBack структуры PROPSHEETHEADER, чтобы указать функцию обратного вызова.
  • Реализуйте функцию обратного вызова. Когда эта функция получает сообщение PSCB_PRECREATE , он также получит указатель на шаблон диалогового окна листа свойств. Удалите стиль DS_CONTEXTHELP из этого шаблона.

В следующем примере показано, как реализовать такую функцию обратного вызова:

int CALLBACK RemoveContextHelpProc(HWND hwnd, UINT message, LPARAM lParam)
{
    switch (message) 
    {
    case PSCB_PRECREATE:
        // Remove the DS_CONTEXTHELP style from the
        // dialog box template
        if (((LPDLGTEMPLATEEX)lParam)->signature ==    
           0xFFFF)
           {
            ((LPDLGTEMPLATEEX)lParam)->style 
            &= ~DS_CONTEXTHELP;
        }
        else {
            ((LPDLGTEMPLATE)lParam)->style 
            &= ~DS_CONTEXTHELP;
        }
        return TRUE;
    }
    return TRUE;
}

Если структура DLGTEMPLATEEX не определена, включите следующее объявление:

#include <pshpack1.h>

typedef struct DLGTEMPLATEEX
{
    WORD dlgVer;
    WORD signature;
    DWORD helpID;
    DWORD exStyle;
    DWORD style;
    WORD cDlgItems;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATEEX, *LPDLGTEMPLATEEX;

#include <poppack.h>

ОК, отмена и применение кнопок

Кнопки "ОК" и "Применить" похожи. Как на страницах листа свойств, так и для проверки и применения изменений свойств, внесенных пользователем. Единственное различие заключается в том, что нажатие кнопки "ОК" приводит к уничтожению листа свойств после применения изменений.

Когда пользователь нажимает кнопку "ОК" или "Применить", лист свойств отправляет уведомление PSN_KILLACTIVE на активную страницу, предоставляя ему возможность проверить изменения пользователя. Если изменения допустимы, страница должна вызвать функцию SetWindowLong с значением DWL_MSGRESULT, заданным значением FALSE. Если изменения пользователя недопустимы, страница должна задать DWL_MSGRESULTзначение TRUE и отобразить диалоговое окно, информирующее пользователя о проблеме. Страница остается активной до тех пор, пока не будет задано DWL_MSGRESULT значение FALSE в ответ на сообщение PSN_KILLACTIVE.

После ответа страницы на уведомление PSN_KILLACTIVE путем задания DWL_MSGRESULT значение FALSE лист свойств отправляет на каждую страницу уведомление PSN_APPLY. Когда страница получает это уведомление, она должна применить новые свойства к соответствующему элементу. Чтобы указать на лист свойств, что изменения действительны для страницы, вызовите SetWindowLong с DWL_MSGRESULT для параметра PSNRET_NOERROR. Если изменения недопустимы для страницы, верните ошибку. Это предотвращает уничтожение листа свойств и возвращает фокус на страницу, которая получила уведомление PSN_APPLY или страницу, которая была фокусирована при нажатии кнопки "Применить ". Чтобы вернуть ошибку и указать, какая страница будет получать фокус, задайте DWL_MSGRESULT одно из следующих значений.

  • PSNRET_INVALID. Лист свойств не будет уничтожен, и фокус будет возвращен на эту страницу.
  • PSNRET_INVALID_NOCHANGEPAGE. Лист свойств не будет уничтожен, и фокус будет возвращен на страницу, которая была фокусирована при нажатии кнопки.

Приложение может использовать сообщение PSM_APPLY для имитации выбора кнопки "Применить".

Кнопка "Применить" изначально отключается, когда страница становится активной, указывая на то, что для применения изменений свойств еще нет. Когда страница получает входные данные через один из его элементов управления, указывающих, что пользователь редактировал свойство, страница должна отправлять сообщение PSM_CHANGED на лист свойств. Сообщение приводит к включению кнопки "Применить ". Если пользователь впоследствии нажимает кнопку "Применить" или "Отмена", страница должна повторно инициализировать свои элементы управления, а затем отправить сообщение PSM_UNCHANGED, чтобы снова отключить кнопку "Применить".

Иногда кнопка "Применить" приводит к изменению страницы на листе свойств, и изменение не может быть отменено. В этом случае страница должна отправить PSM_CANCELTOCLOSE сообщение на лист свойств. Сообщение приводит к изменению текста кнопки "ОК " на "Закрыть", указывая, что примененные изменения не могут быть отменены.

Иногда страница вносит изменения в конфигурацию системы, требующую перезапуска Windows или перезагрузки системы, прежде чем изменение может вступить в силу. После внесения такого изменения страница должна отправить PSM_RESTARTWINDOWS или PSM_REBOOTSYSTEM сообщение на лист свойств. Эти сообщения приводят к тому, что функция PropertySheet возвращает значение ID_PSRESTARTWINDOWS или ID_PSREBOOTSYSTEM после уничтожения листа свойств.

Когда пользователь нажимает кнопку "Отмена", лист свойств отправляет код уведомления PSN_RESET на все страницы, указывая, что лист свойств будет уничтожен. Страница должна использовать уведомление для выполнения операций очистки.

Мастеры

Мастер — это особый тип листа свойств. Мастера предназначены для представления страниц по одному за раз в последовательности, управляемой приложением. Вместо выбора из группы страниц, щелкнув вкладку, пользователи перемещаются вперед и назад по последовательности, по одной странице за раз, нажимая кнопки. Например, на следующем снимке экрана показана страница приветствия мастера добавления оборудования:

screen shot of the welcome page of a wizard

На следующем снимке экрана показана первая страница мастера Аэро, новый стиль, представленный в Windows Vista.

screen shot of the first page of an aero wizard

См. раздел " Создание мастеров " для полного обсуждения мастеров.