Часто задаваемые вопросы и ответы по C/C++/Visual C++
Последнее обновление: 27.08.2003
FAQ по C/C++/Visual C++
Работа с сетью
Как сделать XP интерфейс в проге
Составители: SUnteXx, Leprecon
Как сделать XP-интерфейс в программе.
A: (SUnteXx & Andruishka)
Оригинальная ссылка: нету

Написанный ниже текст предназначен только для Windows XP (и ее продолжений)

Самый простой вариант - это написать манифест, позволяющий Windows XP на стадии загрузки программы подключить нужную версию библиотеки разделяемых элементов (common controls), и занести его в ресурсы.

Q: Что такое манифест?
A: Манифест(manifest) - это текст на языке XML, описывающий нашу программу и библиотеки, необходимые для ее работы. В данном случае мы рассматриваем манифест для подключения шестой библиотеки common controls, включенной в состав Windows XP.

Лирическое отступление
Здесь нужно сказать, почему для подключения этой самой библиотеки в Windows XP нужно предпринимать какие-либо действия. Ведь для подключения этой же библиотеки в предыдущих версиях Windows никаких усилий не требовалось: достаточно подключить в проект библиотеку comctl32.lib и инициализировать ее с помощью функции InitCommonControls(), прописанной в commctrl.h
Дело в том, что в Windows XP существует две разные библиотеки common controls: одна "старая", версии 5.80, которая входит в поставку Internet Explorer 5.5 и которая может быть установлена на любую версию Windows, и "новая" версия - 6.0, которая и обеспечивает XP-интерфейс, т.е. поддержку визуальных стилей (visual themes)
Вы можете спросить, а почему бы этим странным людям из Microsoft просто не заменить бы "старую" версию на "новую"?
Дело в том, что до выхода Windows XP часть оконных классов - так называемые базовые классы окон - кнопки, статики (static text), поля ввода (editbox), скроллбары, списки и комбобоксы - хранилась в основной библиотеке, отвечающей за элементы пользовательского интерфейса - user.exe (Да, да, именно user.exe, а не user32.dll) Теперь же, все они "переехали" (нет, только новые версии - совместимость, понимаете ли) в библиотеку comctl32.dll
Из-за этого "старая" библиотека оставлена на своем прежнем месте, а новая засунута немножко дальше. И чтобы извлечь именно новую версию и нужен манифест.

Формат манифеста
Манифест лучше всего создавать как внешний файл. Назвать его можно как угодно, к примеру "data.bin". Создав файл с таким именем, запишите в него следующий текст:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
    version="5.1.0.0"
    processorArchitecture="x86"
    name="Author.Program_Name"
    type="win32"
/>
<description>Program Description</description>
<dependency>
    <dependentAssembly>
    <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        processorArchitecture="x86"
        publicKeyToken="6595b64144ccf1df"
        language="*"
    />
</dependentAssembly>
</dependency>
</assembly>
Лирическое отступление
Текст приведенный на этой странице можно копировать прямо из FAQ в какой-нибудь текстовый редактор, поддерживающий сохранение в текстовом формате, например в notepad.

Написали? Да у вас успехи в программировании! Теперь измените имя программы в 6-ой строке name="..." (не используйте пробелов, рекомендуется форма "Author.ProgramName" и описание программы в 9-ой между тэгами и (тут уже можно вставлять пробелы).

Подключение манифеста к приложениям.
Вообще, подключать манифест можно как через ресурсы приложения, так и используя внешний манифест. Внешний манифест подключается путем создания внешнего файла с именем типа "application.exe.manifest", где "application.exe" - имя исполняемого модуля вашей программы. Он помещается в одну папку с исполняемым модулем. Также можно использовать две версии манифеста: в виде ресурсов и в виде внешнего файла. В этом случае преимущество имеет дисковая версия манифеста.

Манифест может быть записан в ресурсы приложения (в новых SDK есть описание ресурса с именем RT_MANIFEST, именно так его обозвали в Visual Studio .NET. Для использования манифеста в Visual Studio 6.0 и во всех остальных системах нужно записывать манифест в ресурс с номером 24 (именно с номером, а не с именем "24")

Подключение манифеста к исполняемым модулям.
Данный параграф относится к большинству случаев создания XP-интерфейса. Он распространяется на приложения Windows и показывает, как подключить манифест, используя ресурс манифеста.
Лезем в ресурсы приложения (если кто не знает, никогда не писал программы под Windows или не использовал в них ресурсы - то это такой файл с расширением *.RC) и пишем в файл ресурсов следующую строку:
1                       24      MOVEABLE PURE   "data.bin"
А теперь собираем приложение и наслаждаемся новым интерфейсом программы.

Q: Упс... прога выдает "ошибку" и не запускается... Что делать?
A: (SUnteXx) В моем случае надо было добавить в опции линковщика ( Project -> Settings -> Link -> Object/Library Modules ) вот эту библитотеку: comctl32.lib. Если и это не помогло, то в самом начале программы вызываем функцию InitCommonControls (без параметров) которая прописана commctrl.h
A: (Anduishka) А в моем случае надо было переписать сам файл манифеста. Я выкинул из него все символы перевода строки. Поэтому, я рекомендую писать файл манифеста в одну строку.

Подключение манифеста к динамическим библиотекам, используемым как In-Process сервер.
Этот способ был использован для создания XP-интерфейса в библиотеке расширения Проводника. Нужно было создать дополнительную страничку свойств файла. В этом случае описанный выше способ не срабатывает. Простое подключение манифеста в ресурсы библиотеки тоже не подходит. В этом случае необходима модификация кода библиотеки.
Для подключения манифеста в DLL сделать нужно следующее:
Добавить в файл ресурсов следующую строку
2                       24      MOVEABLE PURE   "data.bin"
то есть, нужно подключить манифест с идентификатором ресурса ID=2. Далее, надо либо сделать определение ISOLATION_AWARE_ENABLED в главном файле библиотеки, но до подключения к нему файла "windows.h" , то есть, после модификации фрагмент кода программы будет выглядеть так :
#define    ISOLATION_AWARE_ENABLED
#define    "windows.h"
Однако, при использовании MFC, файл "windows.h" подключается где-то глубоко в недрах библиотеки, поэтому определение можно сделать в опциях компилятора (Project -> Settings -> C/C++ -> Preprocessor definitions)
Теперь, компилируем программу, используя новую версию SDK (у меня стоит версия SDK от июля 2001), так как в старой версии, поставляемой, скажем, с Visual Studio 6.0, определение ISOLATION_AWARE_ENABLED отсутствует. Да, и еще: для использования этого определения надо установить _WIN32_WINNT в 0x501, т.е. включить поддержку Windows XP. Строка, описывающая эту директиву должна выглядеть так:
#define      _WIN32_WINNT    0x501
Подключение манифеста к приложениям, используемым как расширения Панели Управления.
На расширения панели управления распространяются те же правила, что и на обычные приложения. Однако, манифест в случае его размещения во внешнем файле будет иметь имя "application.cpl.manifest", а при размещении в ресурсах приложения, ему следует присвоить ID=123.
Содержание Обсудить на форуме « Предыдущая статья | Следующая статья »
Перейти к FAQ:  
FAQ составлен по материалам Форума на Исходниках.Ру.
Copyright © 2002 by Sources.ru. All rights reserved.