Вне WinFX: Transcriptions, Aero Wizards и Task Dialogs в Windows Vista
Что приходит первое на ум, когда Вы думаете о программировании для Windows Vista. Конечно же Вы вспоминаете о WinFX.
WinFX охватывает множество технологий, которые получили большое внимание, включая Microsoft® .NET Framework 2.0, Windows® Presentation Foundation, Windows Communication Foundation и Windows Workflow Foundation. Но WinFX является всего лишь частью новой ОС. Windows Vista обновленная операционная система Windows, несущая новые улучшенные библиотеки и сервисы, которые вне досягаемости WinFX, позволяя создавать более мощные приложения с меньшим количеством кода.
Эта статья представит Вам множество новых возможностей, которые несет в себе Windows Vista. Эти возможности обычно не получают особого внимания, которого они заслуживают, потому что они обычно предназначаются разработчикам, программирующим на чистом C++ или не попадают в категорию программирования WinFX.
Kernel Transaction Manager
Одной из самых невероятных, новых служб в Windows Vista, которая будет в распоряжении разработчиков, будет Kernel Transaction Manager (KTM). Это служба, как менеджер операций для локальных транзакций и менеджер ресурсов для распределенных локальных транзакций. KTM предлагает новую концепцию менеджеров операций с множественной структурой на одиночном компьютере, поскольку он управляет множественными исключениями и связанными с ними менеджерами ресурсов. Перед тем как начать изучение функциональных возможностей KTM более подробно, давайте определимся с целью менеджеров ресурсов и операций.
Менеджер ресурсов отвечает за какой-либо локальный ресурс, типа устройства базы данных или сервера очереди сообщений. Менеджеры ресурсов работают вместе с менеджерами операций, чтобы скоординировать изменения в ресурсах, управляемых в пределах контекста транзакции. Любое число менеджеров ресурсов может участвовать в транзакции, согласовываясь с менеджерами операций. На практике, большинство менеджеров ресурсов работают как менеджеры операций, когда транзакция ограничена единственным ресурсом, типа устройства базы данных. Это рассматривается как локальная транзакция.
Если какая-либо транзакция привлечет менеджер ресурсов, то произойдет распределение операций и независимый операционный менеджер вступит во взаимодействие с менеджером ресурсов. Это взаимодействие гарантирует, что все менеджеры ресурсов или передадут или возвратят изменения до начального уровня ресурсов. В общем, привлечение менеджеров ресурсов происходит, когда только это становится необходимым.
Microsoft SQL Server™ является хорошим примером менеджера ресурсов. Все транзакции, вызывающие SQL Server, используют менеджер операций SQL Server для выполнения любых команд в пределах контекста данной транзакции. Microsoft Distributed Transaction Coordinator (DTC) - служба, которую предоставляет Windows, она используется как менеджер операций, когда транзакция охватывает более одного менеджера ресурсов. DTC координирует транзакции с SQL Server и с другими менеджерами ресурсов пользовательского режима, включая KTM. Кроме того, Вы можете начать транзакцию в управляемом коде и использовать ее для транзакции файла.
Так же, как SQL Server работает как менеджер ресурсов для местных транзакций базы данных и как менеджер операций для распределенных транзакций базы данных, KTM работает как менеджер операций для локальной файловой системы и операции регистрации и как менеджер ресурсов для распределенных локальных транзакций, которые включают в себя файловую систему и операции регистрации. KTM позволяет Вам вызвать файловую систему и функции регистрации в контексте транзакции и даст гарантию, что все операции будут проведены полностью.
Прелесть KTM заключается в том, что он не требует, чтобы Вы изменяли способ, с помощью которого Вы взаимодействуете с файлами и регистрационными ключами. Какой бы API Вы бы не использовали для взаимодействия с файлами и регистрационными ключами, он будет работать ровно столько сколько будут производиться к ним обращения.
Давайте рассмотрим простой пример использования функции файлового и регистрового управления из Windows SDK. Предположим, что Вы пишите программу, которая должна хранить адрес файла системной папки, к примеру для хранения истории изменения текущего сообщения. И скажите, хотите ли Вы позволить пользователю изменять местоположение папки истории. Вы можете это осуществить с помощью
Функция MoveHistoryFolder предназначена для перемещения папки истории и обновления информации о ее новом местоположении. Все довольно таки просто. Но есть множество сценариев, не принимающих это во внимание.
MoveHistoryFolder отключается по окончанию перемещения папки истории. Если перемещение произойдет успешно, то функция обновит данные о местоположении в регистре. Иначе папка истории будет перемещена в изначальное местоположение.
Так что же плохого в этой функции? Даже в этом простом примере может произойти сбой с потерей данных. Так непреднамеренное отключение ПК, в случае отказа какого-либо устройства и т.п., папка может быть и успеет переместиться и потеря данных не произойдет, а вот обновление регистра о новом местоположении данной папки может и не произойти. Дело в том, что операционная система рассматривает работу с файлами и запросы к регистру как независимые операции.(В то время как ваше приложение считает, что это одна операция, которая не должна иметь никаких побочных эффектов).
Благодаря KTM решение данной проблемы будет весьма простым. Так как все вовлеченные ресурсы являются локальными ресурсами управляемыми с объектами ядра(предполагается, что Вы не даете права пользователю перемещать папку истории на другой компьютер), Вы можете использовать KTM как менеджер операций для локальных транзакций, а так же как менеджер ресурсов.
Функция CreateTransaction создает новый объект транзакции, которым управляет KTM. Объекты транзакции – регуляторные объекты ядра, относящиеся к таким конструкциям ОС, как события и файлы, представленные объектами ядра. Функция CreateTransaction передает управление объекту транзакции. GUID идентифицирует транзакцию на компьютере(если GUID не определено, то KTM создаст GUID по умолчанию). Что касается других объектов ядра, то Вы можете определить структуру SECURITY_ATRIBUTES для управления атрибутами безопасности вручную. Так же Вы можете передать описание пользователя в параметры CreatTransaction, что рекомендуется для процесса управления.
Когда транзакция Вам будет не нужна, Вы можете закрыть ее вручную, с помощью функции CloseHandle. Чтобы передать транзакцию, достаточно воспользоваться функцией CommitTransaction. Для возврата транзакции, нужно воспользоваться функцией RollbackTransaction. Пример использования данных функций можно рассмотреть в
Данный код иллюстрирует использование класса KtmTransaction. Однако прежде чем Вы сможете воспользоваться данным классом, Вам нужно связаться со средой, которая вызывает файловые и регистровые функции управления, тем самым этим функциям будет передана информация о том, что они запускаются из контекста транзакции. За это отвечает функция SetCurrentTransaction: связывает запрос с транзакцией. Все будет работать, пока SetCurrentTransaction не будет вызван вручную. Класс KtmTransactionBinding показан в
С помощью KtmTransaction и класса KtmTransactionBinding, Вы можете вызвать в пределах контекста транзакции функцию MoveHistoryFolder, что показано в
Если MoveHistoryFolder не возвратит успешного результата HRESULT, то функция объектов транзакции не будет вызвана, файловые и регистровые операции будут возвращены в начальное состояние. Так как возвращение в начальное состояние файлов и регистров произойдет автоматически, Вам не придется на этом останавливать внимания, Вы можете сосредоточиться на написании вашего кода. Примером может послужить
Command Links
Command Links – новый стиль кнопок, более упрощенных для пользователя и сосредотачивающих внимание пользователя на одной или более команд. Хотя они разработаны для мастеров установки и т.п. Command Links – нечто большее, чем устаревшие кнопки управления со специальными атрибутами стиля.
Самый простой способ создания Command Links – использование Visual C++ Resource Editor. Откройте панель инструментов диалогового редактора и поместите custom control(специальные управляющие элементы) на диалоговое окно. Убедитесь, что сделали Command Links достаточного размера, так как они должны быть немного больше, чем обычные кнопки. Теперь установите свойство класса control для кнопки и ее свойство Style как 0x5001000e. Вы также можете изменит свойство Caption, записав текст, который Вы хотите увидеть на Command Links. Вы можете посмотреть параметры настройки панели Properties на следующей иллюстрации:
Теперь Вы можете откомпилировать Ваш проект и Вы увидите примерно такое диалоговое окно:
Command Links так же позволяют добавить дополнительный текст, чтобы обеспечить подсказки. Вы можете сделать это отправив BCM_SETNOTE сообщение или используя макрос Batton_SetNote. Вы так же можете изменить стрелку курсора щитом при наведение на Command Links, для этого Вам надо отправить команду BCM_SETSHIELD или используя макрос Button_SetEvolutionRequiredState. Примером может стать следующая иллюстрация кода:
CWindow button1 = GetDlgItem(IDC_BUTTON1);
Button_SetNote(button1,
L"You know you want to click it.");
Button_SetElevationRequiredState(button1,
TRUE);
Streamlined UI: Aero Wizards
Хотя Wizards используются уже на протяжение длительного времени, спецификация Wizards 97 полна бесполезной и избыточной информации , внешних страниц и заголовков. Aero Wizards, которые заменит устаревшую версию Wizards 97, разработаны с более понятным и кратким интерфейсом, основаны на новом опыте, помогут пользователю избежать потенциальных сложностей в выполнении операций. Как и в случае с Command Links, Aero Wizards являются дополнительной надстройкой над уже существующими средствами управления. На следующей иллюстрации продемонстрирован старый Wizards 97:
Давайте посмотрим, что потребуется для преобразования Wizards 97 в новый Aero Wizards. Для этого Я воспользуюсь ATL и Windows Template Library(WTL) для демонстрации. Вы же можете работать с тем, с чем Вам больше нравиться.
Окно проиллюстрированное выше создано с помощью класса Wizard. Базовый класс CPropertySheetImpl скрывает функции, сообщения, и структуры, которые необходимы для выполнения свойств. Структура PROPSHEETHEADER используется для управления всеми аспектами свойств. Класс CPropertySheetImpl автоматически заполняет эту структуру от Вашего имени. Если Вы хотите изменить поведение Aero Wizard, то вам нужно изменить структуру PROPSHEETHEADER, с помощью переменной m_psh. Это продемонстрировано в иллюстрации, находящейся выше. Изменение Wizard 97 в Aero Wizard происходит при смене флага PSH_WIZAR97 на PSH_AEROWIZARD. В результате Вы получите следующее:
При виде нового Aero Wizard первое, что бросается в глаза это заметно меньший размер окна, а так же измененная кнопка возврата. Кнопка возврата была перенесена из нижней части окна в верхнюю, что напоминает стиль Web-browser. Но все действия, которые можно было провести над кнопкой возврата в Wizard 97 можно осуществить и в Aero Wizard.
Возможность запрета кнопки Next не только осталась, но появилась возможность удаления данной кнопки из окна Wizard. Для этого вам нужно создать сообщение PSM_SETWIZBUTTONS. Напомню, что до появления Windows Vista такой возможности не было, Вы не могли удалять кнопку Next и Finish из окна Wizard. Windows Vista дает Вам такую возможность, позволяя заменить кнопку Next и Finish любым числом Command Links.
В Aero Wizards появились новые сообщения, которые позволяют Вам управлять видимостью кнопок. Вы можете скрыть кнопку Next послав сообщение PSM_SHOWWIZBUTTONS или используя макрос PropSheet_ShowWizButtons:
SetWizardButtons(0);
PropSheet_ShowWizButtons(m_hWnd, PSWIZB_CANCEL,
PSWIZB_CANCEL | PSWIZB_NEXT);
Для отключения кнопки возврата нужно создать сообщение PSM_SETWIZBUTTONS с индикатором 0 в свойствах. Для включения нужно установить индикатор – 1. Для скрытия – 2. Наконец Вы можете добавить Command Links для предоставления пользователю вариантов перехода, пример можно посмотреть на следующей иллюстрации:
От Message Box к Task Dialogs.
Task dialog – новый мощный инструмент для отображения подсказок и напоминаний пользователям, с использованием маленького количества кода. Функция MessageBox широко используется на протяжении уже многих лет для вывода подтверждений и ошибок или принятие решения “Да/Нет”.
Наконец Message Box стали заменены на Task Dialogs, которые сохранили простату и компактность, но получили больше настроек для управления. Task Dialogs используют пару функций, наиболее простая TaskDialog и более мощная TaskDialogIndirect. Функция TaskDialog очень похожа на функцию MessageBox и в большенстве случаев Вы можете одной заменять другую, заменяя соответствующие параметры для получения желаемого результата. Рассмотрите следующий вызов messageBox:
int result = ::MessageBox(0, // no owner window
L"Do you want to save changes?",
L"Application",
MB_YESNOCANCEL | MB_ICONINFORMATION);
Этот код можно изменить воспользовавшись функцией TaskDialog.
Хотя и между Message Box и Task Dialogs нет серьезных отличий, функция TaskDialog имеет несколько удобных особенностей, которые делают ее использование стоящим. Одна из лучших особенностей – способность определения модуля вручную, который позволяет определять идентификаторы ресурсов и литеральные строки. Это поможет Вам избежать запроса функций LoadString. Определение модуля вручную так же позволит Вам отображать иконку вашего выбора в диалоговом окне. Так же task dialog способен отображать дополнительную информацию, когда это нужно. Наконец есть отдельные флаги для каждой кнопки, таким образом Вы можете создавать произвольные комбинации кнопок, как показано
Сложный Task Dialog.
Одна из проблем функции TaskDialog – то, что Вы не можете изменить текст, который появляется на кнопках. Из иллюстрации продемонстрированной выше видно, что многословные описания кнопок не будут нужны, если кнопки будут иметь более определенную формулировку, такую как "Save", "Don’t Save" и "Cancel". Эта проблема была решена в TaskDialogIndirect. Но TaskDialogIndirect может еще больше: она может превратить простое диалоговое окно в богатое информацией диалоговое окно, которое предоставляет больше информации без написания огромного UI кода. Функция TaskDialogIndirect задается следующим образом:
HRESULT WINAPI TaskDialogIndirect(
const TASKDIALOGCONFIG* config, int* button,
int* radioButton, BOOL* verificationChecked);
Чтобы использовать данную функции нужно подготовить параметр config. TASKDIALOGCONFIG управляет всеми аспектами интерфейса Task Dialog.
Для начала, давайте пересоздадим диалог "Do you want to save changes?" с более описательными кнопками. Результат можно посмотреть на
Функция TaskDialogIndirect предоставляет контроль над появлением диалога. Чтобы легче изучить различные варианты функции TaskDialogIndirect я написал TaskDiaolog Design, показанный ниже:
TaskDialog Designer – маленькое приложение Windows Form написанное на C#, которое содержит ряд опций Task Dialog, с которыми Вы можете поэкспериментировать. TaskDialog Designer делает возможным использование .Net написанного на C++/CLI, обеспечивающий управление интерфейсом с функцией TaskDialogIndirect. Вы можете переписать предыдущий код на чистом C++ вот этим кодом на C# для создания того же task dialog:
using (TaskDialog dialog = new TaskDialog())
{
dialog.Title = "Application";
dialog.MainInstruction = "Do you want to save changes?";
dialog.Content = "Click Cancel to return to the application.";
dialog.Buttons = TaskDialogButtons.Cancel;
dialog.CustomButtons.Add(new TaskDialogButton("&Save", 6));
dialog.CustomButtons.Add(new TaskDialogButton("&Don’t Save", 7));
dialog.MainIcon = TaskDialogIcon.Information;
int button = dialog.ShowDialog();
}
Одна из распространенных причин использования task dialog – вывод сообщения об ошибке. В следующей иллюстрации представлен Task Dialog с информацией от объекта исключения. Первоначально показана краткая информация об ошибке, но если пользователю нужна полная информация достаточно нажать на See details,
Заключение:
Windows Vista – самое главное обновление ОС Windows и включает огромное обновление в Windwos SDK. Из всех новых возможностей, Kernel Transaction Manager, Aero Wizards и task dialogs любят не многие, но они заслуживают более близкого ознакомления. KTM позволяет Вам сосредоточиться на логике приложений, в то время как операционная система заботится обо всем комплексе, гарантируя, что ваши приложения не будут иметь никаких нежелательных эффектов. Aero wizards, объединенные с командами связи предоставляют простой и новый интерфейс для взаимодействия с пользователем. А task dialogs предоставляют новый мощный API, который несет легкость в использования и представляет реальную замену для устаревших диалоговых окон.
Источник:
Перевод: lexa
По теме
- Видео-курсы от MS: Разработка приложений виртуальной и расширенной реальности на платформе Microsoft
- ECMA JavaScript 6: Объекты
- Как просто создать приложение для iPhone
- Разработка приложений под Windows Phone 8
- Индексированное хранилище, часть 2
- Индексированное хранилище, часть 1
- Начала Metro-программирования: создание настраиваемых приложений (ч.2)
- Начала Metro-программирования: создание настраиваемых приложений (ч.1)
- Начала Metro-программирования: создание компонентов WinRT (ч.3)
- Начала Metro-программирования: создание компонентов WinRT (ч.2)