Элементы управления Windows XP

=== Элементы управления Windows XP ===
В Delphi 7 впервые появилась возможность настраивать пользовательский интерфейс приложений для использования в Windows XP. Для этого в состав ресурсов приложения должен включаться манифест Windows XP. Это дополнение призвано обеспечить корректное взаимодействие элементов управления приложения с системной библиотекой ComCtl32.dll версии 6, используемой в Windows XP. Собственно все особенности работы приложений под управлением Windows XP вызваны именно появлением новой версии этой библиотеки. Впрочем, об этом подробно рассказывается ниже. 
ID: 00390
=== Пользовательский интерфейс Windows XP ===
При первом знакомств с Windows XP сразу же обращаешь внимание на существенные изменения в оформлении пользовательскою интерфейса этой операционной системы. Все нововведения основаны на использовании нового способа отрисовки элементов управления, который реализован в системной динамической библиотеке ComCtl32.dll версии 6. Эта библиотека входит в состав операционной системы Windows XP. 
Примечание 
Обратите внимание, что все более ранние операционные системы фирмы Microsoft используют ComCtl32.dll версии 5 с традиционным стилем оформления элементов управления. И, конечно, нельзя заставить Windows 2000 выглядеть как Windows XP простой заменой версии ComCtl32.dll. Операционная система должна уметь использовать новые возможности. 
Теперь элементы управления в стиле Windows XP могут иметь собственную цветовую палитру, текстуры, стили заполнения и, самое главное, различные методы отрисовки своих составных частей. Например, элемент управления может рисовать собственное поле ввода данных обычным способом, а рамку-с использованием маски XOR. 
Совокупность правил и методов поведения, оформления и отрисовки элементов управления называется визуальным стилем (visual style). Совместно с Windows XP поставляется один готовый стиль. 
Если разработчик хочет, чтобы его приложение могло использовать новые возможности Windows XP, он должен включить в состав проекта специальный ресурс - манифест (manifest). Манифест представляет собой документ XML, содержащий необходимую для библиотеки ComCtl32.dll версии 6 информацию. 
Такое приложение будет чувствовать себя комфортно в среде Windows XP. Но и при запуске в старых операционных системах оно просто будет использовать стандартный набор возможностей ComCtl32.dll версии 5 и выглядеть, как и любое другое приложение. 
Кроме этого, Windows XP также имеет библиотеку ComCtl32.dll версии 5 и именно она используется по умолчанию. 
ID: 00391
=== Манифест Windows XP ===
Итак, начнем с манифеста. Он представляет собой документ в формате XML, содержащий всю информацию, необходимую для взаимодействия приложения и библиотеки ComCtl32.dll версии 6. 
Примечание 
Следует отметить, что манифесты широко используются во многих продуктах и технологиях, работающих в операционных системах Microsoft. С полной схемой XML манифеста вы можете ознакомиться в документации Microsoft MSDN. 
Пример манифеста
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.vl" manifestVersion="l.0"> 
<assemblyIdentity
 version="l.0.0.0" 
 processorArchitecture="X86" 
 name="CompanyName.ProductName.YourApp" 
 type="win32" 
/> 
<description>Your application description here.</description> 
<dependency> 
<dependentAssembly> 
<assemblyIdentity 
 type="win32" 
 name="Microsoft.Windows.Common-Controls" 
 version="6.0.0.0" 
 processorArchitecture="X86" 
 publicKeyToken="6595b64144ccfldf" 
 language="*" 
/> 
</dependentAssembly> 
</dependency> 
</assembly> 
Обратите внимание, что в элементе 
 <dependency> 
 <dependentAss emblу> 
 <assemblyldentity> 
описывается версия системной библиотеки, используемой приложением для отрисовки элементов управления. 
При загрузке приложения операционная система Windows XP считывает манифест (если он есть) и получает информацию о том, что для выполнения приложения потребуется библиотека ComCtl32.dll версии 6. 
Помимо этой информации манифест может содержать и другие необходимые сведения о приложении и условиях его работы. Например, общая информация о приложении и его версии представлены элементом 
 <AssemblyIdentity>. 
Вы можете добавить манифест в ваше приложение двумя способами: 
* использовать компонент TxpManifest; 
* добавить манифест в ресурсы приложения вручную.
ID: 00392
=== Компонент TXPManifest ===
На странице Win32 Палитры компонентов Delphi 7 имеется компонент TXPManifest. Будучи добавленным в проект, он обеспечивает компиляцию манифеста Windows XP в исполняемый файл приложения. В качестве основы используется стандартный манифест Delphi для Windows XP, содержащийся в файле ресурсов Delphi7\Lib\WindowsXP.res: 
<assembly xmlns="urn:schemas-microsoft-com:asm.vl" manifestVersion="l.0"> 
<assemblyIdentity 
 type="win32" 
 name="DelphiApplication" 
 version="3.2.0.0" 
 processorArchitecture="*" 
/> 
<dependency> 
<dependentAssembly> 
<Assemblyldentity 
 type="win32" 
 name="Microsoft.Windows.Common-Controls" 
 version="6.0.0.0" 
 publicKeyToken="6595b64144ccfldf"
 language="*" 
 processorArchitecture="*"
/> 
</dependentAssembly> 
</dependency> 
</assembly> 
К сожалению, версия профаммного продукта (ProductVersion), а также любая другая информация о версии, содержащаяся в проекте (файлы DOF и RES) и настраиваемая в диалоге Project Options среды разработки Delphi, никак не влияет на содержимое манифеста. Поэтому при настройке манифеста в соответствии с потребностями приложения вам придется предварительно отредактировать файл WindowsXP.res или поправить манифест прямо в исполняемом файле. (Ввиду частых перекомпиляций проекта второй вариант представляется довольно обременительным.) 
ID: 00393
=== Включение манифеста Windows XP в ресурсы приложения ===
Так как использование стандартного компонента TXPManifest требует настройки исходного манифеста Delphi для каждого проекта, было бы неплохо изыскать более удобный способ. В качестве альтернативы вы можете подключить манифест к файлу вашего проекта и по мере надобности редактировать его, не опасаясь, что ваша забывчивость может отразиться на версиях в манифестах других приложений. 
Для начала необходимо создать исходный файл ресурса RC, включающий единственную строку: 
1 24 "ХР.manifest" 
где 1 - номер ресурса версии библиотеки ComCtl32.dll, а 24 - номер ресурса манифеста (нумерация соответствует заголовочным файлам, распространяемых Microsoft); "ХР.manifest" - имя файла с документом XML, содержащим манифест. Естественно, манифест нужно настроить в соответствии с потребностями вашего проекта. 
Теперь нужно откомпилировать файл ресурса при помощи строчного компилятора-ресурсов \Delphi7\Bin\brcc32.exe и разместить его в папке проекта. 
И последняя операция - добавьте в исходный код файла проекта директиву подключения ресурса манифеста: 
{$R xpmanifest.res} 
В результате при компиляции проекта манифест из ресурса будет добавлен в исполняемый файл приложения. 
ID: 00394
=== Визуальные стили и темы оформления ===
Теперь давайте более подробно разберемся с визуальными стилями и их влиянием на пользовательский интерфейс приложений. 
Начиная с операционной системы Widows 95 пользователям был доступен пакет обновления Microsoft Plus!, который позволял использовать темы оформления рабочего стола Windows. Темой называется совокупность настроек цветов, шрифтов, курсоров и прочих ресурсов, необходимых для создания унифицированного пользовательского интерфейса. 
Все параметры одной темы сохраняются в файле с расширением theme в виде секций и значений, подобно файлам INI. Существующие темы доступны для выбора в системном диалоге Display Options. 
Визуальные стили, интегрированные в Windows ХР, управляют внешним видом и поведением элементов управления. При этом визуальный стиль использует настройки параметров пользовательского интерфейса, заданные текущей темой. Для управления темами визуального стиля операционная система использует менеджер тем. 
Визуальный стиль позволяет настраивать внешний вид элементов управления в целом и его составных частей. Правила и методы отрисовки сохраняются в файле с расширением mst, который входит в состав визуального стиля. 
Совместно с Windows XP поставляется только один визуальный стиль, и он составляет приятное и свежее впечатление о пользовательском интерфейсе операционной системы. 
ID: 00395
=== Визуальные стили в Delphi ===
TActionManager является своего рода "командным пунктом", из которого должны управляться элементы управления приложения. Нас интересует только одно свойство этого компонента 
property Style: TActionBarStyle; 
По умолчанию среда разработки Delphi предлагает к использованию два стиля: 
* standard - приложение использует системную библиотеку ComCtl32.dll версии 5; 
* windows XP - приложение использует системную библиотеку ComCtl32.dll версии 6 и единственный стандартный визуальный стиль Windows XP. 
Эти стили применимы только к элементам управления, размещенным на панелях инструментов (TActionToolBar), созданных в компоненте TActionManager. 
Однако не торопитесь возмущаться явной ограниченностью выбора. Вы можете создать собственный стиль самостоятельно. Правда, это потребует очень много усилий - ведь на основе базовых классов элементов управления вам потребуется создать собственные классы с нужным вам поведением и внешним видом. 
Для этого необходимо создать класс нового визуального стиля на основе класса TActionBarstyieEx. Затем новый стиль регистрируется при помощи процедуры 
 procedure RegisterActnBarStyle(AStyle: TActionBarStyleEx); 
После этого ваш стиль становится доступным для свойства style компонента TActionManager. Чтобы отменить стиль, используйте процедуру 
procedure UnRegisterActnBarStyle(AStyle: TActionBarStyleEx); 
Например, обе эти операции удобно выполнить при инициализации и деинициализации модуля, описывающего класс стиля: 
Вариант регистрации и отмены собственного визуального стиля 
var MyStyle: TMyStyleActionBars; 
... 
initialization 
 MyStyle := TMyStyleActionBars.Create; 
 RegisterActnBarStyle(MyStyle); 
finalization 
 UnregisterActnBarStyle(MyStyle); 
 MyStyle.Free; 
end. 
Для смены стиля приложения можно использовать глобальную переменную нового стиля (см. листинг 6.3). Ее достаточно присвоить свойству style: 
ActionManagerl.Style := MyStyle; 
При смене стиля все элементы управления, расположенные на панелях компонента ActionManagerl, будут уничтожены и созданы заново с использованием настроек нового стиля. 
Класс TActionBarstyieEx имеет всего несколько методов, которые необходимо перекрыть при создании собственного стиля. Все они возвращают классы объектов, используемых при создании пользовательского интерфейса. Рассмотрим их. 
Функция function GetStyleName: string; возвращает имя стиля. 
Функция function GetColorMapClass(ActionBar: TCustomActionBar): TCustomColorMapClass; позволяет получить ссылку на класс компонента настройки цветовой палитры (см. разд. "Компоненты настройки цветовой палитры" далее в этой главе), используемый панелью инструментов. 
Следующие три метода дают информацию о классах различных типов элементов управления, используемых при проектировании пользовательского интерфейса с помощью компонента TActionManager. 
Для того чтобы получить доступ к элементам управления, связанным со стилем, предназначен метод 
function GetControlClass(ActionBar: TCustomActionBar; AnItem: TActionClientltem): TCustomActionControlClass; 
Он возвращает класс элемента управления из панели ActionBar, связанного с элементом управления Anitem. Именно эта функция вызывается при создании элементов управления в панелях инструментов компонента TActionManager. 
Как уже говорилось выше, при присвоении свойству style компонента TActionManager нового значения (экземпляра класса разработанного вами визуального стиля) уничтожаются все существующие элементы управления и затем создаются новые. И в процессе создания каждого визуального компонента вызывается функция Getcontrolciass нового стиля, а возвращенное ею значение используется для вызова конструктора соответствующего класса. 
Аналогично, для получения класса, используемого в панели меню, применяется метод 
function GetPopupClass(ActionBar: TCustorrActionBar) : TGetPopupClass; 
и для классов кнопок панели инструментов применяется функция 
function GetScrollBtnClass: TCustomToolScrollBtnClass; 
А класс самой панели инструментов возвращает функция 
function GetAddRemoveltemClass(ActionBar: TCustomActionBar): TCustomAddRemoveltemClass;
Итак, после разработки и отладки собственных классов элементов управления с заданными свойствами вам потребуется создать потомка от класса TActionBarstyieEx и перекрыть все перечисленные выше функции так, чтобы они возвращали нужные классы для используемых типов элементов управления. 
ID: 00396
=== Theme API ===
Помимо описанного способа создания и управления визуальными стилями разработчик может использовать функции Theme API, разработанные Microsoft для этих целей. 
Для того чтобы использовать Theme API, можно стандартным способом подключить к проекту динамическую библиотеку Theme.dll: 
var ThemeDLL: HINST; 
... 
begin 
 ThemeDLL := LoadLibrary('theme.dll'); 
 if ThemeDLL <> 0 then 
 begin 
 ... 
 end; 
end;
Затем можно использовать возможности этого программного интерфейса напрямую. С деталями его реализации вы можете ознакомиться в документации Microsoft MSDN. 
Однако можно поступить проще. В составе Delphi 7 имеется модуль Ux-Theme.pas, в котором как раз и реализованы возможности Theme API. Кроме этого, модуль Themes.pas содержит классы для основных элементов управления, которые могут использоваться при создании визуальных стилей, а также класс менеджера тем TThemeServices. 
Так как детальное обсуждение возможностей Theme API выходит за рамки этой книги, в листинге 6.4 представлен схематичный пример использования функций этого программного интерфейса. Кроме того, как и все остальные API, работающие с GUI (Graphic User Interface) операционной системы, реальный код с использованием Theme API всегда перегружен многочисленными и ужасными на вид (а на самом деле вполне безобидными) функциями, рассчитывающими области вывода, неклиентские зоны оконных элементов и т. д. 
Поэтому наш пример лишь показывает, как загрузить динамическую библиотеку theme.dll и получить ссылку на тему визуального стиля для текущего окна и кнопочного элемента управления. 
Пример использования функций Theme API в Delphi 
var DC: HOC; 
 CurrentThemeData: HTHEME; 
begin 
 if UseThemes and InitThemeLibrary then 
 try 
 DC := GetWindowDC(Handle) ; 
 try 
 CurrentThemeData := OpenThemeData(0, 'button'); 
 CloseThemeData(CurrentThemeData); 
 finally 
 ReleaseDC(Handle, DC); 
 end 
 finally 
 FreeThemeLibrary; 
 end 
 else 
 ShowMessage('Приложение или операционная система не поддерживают использование Theme API'); 
end;
Функция 
function UseThemes: Boolean;
проверяет способность операционной системы и приложения использовать Theme API. 
Методы 
function InitThemeLibrary: Boolean; 
procedure FreeThemeLibrary; 
соответственно инициализируют и выгружают библиотеку theme.dll. 
Графический контекст ос наверняка понадобится при отрисовке элементов управления 
Функция 
OpenThemeData: function(hwnd: HWND; pszClassList: LPCWSTR): HTHEME; stdcall;
возвращает дескриптор темы для текущего визуального стиля и класса, имя которого представлено параметром pszdassList. 
После того как тема загружена, можно использовать разнообразные графические функции, входящие в состав программного интерфейса. 
При завершении работы не забудьте освободить занятые дескрипторы графического контекста и темы. Для темы используйте функцию 
CloseThemeData: function(hTheme: HTHEME): HRESULT; stdcall; 
Заинтересованный читатель найдет подробное описание нужных функций Theme API в Microsoft MSDN или же может полюбопытствовать содержимым модулей UxTheme.pas и Themes.pas. 
ID: 00397
=== Компоненты настройки цветовой палитры ===
Помимо создания собственных визуальных стилей, что является делом довольно трудоемким и хлопотным, вы можете изменить внешний вид пользовательского интерфейса приложения более легким способом. Впервые в составе Палитры компонентов Delphi 7 появились специализированные компоненты, позволяющие настраивать цветовую палитру всех возможных деталей пользовательского интерфейса одновременно. Эти компоненты расположены на странице Additional: 
* TstandardColorMap - по умолчанию настроен на стандартную цветовую палитру Windows; 
* TXPColorMap - по умолчанию настроен на стандартную цветовую палитру Windows XP; 
* TTwilightColorMap - по умолчанию настроен на стандартную полутоновую (черно-белую) палитру Windows. 
Все они представляют собой контейнер, содержащий цвета для раскраски различных деталей элементов управления. Разработчику необходимо лишь настроить эту цветовую палитру и по мере необходимости подключать к пользовательскому интерфейсу приложения. Для этого снова используется компонент TActionManager. 
Все панели инструментов (класс TActionToolBar), созданные в этом компоненте (см. гл. 8), имеют свойство 
property ColorMap: TCustomActionBarColorMap; 
в котором и задается необходимый компонент цветовой палитры. Сразу после подключения все элементы управления на такой панели инструментов перерисовываются в соответствии с цветами новой палитры. 
Обратите внимание, что в компоненте TToolBar, перенесенном из Палитры компонентов на форму вручную, это свойство отсутствует. 
Все компоненты настройки цветовой палитры имеют один метод-обработчик 
property OnColorChange: TnotifyEvent; 
который вызывается при изменении любого цвета палитры. 
ID: 00398
Category:Статьи