Программная логика приложений для Windows 8 и их взаимодействие с системой

Контракты

Разбить на страницы
Показывать лекцию целиком

Введение

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

Весьма ярко этот персонаж проявил себя в сцене на бензоколонке. К нему подошел нищий с табличкой: "Буду работать за еду". Увидев это, наш герой предложил ему яблоко в обмен на то, чтобы тот помыл лобовое стекло его машины. Но когда тот нищий отказался, не соблюдя, таким образом, письменный контракт, герой Купера весьма расстроился… до состояния, когда он объявляет о своей неизлечимой болезни, распахивает рубашку и показывает пояс из взрывчатки с десятисекундным таймером, на котором уже начался обратный отсчет.

В итоге, он уезжает с чистым лобовым стеклом и с чувством удовлетворения от того, что помог кому-то, хотя и странным способом, соблюсти свою часть письменного соглашения. Он появляется и позже, в городе, в котором живут одни адвокаты да полицейские… Предлагаю вам попытаться представить, что там произошло, или, по крайней мере, насладиться фильмом.

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

Такова природа различных контрактов в Windows 8, которые, в целом, возможно, являются одной из наиболее мощных возможностей во всей системе. Главную цель контрактов можно описать как "Запуск приложения с определенной целью и в определенном контексте". Таким образом, вместо того, чтобы запускать приложения изолированно, контракты позволяют запускать их в связи с нуждами других приложений в контексте этих приложений. Информация может быть, таким образом, передана для реального использования напрямую из приложения в приложение, вместо передачи ее через обычное посредничество файловой системы, где теряется связь между приложениями.

В случае с любым контрактом, одна сторона – это потребитель или приемник информации, передаваемой посредством контракта. Другая сторона – это источник или поставщик этой информации. Сам по себе контакт – это нечто общее: ни одна из сторон не нуждается в знании подробностей о другой, ей лишь нужно знать о своей стороне контракта. Это может звучать не особенно сильно, но это дает высокую степень расширяемости, которая становится все больше и больше при установке в систему приложений, которые поддерживают те или иные контракты. Я полагаю, что когда пользователи начнут испытывать возможности, которые предоставляют контракты, они все больше и больше будут искать в Магазине Windows приложения, которые используют контракты для обогащения их системы и создания более насыщенного опыта взаимодействия с системой.

Что касается приложений, использование контрактов обычно происходит посредством вызовов API, таких, как средство выбора файлов, или через использование встроенных возможностей интерфейса системы, таких, как Панель чудо-кнопок. Предоставление информации для контрактов часто выглядит интереснее, так как приложению нужно отреагировать на специфические события (если оно выполняется), или сообщить о возможностях посредством манифеста и затем обрабатывать различные варианты активации контрактов.

Таблица ниже содержит краткое описание всех контрактов и расширений Windows 8 (в алфавитном порядке), некоторые из которых позволяют приложениям работать вместе, в то время как другие позволяют приложениям расширять функциональность системы. Их полное описание можно найти в материале "Контракты и расширения приложений" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh464906%28v=VS.85%29.aspx). Те, о которых речь идет в этой лекции, выделены зеленым: Общий доступ (Share), Поиск (Search), сопоставление типов файлов и схем универсальных кодов ресурсов (URI) (file type and URI scheme association), средства выбора файлов (file pickers), обновление кэшированных файлов (cached file updater) и окно выбора контактов (людей) (contacts (people)). Другие контракты либо обсуждаются в указанных лекциях, некоторые из них я оставил для вашего самостоятельного изучения с использованием документации и примеров.

Совет. Для того чтобы сравнить различные возможности обмена данными – контракт Общий доступ (Share), буфер обмена (clipboard), контракт средства сохранения файлов (file save picker), посмотрите материал "Общий доступ к данным и обмен данными" (http://msdn.microsoft.com/library/windows/apps/hh464923.aspx) в Центре разработчиков Windows. Он показывает различные сценарии для каждой из возможностей, и случаи, когда вы можете реализовать больше, чем одну из них в приложении.

Кроме того, обратите внимание на то, что эти контракты используют множество событий WinRT, поэтому помните о необходимости вызова removeEventListener, как это описано в лекции 3 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript".

Контракт / Расширение Поставщик Потребитель Описание, Документация и Примеры
Поставщик аватаров (Account picture provider) (лекция 3) Приложение, которое может работать с изображениями. Windows (изображение в учетной записи) Когда пользователь меняет аватар, он может либо выбрать из существующих изображений, либо получить его от какого-либо приложения-поставщика. Смотрите пример "Имя для аватара" (http://code.msdn.microsoft.com/windowsapps/Account-picture-name-sample-912baff1).
Автозапуск (AutoPlay) (лекция 4) Приложение, которое может быть перечислено в списке действий при автозапуске. Windows Смотрите материал "Запуск приложения с помощью автозапуска" (http://msdn.microsoft.com/library/windows/apps/hh452731.aspx) и пример "Съемные запоминающие устройства" (http://code.msdn.microsoft.com/windowsapps/Removable-Storage-52cc49f0).
Фоновые задачи (Background tasks) (лекции 2 и 3) Приложения, имеющие фоновые задачи Windows Позволяет приложение исполнять небольшие задачи в фоновом режиме (то есть, когда, в противном случае, приложение приостановлено или не исполняется), без необходимости взаимодействия с пользователем. Смотрите материал: "Введение в фоновые задачи" (http://www.microsoft.com/en-us/download/details.aspx?id=27411) и лекцию 2. Фоновая передача файлов – это особый случай, поддерживаемый специальным API; смотрите материал "Передача данных в фоновом режиме" (http://msdn.microsoft.com/library/windows/apps/hh452979.aspx) и лекцию 3.
Контракт обновления кэшированных файлов (Cached file updater) Приложения, которые предоставляют доступ к своим данным с помощью средства выбора файлов и нуждаются в синхронизации их обновления. Приложения, использующие API средства выбора файлов и файловые API для управления ими. Приложение-поставщик может позволить потребителю получить кэшированную копию файла. С помощью контракта поставщик может синхронизировать обновления между локальной копией и исходным файлом. Смотрите материал "Интеграция с контрактами "Средство выбора файлов" (http://msdn.microsoft.com/library/windows/apps/hh465174.aspx).
Параметры камеры (Camera settings) Приложения с настраиваемым пользовательским интерфейсом камеры Пользовательский интерфейс камеры Windows Windows Camera Capture UI Смотрите материал "Разработка приложений Магазина Windows для камер" (http://msdn.microsoft.com/library/windows/hardware/hh454870)
Окно выбора контактов (Contact picker) Приложения, которое работает с данными контактов (наподобие адресной книги). Приложения, которые используют API выбора контактов (наподобие приложений электронной почты) Запускает приложение для предоставления списка, из которого можно выбирать контакты. Смотрите материал "Управление контактами пользователя" (http://msdn.microsoft.com/library/windows/apps/hh464939.aspx)
Активация файла (сопоставление типа файла) (File activation (file type association)) Приложения, которые могут открывать файлы конкретного типа. Проводник Windows и приложения, которые используют API запуска файлов. Запускает приложение для открытия или обработки файла при необходимости. Смотрите материалы "Обработка активации файла" (http://msdn.microsoft.com/library/windows/apps/hh452684.aspx), и "Автоматический запуск с сопоставлением файлов и универсальных кодов ресурсов (URI)" (http://msdn.microsoft.com/library/windows/apps/hh452691.aspx).
Контракты выбора файлов в окне открытия/сохранения (File open picker/file save picker) Приложение с данными, которые могут выглядеть для других приложений как файлы, которые можно открывать и / или сохранять (два разных контракта). Приложения, использующие API средства выбора файлов (а так же, определенные возможности Windows) Дает доступ к данным, которые, в противном случае, скрыты внутри приложения и управляются его средствами. Эти данные видны пользователю как часть файловой системы. Смотрите материал "Интеграция с контрактами "Средство выбора файлов" (http://msdn.microsoft.com/library/windows/apps/hh465174.aspx).
Проводник игр (Game explorer) Игровое приложение с файлом описания игры (Game Definition File) Windows (Служба семейной безопасности (parental controls) Управляет возрастными ограничениями для игр. Смотрите материал "Создание файла описания игры" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh465153.aspx).
Воспроизведение на устройстве (Play To) (лекция 4 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript") Приложения, которые могут воспроизводить цифровое мультимедиа на DLNA-устройствах Windows (Чудо-кнопка "Устройства" (Devices) > Подключиться (Connect)) Смотрите материал "Потоковая передача мультимедиа на устройства с помощью функции воспроизведения на устройстве" (http://msdn.microsoft.com/library/windows/apps/hh465176.aspx).
Параметры задачи печати (Print task settings) Приложения, работающие с принтерами Windows (Чудо-кнопка "Устройства" (Devices) > Печать (Print)) Смотрите материал "Разработка приложений Магазина Windows для принтеров" (http://msdn.microsoft.com/library/windows/hardware/br259129).
Активация протокола (сопоставление со схемой URI) (Protocol activation (URI scheme association)) Приложение, которое открывает URI, начинающиеся с определенной схемы URI). Проводник Windows и приложения, которые используют API запуска файлов. Запускает приложения для открытия или обслуживания URI при необходимости. Смотрите материалы "Обработка активации протокола" (http://msdn.microsoft.com/library/windows/apps/hh452686.aspx) и "Автоматический запуск с сопоставлением файлов и универсальных кодов ресурсов (URI)" (http://msdn.microsoft.com/library/windows/apps/hh452691.aspx).
Поиск (Search) Приложение с данными, по которым можно осуществлять поиск Windows (Чудо-кнопка Поиск (Search)) Представляет легко доступную во всей системе возможность по поиску в любом приложении. Смотрите материал "Добавление поиска в приложение" (http://msdn.microsoft.com/library/windows/apps/hh465231.aspx).
Параметры (Settings) (Глава 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript") Приложения, имеющие параметры Windows (Чудо-кнопка Параметры (Settings)) Предоставляет единую точку доступа к параметрам приложения. Смотрите материал "Добавление параметров приложений" (http://msdn.microsoft.com/library/windows/apps/hh770540.aspx).
Общий доступ (Share) Приложения с данными для совместного использования. Приложения, которые могут принимать данные для включения в состав собственных данных или для отправки на устройства. Предоставляет средство для передачи данных между приложениями, в результате, приложение-источник не нуждается в знании особенностей реализации приложения-получателя, наподобие Facebook, Twitter и так далее. Смотрите материал "Общий доступ к содержимому и его получение" (http://msdn.microsoft.com/library/windows/apps/hh758314.aspx).
SSL/сертификаты (SSL/certificates) Приложение, которое нуждается в установке сертификата Приложение, которое нуждается в поддержке сертификата для доступа к стороннему сервису. Смотрите материал: "Шифрование данных и работа с сертификатами" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh465012.aspx).

Общий доступ

Хотя чудо-кнопка Поиск расположена первой на Панели чудо-кнопок, певый контракт, который я хочу подробно рассмотреть – это Общий доступ. В конце концов, это одна из первых вещей, которую узнают дети! Я начинаю с Общего доступа, так как мы уже видели его со стороны источника, в Главе 2 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", в приложении "Here My Am!", а здесь, в конце этого раздела, мы так же коснемся старого доброго буфера обмена.

Вот, что мы уже знаем об Общем доступе, более подробно процесс работы с ним показан на рис. 1.1.

  • Приложение с содержимым, подходящим для общего доступа, прослушивает событие datarequested объекта, возвращаемого Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView(). Это событие WinRT (при работе с которым вы должны помнить об использовании removeEventListener) вызывается, когда пользователь активирует чудо-кнопку Общий доступ. Заметим, что если приложение вовсе не прослушивает это событие, панель Общего доступа отобразит сообщение по умолчанию "Это приложение не поддерживает общий доступ "unable to share" (это сообщение, несомненно, разочарует пользователей!).
  • В обработчике события приложение определяет, есть ли в его текущем состоянии что-то для общего доступа. Если есть, оно заполняет Windows.ApplicationModel.DataTransfer.DataPackage, предоставленный в событии. (Здесь возможны варианты в зависимости от наличия или отсутствия выделения. Если пользователю нужно сделать выделение для того, чтобы общий доступ заработал, приложение может отобразить сообщение об этом).
  • На основании форматов данных в пакете, Windows, то есть – брокер общего доступа, управляющий контрактом, определяет целевые приложения общего доступа для отображения пользователю. Пользователь так же может управлять тем, какие приложения следует отображать, посредством параметра Изменение параметров компьютера (Change PC Settings) > Общий доступ (Share).
  • Когда пользователь выбирает цель общего доступа, активируется соответствующее приложение и принимает пакет данных для обработки.
  • (рис 1.1) Обработка реализации контракта Общий доступ, инициированная после активации пользователем чудо-кнопки Общий доступ

    Приложение-источник (Source App)

    Прослушивает событие datarequested объекта DataTransferManager (Listens for datarequested event on DataTransferManager)

    Принимает событие и заполняет DataPackage (Receives events and fills DataPackage)

    Завершает асинхронный вызов (посредством отложенной операции) и возвращается из операции обработки (Completes async calls (via deferrals) and returns)

    Необязательный прослушиватель для события targetApplicationChosen объекта DataTransferManager (Optional listen for targetApplicationChosen event on DataTransferManager)

    Брокер общего доступа(Share Broker)

    Чудо-кнопка Общий доступ активирована, вызвано событие datarequested для приложения переднего плана (Share charm is invoked, datarequested fired to foreground app)

    Отфильтрованный список целевых приложений и быстрых ссылок (Filters list of target apps and Quicklinks base on format)

    Пользователь выбирает целевое приложение или быструю ссылку (User selects target app or Quicklink)

    Активация целевого приложения с пакетом данных (Activate target app with data package)

    Целевое приложение общего доступа (Share Target App)

    Активация для общего доступа (Activated for sharing)

    Обрабатывает содержиме DataPackage (вывод запросов) (Processes DataPackage contents (requests rendering))

    Сообщает о завершении операции и операция завершена (Reports complete and sharing is complete)

    Все это предоставляет пользователям удобный способ взять что-то, что им нравится, в одном приложении и передать в другое приложение, воспользовавшись простым жестом у края экрана и выбором целевого приложения. Это похоже на буфер обмена с широкими семантическими возможностями, работая с которым, вы не задумываетесь о том, как подключиться к другим приложениям. Что особенно приятно в случае с контрактом Общий доступ, другими словами, что приложение-источник не должно заботиться о том, что произойдет с данными – его единственная задача – предоставить данные, подходящие для общего доступа в тот момент, когда пользователь активирует чудо-кнопку Общий доступ (если, на самом деле, это подходящие данные, а иногда это не так). Это освобождает приложение-источник от необходимости предсказывать, предвидеть или предугадывать то, что пользователи могут захотеть сделать с данными. Может быть, пользователь решит отправить их по электронной почте, может быть – в социальную сеть, или захочет поместить их в приложение для управления контентом… кто знает?

    Да, только пользоваель и знает, и брокер общего доступа делает с данными то, что решит пользователь! Получив пакет данных из источника, брокер сравнивает формат данных в пакете с форматами, которые поддерживают целевые приложения, объявив о них в манифесте. Затем брокер показывает список этих приложений пользователю. Этот список может содержать приложения, и то, что называется быстрой ссылкой (quicklink) (если быть точным, то это объекты Windows.ApplicationModel.DataTransfer.ShareTarget.Quicklink), которые поддерживают некоторые приложения, но более конкретным образом. Например, когда приложение электронной почты отображается в качестве целевого для нужд общего доступа, лучшее, что оно может сделать – это создать новое сообщение без указания конкретного адресата. Быстрая ссылка, однако, может идентифицировать конкретных получателей электронного письма, например, человека или людей, которым вы часто пишете письма. Быстрая ссылка, таким образом, это возможность выбрать целевое приложение с добавлением конкретной конфигурационной информации.

    В любом случае, когда пользователь выбирает цель, запускается какое-то приложение. В случае с контрактом Общий доступ, приложение запускается с видом активации shareTarget. Это сообщает ему о том, что ему не нужно показывать свой интерфейс по умолчанию, но, вместо этого, нужно показать специальную панель общего доступа (с возможностью автоматического скрытия при неактивности). С ее помощью пользователь может уточнить, что и как следует добавить в приложение из данных общего доступа. Например, на панели общего доступа для приложений социальных сетей часто предоставляют место для ввода комментария к данным перед их отправкой. Приложение электронной почты может предоставить средства для правки сообщения перед отправкой. Клиент сервиса для работы с фотографиями может позволить добавить подпись, указать место, где была снята фотография, людей, изображенных на фото и так далее. В общем, вы поняли. Все это, собрано вместе для обеспечения плавного взаимодействия пользователя и системы – от выбора данных, которыми он хочет поделиться, до указания приложения и настройки этих данных.

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

    Приложениям-источникам так же не нужно обновляться, когда, например, новая цель общего доступа становится популярной (например – новая социальная сеть): все, что нужно – это единственное целевое приложение. Что касается этих целевых приложений, им не нужно возвещать о себе всему миру: посредством контрактов приложения-источники автоматически получают возможность использовать любые целевые приложения, которые станут доступны в будущем. И, с точки зрения конечного пользователя, работа с чудо-кнопкой Общий доступ становится все интереснее и интереснее, когда он устанавливает больше программ, поддерживающих возможность Общего доступа.

    В то же время, приложение-источник может кое-что узнать о том, как использованы данные, предоставленные для общего доступа. Вместе с событием datarequested, DataTransferManager так же запускает событие targetApplicationChosen для прослушивающего это событие приложения-источника. В данном случае eventArgs содержит лишь одно свойство – applicationName (имя приложения). Это не особо полезно для любых других API WinRT, однако, эти сведения вы можете использовать для целей собственной аналитики. Подобные данные могут помочь вам понять, обеспечиваете ли вы лучший опыт взаимодействия, предоставляя в общий доступ больше форматов данных, например, или, если типичные целевые приложение поддерживают пользовательские форматы, вы можете включить их поддержку в будущих обновлениях программы.

    Приложения-источники

    Придем к окончательному пониманию приложений-источников, изучив некоторые подробности, которые мы еще не рассматривали, преимущественно касающиеся того, как приложение-источник заполняет пакет данных, и параметров, которые у него есть для обработки запроса. Для этой цели я предлагаю вам загрузить и запустить пару примеров: "Приложение-источник для общего доступа" (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Source-App-d9bffd84) и "Приложение-цель для общего доступа" (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782). Мы рассмотрим оба, а последний содержит хороший пример того, как целевое приложение принимает пакет данных, созданный в приложении-источнике.

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

    Windows.ApplicationModel.DataTransfer.DataTransferManager.showShareUI();

    Такой вызов, как и в случае, когда пользователь нажимает на чудо-кнопку, вызывает событие datarequested, где eventArgs.request – это объект ). Объект запроса содержит два свойства и два метода:

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

    deadline – это свойство типа Data, показывающее время в будущем, когда данные, которые вы сделали доступными, будут неактуальны (таким образом, не будут обработаны). Это позволяет учесть ситуацию, когда между запросом данных и реальной попыткой их использовать может пройти неопределенное время. В случае с отложенной обработкой данных, как отмечено выше для свойства data, возможно, что некоторые непостоянные источники данных могут исчезнуть. Когда это время отмечено в deadline, запросы на обработку, которые происходят позже него, будут проигнорированы.

    failWithDisplayText – это метод, который сообщает брокеру общего доступа, что в данный момент предоставление данных в общий доступ невозможно, так же предоставляется строка, которая сообщит пользователю, почему это так (возможно, ему нужно выделить что-нибудь). Вы вызываете это тогда, когда нет выделенных данных, формат которых подходит для предоставления в общий доступ, если произошла ошибка при заполнения пакета данных по любой другой причине. Текст, который вы предоставите, будет отображен в панели чудо-кнопки Общий доступ (и, таким образом, его следует локализовывать). Сценарий 8 примера о приложении-источнике показывает использование этого подхода в простом случае, когда он не предоставляет данных в ответ на событие datarequested.

    getDeferral предоставляется для асинхронных операций, которые могут вам понадобиться для заполнения пакета данных (это те же самые отложенные операции, которые используются везде в WinRT API). Отметим, что событие datarequested имеет тайм-аут в 200 мс, после чего в интерфейсе чудо-кнопки Общий доступ отобразится сообщение о невозможности немедленного предоставления данных в общий доступ. Запрос отложенной операции не меняет этот тайм-аут, он лишь предотвращает ситуацию, когда datarequested считает, что пакет данных готов как только вы возвратились из обработчика.

    Обычная структура обработчика datarequested, таким образом, направлена на заполнение минимальных свойств eventArgs.request.data и вызов eventArgs.request.failWithDisplayText по возникновению ошибки. Мы встретимся с этой структурой в большинстве сценариев примера:

     var dataTransferManager =
        Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
        // Удалите этот прослушиватель в соответствии с требованиями
        dataTransferManager.addEventListener("datarequested", dataRequested);
    
        function dataRequested(e) {
        var request = e.request;
    
        // Нужен заголовок (Title)
        var dataPackageTitle = document.getElementById("titleInputBox").value;
    
        if ( /* Проверяем, есть ли подходящие для целей общего доступа данные */ ) {
        request.data.properties.title = dataPackageTitle;
    
        // Параметр description необязателен.
        var dataPackageDescription = document.getElementById("descriptionInputBox").value;
        request.data.properties.description = dataPackageDescription;
        // Вызываем request.data.setText, setUri, setBitmap, setData, и так далее.
        } else {
        request.failWithDisplayText(/* Сообщение об ошибке */ );
        }
        }

    Как мы здесь видим, объект )), это то место, куда вы записываете данные наподобие заголовка и описания пакета данных. Вот другие свойства:

  • ).
  • applicationName – это строка, которая помогает целевому приложению получить ту же информацию, которую источник может получить из события targetApplicationChosen.
  • ), но он может содержать и сведения о пользовательских форматах.
  • size – количество элементов, если данные в пакете – это коллекция, например, коллекция файлов.
  • thumbnail – поток, содержащий изображение-эскиз. Обычно именно из-за надобности получения этого изображения и используют метод DataRequest.getDeferral.
  • Помимо этого объект data.properties так же поддерживает пользовательские свойства, посредством своих методов insert, remove и других. Это делает для приложения-источника возможным передавать пользовательские свойства вместе с пользовательскими форматами, делая все это расширяемым, если новые форматы данных станут широко распространенными в будущем.

    В вышеприведенном коде, основная задача приложения-источника заключается в заполнении пакета данных с помощью вызова различных set*-методов пакета. Для стандартных форматов, которые описаны в перечислении StandardDataFormats, это отдельные методы: setText, setUri, setHtmlFormat, setRtf (rich text format, довольно ранний предшественник HTML), setBitmap, и setStorageItems (для папок и файлов). Все эти методы, кроме setRtf, представлены в коде примера.

    Общий доступ к тексту – Сценарий 1 (js/text.js):

    var dataPackageText = document.getElementById("textInputBox").value;
        request.data.setText(dataPackageText);

    Передача в общий доступ ссылки – Сценарий 2 (js/link.js). Это можно использовать и для локального и для удаленного содержимого:

     request.data.setUri(new Windows.Foundation.Uri(document.getElementById("linkInputBox").value));

    Общий доступ к изображению и элементу хранения – Сценарий 3 (js/image.js):

          var imageFile; // StorageFile, полученный через средство выбора файлов
          //В событии datarequested
          var streamReference =
          Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
          request.data.properties.thumbnail = streamReference;
          // Рекомендуется всегда, для предоставления общего доступа, использовать и setBitmap и setStorageItems
          // для изображения, так как целевое приложение может поддерживать либо то, либо другое
    
          // Поместим файл изображения в массив и передадим его setStorageItems
          request.data.setStorageItems([imageFile]);
    
          // Метод setBitmap требует RandomAccessStreamReference
          request.data.setBitmap(streamReference);
        

    Общий доступ к файлам – Сценарий 4 (js/file.js)

    var selectedFiles; // Коллекция объектов StorageFile, полученных из средства выбора файлов
    
        // В событии datarequested
        request.data.setStorageItems(selectedFiles);

    Что касается общего доступа к HTML, то это может быть очень простой задачей, если HTML у вас есть в виде строки:

     request.data.setHtmlFormat(someHtml);

    Для этой цели вы можете воспользоваться полезным объектом Windows.ApplicationModel.DataTransfer.HtmlFormatHelper (http://msdn.microsoft.com/library/windows/apps/hh738437.aspx), который предоставляет методы для создания правильно отформатированной разметки. Справедливо по отношению к HTML и то, что он часто ссылается на другое содержимое, наподобие изображений, которые не включены непосредственно в разметку. Что же делать в такой ситуации? К счастью, дизайнеры API поработали над этим: вы можете использовать свойство пакета данных resourceMap для связывания относительных URI в HTML с потоком изображения. Мы видим это в Сценарии 6 (js/html.js):

      var path = document.getElementById("htmlFragmentImage").getAttribute("src");
        var imageUri = new Windows.Foundation.Uri(path);
        var streamReference =
        Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(imageUri);
        request.data.resourceMap[path] = streamReference;

    Еще одна интересная часть Сценария 6 – это та, которая заменяет пакет данных в eventArgs на новый, который она создает следующим образом:

    var range = document.createRange();
        range.selectNode(document.getElementById("htmlFragment")); request.data
        = MSApp.createDataPackage(range);

    Как вы можете видеть, метод ) берет диапазон DOM (в данном случае – часть текущей страницы) и создает из него пакет данных, где, при обработке, вызывается метод пакета setHtmlFormat (поэтому вы не увидите явного вызова этого метода в Сценарии 6). Ценно заметить, что имеется еще и метод ), который выполняет то же самое с текущим выделенным фрагментом DOM. Очевидно, вы воспользуетесь этим, если у вас есть элемент, который можно редактировать, данные которого вы хотите предоставить в общий доступ.

    Организация общего доступа к данным разных форматов

    Как показано в Сценарии 3, не только разрешено, но и рекомендовано, предоставлять в общий доступ к данным во всех возможных форматах, таким образом, получая больше потенциальных целевых приложений. Все это значит, что вы вызываете все методы set*, которые имеют смысл, в обработчике datarequested. Это включает в себя вызов setData для пользовательских форматов и setDataProvider для отложенной обработки, как описано в следующих двух разделах.

    Пользовательские форматы данных: schema.org

    Я думаю, что много лет назад дизайнеры API решили, что пытаться предвидеть все форматы данных, которыми могут обмениваться приложение, это – бесполезное занятие. API WinRT следует этой идее, поэтому вместе с методами set* для конкретных форматов, в DataPackage мы можем найти и общий метод setData. Он принимает идентификатор формата (строку) и данные для общего доступа. Это показано в Сценарии 7 примера с использованием формата "http://schema.org/Book" и данных в строковом формате JSON (js/custom.js):

     request.data.setData(dataFormat, JSON.stringify(book));

    Так как идентификатор пользовательского формата данных – это обычная строка, вы можете использовать здесь все, что хотите. Например, здесь могут быть полезны весьма специфичные форматы данных, например, в сценарии обмена данными, в котором участвует весьма специфичное целевое приложение, возможно то, которое вы сами и создали. Однако, если только вы не оповестили всех разработчиков о своем формате данных (и если только у вас нет бюджета для этого!), есть вероятность, что другие целевые приложения не будут иметь никакого понятия о ваших форматах данных.

    К счастью, имеется растущее количество соглашений, касающихся пользовательских форматов данных, которые поддерживает http://schema.org/ . Этот сайт является местом, где хранятся соглашения по пользовательским форматам, таким образом, мы настоятельно рекомендуем, чтобы вы брали форматы оттуда. Их полный список можно найти http://schema.org/docs/schemas.html .

    Вот JSON-данные в формате book, использованные в примере:

    var book = {
    type: "http://schema.org/Book", properties: {
    image: "http://sourceuri.com/catcher-in-the-rye-book-cover.jpg", name: "The Catcher in the Rye",
    bookFormat: "http://schema.org/Paperback",
    author: "http://sourceuri.com/author/jd_salinger.html", numberOfPages: 224,
    publisher: "Little, Brown, and Company", datePublished: "1991-05-01",
    inLanguage: "English", isbn: "0316769487"
    }
    };
        

    Вы можете легко выразить те же данные в виде обычного текста, HTML (или RTF), в виде ссылки (возможно, на страницу с этой информацией), и изображения (обложка книги). Так вы можете заполнить пакет данных полностью стандартными форматами вместе со специфическими пользовательскими форматами.

    Отложенные операции и отложенный рендеринг

    Откладывание, как упомянуто ранее, это простой механизм для задержки завершения события ) показывает пример использования этого механизма при загрузке файла изображения:

    var deferral = request.getDeferral();
    
    Windows.ApplicationModel.Package.current.installedLocation.getFileAsync( "images\\smalllogo.png")
    .then(function (thumbnailFile) {
    request.data.properties.thumbnail = Windows.Storage.Streams.
    RandomAccessStreamReference.createFromFile(thumbnailFile);
    return Windows.ApplicationModel.Package.current.installedLocation.getFileAsync( "images\\logo.png");
    })
    .done(function (imageFile) {
    request.data.setBitmap( Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile));
    deferral.complete();
    });
        

    Отложенный рендеринг – это другое дело, хотя процесс обычно использует откладывание. Его цель зкалючается в предотвращении рендеринга данных общего доступа до тех пор, пока целевое приложение не получит их, иногда это называют операциями отложенного общего доступа (pull operations). Методы set*, которые мы видели, выполняют копирование полных данных в пакет. Отложенный рендеринг (обработка) подразумевает вызов метода пакета данных setDataProvider (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.datatransfer.datapackage.setdataprovider.aspx) с идентификатором формата данных и функцией, которую нужно вызвать, когда понадобятся данные. Вот как это реализовано в Сценарии 5 примера приложения-источника, где imageFile выбирают с помощью средства выбора файлов (js/image.js):

    // Обеспечивая общий доступ к изображению, не забудьте установить эскиз для DataPackage
    var streamReference =
    Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
    request.data.properties.thumbnail = streamReference;
    request.data.setDataProvider(
    Windows.ApplicationModel.DataTransfer.StandardDataFormats.bitmap,
    onDeferredImageRequested);
        

    Как показано в комментариях, хорошо будет предоставить экскиз при использовании операции отложенного рендеринга, таким образом, у целевого приложения будет что показать пользователю. Таким образом, когда целевому приложению понадобятся полные данные, будет вызвана функция провайдера данных, в данном случае – onDeferredImageRequsted:

    function onDeferredImageRequested(request) {
    if (imageFile) {
    // Здесь мы предоставляем обновленные данные изображения с использованием отложенного рендендеринга
    var deferral = request.getDeferral();
    
    var imageDecoder, inMemoryStream;
    
    imageFile.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {
    // Декодируем изображение
    return Windows.Graphics.Imaging.BitmapDecoder.createAsync(stream);
    }).then(function (decoder) {
    // Перекодируем изображение до 50% ширины и высоты
    inMemoryStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
    imageDecoder = decoder;
    return Windows.Graphics.Imaging.BitmapEncoder.createForTranscodingAsync(
    inMemoryStream, decoder);
    }).then(function (encoder) {
    encoder.bitmapTransform.scaledWidth = imageDecoder.orientedPixelWidth * 0.5;
    encoder.bitmapTransform.scaledHeight = imageDecoder.orientedPixelHeight * 0.5;
    return encoder.flushAsync();
    }).done(function () {
    var streamReference = Windows.Storage.Streams.RandomAccessStreamReference
    .createFromStream(inMemoryStream);
    request.setData(streamReference);
    deferral.complete();
    }, function (e) {
    // операция не выполнена, но нам нужно выйти из отложенной операции deferral для того
    //чтобы целевое приложение не зависло
    deferral.complete();
    });
    }
    }
        

    Обатите внимание на то, что эта функция принимает упрощенный гибрид объектов ), который содержит свойства deadline и formatId, метод getDeferral и метод setData, посредством которого вы предоставляете данные, которые соответствуют formatId. Свойство deadline, как вы можете догадаться, это то же свойство, что обработчик datarequested может сохранить в объекте DataRequest.

    Целевые приложения

    Возвращаясь к рис. 1.1, мы можем видеть, что хотя взаимодействие между приложением-источником и брокером общего доступа к данным управляется единственным событием datarequested, взаимодействие между брокером и целевым приложением устроено немного сложнее. С одной стороны, брокер должен определить, какое приложение потенциально может обработать конкретный пакет данных, для чего каждое целевое приложение содержит соответствующие детали в своем манифесте. Когда приложение выбрано, оно запускается с видом активации shareTarget, в ответ на это оно должно показать специальный пользовательский интерфейс общего доступа, вместо полного интерфейса приложения.

    Посмотрим, как все это работает с помощью примера "Приложение-цель для общего доступа" (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782), вид которого показан на рис. 1.2. Убедитесь в том, что сначала запустили приложение в Visual Studio, чтобы оно было установлено и появилось бы в списке приложений, когда мы активируем чудо-кнопку Общий доступ.

    (рис 1.2) Внешний вид примера целевого приложения

    Первый шаг целевого приложения заключается в объявлении форматов данных, которые оно может принимать, в разделе Объявления (Declarations) манифеста, вместе со страницей, которая будет открыта, когда предложение будет выбрано в качестве целевого. Как показано на рис. 1.3., в примере целевого приложения указано, что приложение может работать с текстом, URI, изображениями, HTML и форматом http://schema.org/Book , так же заявлено о том, что оно может обрабатывать любые файлы, которые могут содержаться в пакете данных (вы можете задать здесь конкретные типы файлов). В нижней части панели указано, что страница приложения target.html будет использоваться в качестве страницы, выводимой на панель Общего доступа.

    (рис 1.3) Объявления в манифесте приложения из примера целевого приложения

    Начальная страница для общего доступа – это обычная HTML-страница с любым необходимым вам макетом для выполнения задачи общего доступа. Эта страница обычно функционирует независимо от основного приложения. Когда приложение выбирают в качестве цели для общего доступа, эта страница загружается и активируется самостоятельно и, таким образом, имеет полностью собственный скриптовый контекст. На этой странице не следует размещать навигационные элементы, ведущие к другим частям приложения, и она должа содержать лишь код, который необходим для задач общего доступа к данным (Параметры Исполняемый файл (Executable) и Точка входа (Entry point) не используются приложениями, написанными на HTML и JavaScript, они существуют для приложений, написанных на других языках).

    Большая часть ее структуры может быть создана автоматически с использованием Шаблона элемента контракта получателя данных (Share Target Contract item template), который предоставляется Visual Studio и Blend, как показано на рис. 1.4. Диалоговое окно появляется, после того, как вы щелкнете правой кнопкой мыши по проекту и выберете команду Добавить > Создать элемент (Add > New Item), или воспользуетесь командой меню Проект > Создать новый элемент (Project > Add New Item).

    (рис 1.4) Шаблона элемента контракта получателя данных в Visual Studio и Blend

    Данный шаблон элемента предоставит вам HTML, JS и CSS-файлы для создания страницы целевого приложения и добавит эту страницу в объявление манифеста вместе с указанием поддержки текстового формата и формата URI. Вам лишь останется соответствующим образом отредактировать эти данные.

    Прежде чем мы рассмотрим код, вот несколько замечаний о дизайне страницы для приложения-получателя данных, они представляют собой краткое изложение материала "Руководство по общему доступу к содержимому" ( http://msdn.microsoft.com/library/windows/apps/hh465251.aspx):

  • Сохраняйте индивидуальность приложения, его внешний вид, и удобство работы с ним, на уровне основного приложения.
  • Обеспечьте простоту взаимодействий для быстрого выполнения задач по общему доступу. Избегайте форматирования текста, пометок людей на фотографиях или задач по установке, но предоставьте возможности по редактированию содержимого, особенно, если отправляете данные в социальные сети или отправляете сообщение. (Посмотрите на рис. 12.5., где в качестве примера приведено приложение Mail (Почта)). Целевые приложения социальных сетей обычно подразумевают возможность комментирования, в приложения-получателя фотографий, возможно, есть смысл включить функцию добавления подписи к фотографии.
  • Сведите к минимуму навигацию: задача общего доступа предусматривает собственную рабочую среду, поэтому используйте встроенные элементы управления и встроенные сообщения об ошибках вместо переключения на другие страницы. Другая причина избегать этого заключается в том, что страница обеспечения функциональности общего доступа исполняется в собственном скриптовом контексте, поэтому возможность перехода в приложение, в другой контекст, может смутить пользователя.
  • Избегайте использования ссылок, которые могут отвлечь пользователя от задачи общего доступа или увести его в другое место. Помните, что общий доступ – это способ упростить процесс получения данных из одних приложений в другие, который традиционно является достаточно утомительным. Поэтому сконцентрируйте все усилия интерфейса общего доступа целевого приложения на этой задаче.
  • Избегайте использования автоматического скрытия неактивных всплывающих элементов, так как интерфейс чудо-кнопки Общий доступ уже обладает подобной функциональностью.
  • Подтверждайте действия пользователя, когда вы начинаете отправлять данные (на сетевой сервис, например), чтобы пользователь знал, что что-то действительно происходит.
  • Расположите важные кнопки в пределах досягаемости больших пальцев. Обратитесь к материалу "Состояние сенсорного ввода Windows 8" (http://msdn.microsoft.com/library/windows/apps/hh465415.aspx#touch_posture) для того, чтобы прочесть руководство по размещению элементов.
  • Постарайтесь сделать то, как выглядят элементы в режиме предварительного просмотра, соответствующим их реальному внешнему виду. Другими словами, не показывайте пользователю фокусы!
  • В случае с дизайном этой страницы, полезно знать, что вам не нужно беспокоиться о различных режимах просмотра – страница существует лишь в одном состоянии (как всплывающий элемент, она не может отображаться в прикрепленном режиме). Однако, ей нужно подстраиваться под различные размеры экрана, помните об этом, но не под различные режимы просмотра. Здесь хорошо подойдет макет, основанный на CSS-сетке с дробными размерами строк и столбцов.

    Предупреждение. Так как целевое приложение может принимать данные от любого приложения-источника, ему следует расценивать такое содержимое как недоверенное и потенциально опасное, особенно когда речь идет об HTML, URI и файлах. Целевое приложение должно избегать добавления подобного HTML или содержимого файлов в DOM, исполнять код из URI, переходить по URI или к каким-то другим страницам на основе URI, модифицировать записи базы данных, использовать eval с данными и так далее.

    (рис 1.5) Интерфейс общего доступа в приложении Windows Mail (Почта Windows) (нижняя пустая часть была обрезана). Этот пользовательский интерфейс позволяет править адрес получателя, тему и тело сообщения и отправлять изображение в виде вложения или ссылки на файл в SkyDrive

    Подсмотрим на полное содержимое JavaScript-файла шаблона, так как это показывает нам основные механизмы целевого приложения. Во-первых, как вы можете видеть, у нас есть те же структуры, что и в обычном default.js приложения, мы используем методы и события объекта WinJS.Application.

    (function () { "use strict";
    
    var app = WinJS.Application;
    var share;
    
    function onShareSubmit() {
    document.querySelector(".progressindicators").style.visibility = "visible";
    document.querySelector(".commentbox").disabled = true;
    document.querySelector(".submitbutton").disabled = true;
    
    // TODO: Выполните какие-либо действия с данными общего доступа из переменной 'share'.
    
    share.reportCompleted();
    }
    
    // Эта функция ответственна за различные виды активации приложения.
    app.onactivated = function (args) {
    var thumbnail;
    
    if (args.detail.kind ===
    Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
    document.querySelector(".submitbutton").onclick = onShareSubmit;
    share = args.detail.shareOperation;
    
    document.querySelector(".shared-title").textContent =
    share.data.properties.title;
    document.querySelector(".shared-description").textContent =
    share.data.properties.description;
    
    thumbnail = share.data.properties.thumbnail;
    if (thumbnail) {
    // Если данные общего доступа содержат эскиз, отобразим его.
    args.setPromise(thumbnail.openReadAsync().then(
    function displayThumbnail(stream) {
    document.querySelector(".shared-thumbnail").src =
    window.URL.createObjectURL(stream, { oneTimeOnly: true });
    }));
    } else {
    // Если эскиз не представлен, развернем элементы описания и
    // заголовка для того, чтобы заполнить неиспользуемое пространство.
    document.querySelector("section[role=main] header").style
    .setProperty("-ms-grid-columns", "0px 0px 1fr");
    document.querySelector(".shared-thumbnail").style.visibility = "hidden";
    }
    }
    };
    
    app.start();
    })();
        

    Когда загружается и активируется эта страница, в течение этого времени отображается экран-заставка приложения, выполняется ее событие WinJS.Application.onactivated – снова, независимо от обработчика activated основного приложения, который обычно находится в default.js. Так как мы работаем с целевым приложением для общего доступа к данным, мы проверяем, является ли тип активации shareTarget, после чего ваша основная задача – предоставить предварительный просмотр данных, которые поступают в приложение вместе с любым пользовательским интерфейсом, который предусмотрен для редактирования данных, комментирования и так далее. Обычно здесь так же имеется кнопка для завершения операции или передачи данных, нажатие на которую сообщает брокеру общего доступа, что операция завершена.

    Ключевым моментом здесь является объект ), свойство data которого содержит пакет данных только для чтения, который называется DataPackageView (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.datatransfer.datapackageview.aspx), откуда вы получаете все, что вам нужно:

  • Для того чтобы проверить, содержатся ли в пакете данные в форматах, которые может принять ваше приложение, используйте метод contains или коллекцию availableFormats.
  • Для того, чтобы получить данные из пакета, используйте его методы get*, такие, как getTextAsync, getBitmapAsync, и getDataAsync (для пользовательских форматов). При вставке HTML вы так же можете использовать метод getResourceMapAsync для получения URI связанных ресурсов. Свойства (properties), имеющие отношение к отображению, такие как thumbnail, так же полезны для предоставления возможности предварительного просмотра данных.
  • Как видите, код из шаблона элемента контракта получателя данных, приведенный выше, ничего не делает с полученными данными, лишь отображает заголовок, описание и эскиз. Очевидно, ваше приложение будет делать нечто большее, чем просто запрашивать данные из пакета, как этот пример. Его файл js/target.js содержит обработчик activated для страницы target.html (в корне проекта) и она так же отображает эскиз из пакета данных по умолчанию. Затем они просматривает пакет на предмет различных форматов данных и выводит это содержимое, если оно присутствует:

    if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.
    text)) {
    shareOperation.data.getTextAsync().done(function (text) {
    displayContent("Text: ", text, false);
    });
    }
    Похожий код появляется и для простых форматов. Прием данных изображения требует немного больше работы, но он весьма прост:
    if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.
    bitmap)) {
    shareOperation.data.getBitmapAsync().done(function (bitmapStreamReference) {
    bitmapStreamReference.openReadAsync().done(function (bitmapStream) {
    if (bitmapStream) {
    var blob = MSApp.createBlobFromRandomAccessStream(bitmapStream.contentType, bitmapStream);
    document.getElementById("imageHolder").src = URL.createObjectURL(blob,
    { oneTimeOnly: true });
    document.getElementById("imageArea").className = "unhidden";
    
    }
    });
    });
    }
        

    Для обработки HTML, он просматривает разметку на предмет поиска элементов img, затем устанавливает их атрибуты src в соответствии с картой ресурсов (iframe к этому моменту уже содержит HTML-содержимое из пакета)

    var images = iFrame.contentDocument.documentElement.getElementsByTagName("img");
    if (images.length > 0) {
    shareOperation.data.getResourceMapAsync().done(function (resourceMap) {
    if (resourceMap.size > 0) {
    for (var i = 0, len = images.length; i < len; i++) {
    var streamReference = resourceMap[images[i].getAttribute("src")];
    if (streamReference) {
    // Вызов вспомогательной функции для установки src элементов изображений
    // на соответствующие URL больших двоичных объектов, созданных из streamReference 
    setResourceMapURL(streamReference, images[i]);
    }
    }
    }
    });
    }

    Вспомогательная функция setResourceMapURL выполняет довольно много операций, специфичных для обработки изображений. В частности, в ней вызывается openReadAsync для потока, осуществляется вызов MSApp.createBlobFromRandomAccessStream, полученный большой двоичный объект передается URL.createObjectURL, результат записывается в img.src, и поток закрывается.

    После того, как целевое приложение завершило операцию получения данных, оно должно вызвать метод ShareOperation.reportCompleted, как показано ранее в коде шаблона. Это позволяет системе узнать, что пакет данных принят, набор операций по предоставлению общего доступа к данным завершен, и все связанные с этим ресурсы можно освободить. Целевое приложение в примере выполняет это, когда вы нажмете на кнопку, предназначенную для этой цели, но обычно вы автоматически вызываете метод, когда вы завершаете операцию общего доступа. Хочу предупредить вас, что вызов reportCompleted закроет интерфейс работы с общими данными целевого приложения, поэтому старайтесь не вызывать его как только целевое приложение активировалось: желательно, чтобы пользователь чувствовал уверенность в том, что операция была проведена.

    Операции, выполняемые длительное время

    Когда вы запустите пример реализации целевого приложение и нажмете на чудо-кнопку Общий доступ, находясь в подходящем приложении-источнике данных, внизу будет небольшой разворачиваемый элемент, подписанный как "Поддержка общего доступа, требующего большого количества времени" ("Long-running Share Support"). Если вы развернете этот элемент, вы увидите некоторые дополнительные элементы управления и много описаний, как показано на рис. 1.6. Кнопки, показанные здесь, связаны с другими методами объекта ShareOperation наряду с reportCompleted. Это помогает Windows точно понять, как операция общего доступа обрабатывается внутри целевого приложения: reportStarted, reportDataRetrieved, reportSubmittedBackgroundTask, и reportError. Как вы можете видеть из рис. 1.6, это имеет отношение к тому, чтобы сообщить Windows, когда приложение закончит, так сказать, готовить обед, и система может вымыть посуду и убраться на кухне.

  • reportStarted сообщает Windows, что ваша операция общего доступа может занять некоторое время, как в случае, если вы отправляете данные из пакета в другое место, или просто отправляете в виде вложения электронной почты большие изображения и тому подобное. Этот метод показывает, что вы приняли весь необходимый ввод пользователя и что панель общего доступа может быть закрыта.
  • reportDataRetrieved сообщает Windows, что вы извлекли из пакета данных все, что вам нужно, и он, таким образом, может быть освобожден. Если вы, например, вызывали MSApp.createBlobFromRandomAccessStream для потока изображения, полученный большой двоичный объект теперь содержит копию изображения, которая является локальной для целевого приложения. Если вы используете изображения из свойства пакета resourceMap, с другой стороны, вам не нужно вызывать reportDataRetrieved до тех пор, пока вы явным образом не сделаете копию данных, на которые ссылаются URI внутри пакета данных. В любом случае, если вам нужно сохранять пакет в течение всей операции, вам не нужно вызывать этот метод, так как позже вы вызовете reportCompleted для освобождения пакета.
  • ). Как следует из описания, приведенного на рис. 12.6., это позволяет Windows знать, что она может приостановить целевое приложение и не беспокоиться об операции общего доступа. Если вы вызываете этот метод, работая с локальной копией данных для загрузки, пройдите дальше и вызовите метод reportCompleted, таким образом Windows сможет освободить пакет. В противном случае дождитесь окончания передачи данных.
  • reportError позволяет Windows узнать, не произошла ли ошибка в течение операции общего доступа.
  • (рис 1.6) Развернутое окно, демонстрирующее поддержку общего доступа, требующего большого количества времени, в примере целевого приложения. Кнопка Repopt Completed (Сообщить о завершении) отображается всегда и не является специфической для подобных операций, несмотря на ее расположение в пользовательском интерфейсе примера. Не позвольте этому вас запутать!

    Быстрые ссылки

    Последний аспект контракта Общий доступ, который нам осталось изучить, это то, о чем мы уже упоминали раньше: быстрые ссылки (quicklinks). Они служат для более рациональной реализации операций общего доступа, таким образом, что пользователям не нужно повторно вводить информацию в целевые приложения. Например, если пользователь часто передает данные конкретным людям по электронной почте, каждый контакт может выступать в роли быстрой ссылки для приложения электронной почты. Если пользователь обычно отправляет данные разным людям или группам людей посредством приложения для работы с социальными сетями, эти люди, или группы, так же могут быть представлены в виде быстрых ссылок. И, так как эти целевые объекты более специфичны для конкретного пользователя, чем обычные цели общего доступа, пользовательский интерфейс чудо-кнопки Общий доступ выводит их в верхней части списка (рис. 1.7).

    Каждая быстрая ссылка связана с конкретным целевым приложением и обслуживается им, просто предоставляя идентификатор для этого целевого приложения. Когда целевое приложение активируется посредством быстрой ссылки, оно использует идентификатор для получения данных, связанных с данной быстрой ссылкой и осуществляет предварительное заполнение или иную настройку пользовательского интерфейса. Важно понимать, что быстрые ссылки содержат только идентификатор, таким образом, целевое приложение должно хранить и получать связанные с ним данные из каких-то других источников, обычно из локальных данных приложения, где идентификатор является именем файла, именем контейнера параметров и так далее. Целевое приложение может так же использовать для этой цели перемещаемые данные приложения или облачные данные, но сами быстрые ссылки не перемещаются на другие устройства – они ограничены локальным использованием. Таким образом, имеет смысл хранить связанные с ними данными локально.

    Сами по себе быстрые ссылки – это лишь экземпляры класса ). Их создают с помощью оператора new и затем заполняют их свойства title, thumbnail, supportedDataFormats, supportedFileTypes, и id. Форматы данных и типы файлов – это то, что Windows использует для того, чтобы определить, следует ли показывать конкретные быстрые ссылки в списке целевых объектов для данных, предоставляемых в общий доступ из приложения-источника (независимо от объявлений в манифесте). Свойства title и thumbnail используются для отображения быстрых ссылок в интерфейсе чудо-кнопки Общий доступ, id – это то, что передается целевому приложению при выборе быстрой ссылки.

    Совет. Для эскизов (thumbnail), используйте изображение, которое способно точно представить быструю ссылку (например, фотографию из контакта), вместо изображения, соответствующего целевому приложению. Это помогает отличить быструю ссылку от общего элемента для вызова целевого приложения.

    Затем приложение регистрирует быструю ссылку в системе, передавая ее методу ShareOperation.reportCompleted. Так как это единственный способ регистрации быстрых ссылок, это говорит нам о том, что создание быстрой ссылки всегда происходит как часть другой операции общего доступа. Это способо создания конкретных целей, которые могут сберечь пользователю немного времени и вдохновить его на использование вашего целевого приложения снова в будущем.

    Посмотрим, как все это работает в примере целевого приложения для общего доступа. Для начала, когда вы активируете чудо-кнопку Общий доступ и выбираете приложение-пример, вы увидите, что оно предоставляет флаг для создания быстрой ссылки (рис. 1.7). Когда вы устанавливаете этот флаг, он предоставляет поля, в которые вы можете ввести идентификатор (id) и заголовок (title) (эскиз (thumbnail) просто использует приложение по умолчанию). Когда вы нажимаете на кнопку Report completed (Сообщить о завершении), вызывается метод reportCompleted и быстрая ссылка регистрируется в системе. При последующих обращениях к чудо-кнопке Общий доступ, при наличии у приложения-источника подходящих данных, эта быстрая ссылка появится в списке, как показано на рис. 1.8, а название приложения, обслуживающего быструю ссылку всегда отображается под заданным заголовком быстрой ссылки.

    (рис 1.7) Элементы управления для создания быстрой ссылки в примере целевого приложения для общего доступа (рис 1.8) Быстрая ссылка для приложения из примера целевого приложения для общего доступа появляется в списке целевых объектов чудо-кнопки Общий доступ

    Вот как в этом примере создается быстрая ссылка в функции reportCompleted (js/target.js), которая связана с кнопкой Report completed (Сообщить о завершении) (некоторые проверки ошибок опущены):

    if (addQuickLink) {
    var quickLink = new Windows.ApplicationModel.DataTransfer.ShareTarget.QuickLink();
    
    var quickLinkId = document.getElementById("quickLinkId").value;
    quickLink.id = quickLinkId;
    
    var quickLinkTitle = document.getElementById("quickLinkTitle").value;
    quickLink.title = quickLinkTitle;
    
    // Для быстрых ссылок поддерживаемые типы файлов (FileTypes) и 
    форматы данных (DataFormats) задаются независимо
    
    // от манифеста
    var dataFormats = Windows.ApplicationModel.DataTransfer.StandardDataFormats;
    quickLink.supportedFileTypes.replaceAll(["*"]);
    quickLink.supportedDataFormats.replaceAll([dataFormats.text, dataFormats.uri,
    dataFormats.bitmap,
    dataFormats.storageItems, dataFormats.html, customFormatName]);
    
    // Подготавливаем значок для QuickLink
    Windows.ApplicationModel.Package.current.installedLocation.getFileAsync(
    "images\\user.png").done(function (iconFile) {
    quickLink.thumbnail = Windows.Storage.Streams.RandomAccessStreamReference
    .createFromFile(iconFile);
    shareOperation.reportCompleted(quickLink);
    });
        

    Опять же, здесь лишь создается объект QuickLink, устанавливаются его свойства (возможно, более точно передающий его смысл эскиз, такой, как изображение из контактных сведений), и он передается в reportCompleted. В примере целевого приложения вы можете заметить, что для быстрой ссылки не хранятся локальные данные, в данном случае достаточно свойств самой быстрой ссылки. Большинство целевых приложений, однако, скорее всего будут хранить некоторые данные для быстрой ссылки, связанные с ее свойством quicklink.id и загружающие данные, когда приложение активировано посредством быстрой ссылки.

    Когда приложение активируется таким способом, объект eventArgs.detail.shareOperation в обработчике события активации будет содержать quicklinkId. Целевое приложение из примера просто отображает этот идентификатор, однако, на практике его обычно используют для загрузки данных приложения и предварительного заполнения пользовательского интерфейса:

    // Если приложение было активировано через быструю ссылку,  QuickLink, показать QuickLinkId
    if (shareOperation.quickLinkId !== "") {
    document.getElementById("selectedQuickLinkId").innerText = shareOperation.quickLinkId;
    document.getElementById("quickLinkArea").className = "hidden";
    }
        

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

    Буфер обмена

    Еще до того, как был придуман контракт Общий доступ, механизм, который мы знакм как буфер обмена (clipboard) представлял собой яркий пример средства для организации обмена данными между приложениями. И хотя сегодня он не может привлечь к себе большого внимания, он по-прежнему остается проверенным и надежным средством для обмена данными.

    Для приложений Магазина Windows взаимодействие с буфером обмена построено на том же самом механизме DataPackage, который мы уже видели в применении его к механизму общего доступа. Поэтому все, что мы узнали о заполнении этого пакета, об использовании пользовательских форматов, об использовании отложенного рендеринга применимо и к буферу обмена. В самом деле, если вы делаете данные доступными в буфере обмена, вам следует убедиться, что те же данные доступны для контракта Общий доступ!

    Вопрос заключается в том, как подключить команды, наподобие команд Копировать, Вырезать, Вставить, из панели приложения, контекстного меню или инициированные сочетаниями клавиш, которые приложению следует предоставить для собственного содержимого (многие элементы управления автоматически работают с буфером обмена). Для этих целей мы можем обратиться к классу ).

    Как показано в примере "Буфер обмена" (http://code.msdn.microsoft.com/windowsapps/Clipboard-App-sample-309ec122), этот процесс достаточно прост. В частности, для копирования и вырезания:

  • Создайте новый Windows.ApplicationModel.DataTransfer.DataPackage (или используйте MSApp.createDataPackage или MSApp.createDataPackageFromSelection), и заполните его нужными данными.
      var dataPackage = new Windows.ApplicationModel.DataTransfer.DataPackage();
        dataPackage.setText(textValue);
        //...
  • (Не обязательно) установите свойство пакета ): copy, move , link, или none (последнее используется для отложенного рендеринга). Отметим, что эти значения можно комбинировать, используя побитовый оператор ИЛИ. Например:
     var dpo = Windows.ApplicationModel.DataTransfer.DataPackageOperation;
        dataPackage.requestedOperation = dpo.copy | dpo.move | dpo.link;
  • Передайте пакет данных Windows.ApplicationMode.DataTransfer.Clipboard.setContent:
     Windows.ApplicationModel.DataTransfer.Clipboard.setContent(dataPackage);
  • Для выполнения операции вставки:

  • Вызовите ):
      var dataView = Windows.ApplicationModel.DataTransfer.Clipboard.getContent();
  • Проверьте, с помощью метода contains, содержит ли он форматы, которые вы можете принять (в качестве альтернативы, вы можете проверить содержимое вектора availableFormats):
     if (dataView.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.
          text)) {
          //...
          }
  • Получите данные, используя методы get*, такие, как getTextAsync, getBitmapAsync, и getDataAsync (для пользовательских форматов). Вставляя HTML вы так же можете использовать метод getResourceMapAsync для получения URI ресурсов. Свойства представления, наподобие thumbnail, так же полезны, как и значение или значения requestedOperation.
     dataView.getTextAsync().done(function (text) {
          // Принимаем данные
          }
  • Если вы, в любое время, захотите очистить содержимое буфера обмена, воспользуйтесь методом clear класса Clipboard. Так же вы можете убедиться в том, что данные доступны другим приложениям даже при закрытии вашего приложения, вызвав метод flush (он инициирует любые операции отложенного рендеринга, которые вы предусмотрели).

    Приложения, которые используют буфер обмена, так же нуждаются в информации о том, когда нужно активировать или деактивировать команду вставки в зависимости от доступных форматов. В любое время вы можете получить отображение пакета данных из буфера обмена и использовать его метод contains или свойство availableFormats и принять соответствующее решение. Так же вам следует прослушивать событие contentChanged (это событие WinRT) объекта Clipboard, которое будет выполнено, когда ваше приложение, или какое-то другое приложение, вызовет метод setContetn буфера обмена. Во время, заданное параметром time, вы активируете или деактивируете команды. Конечно, вы не будете принимать эти события, если ваше приложение приостановлено, поэтому, если вы хотите обновить сведения о состоянии этих команд, выполните это в обработчике возобновления работы.

    Пример работы с буфером обмена предоставляет примеры этих сценариев, в том числе, копирование и вставку текста и HTML (Сценарий 1); копирование и вставку изображения (Сценарий 2); копирование и вставу файлов (Сценарий 3); и очистку буфера обмена, перечисление форматов и обработку contentChanged (Сценарий 4).

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

    Страницы:

    Введение

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

    Весьма ярко этот персонаж проявил себя в сцене на бензоколонке. К нему подошел нищий с табличкой: "Буду работать за еду". Увидев это, наш герой предложил ему яблоко в обмен на то, чтобы тот помыл лобовое стекло его машины. Но когда тот нищий отказался, не соблюдя, таким образом, письменный контракт, герой Купера весьма расстроился… до состояния, когда он объявляет о своей неизлечимой болезни, распахивает рубашку и показывает пояс из взрывчатки с десятисекундным таймером, на котором уже начался обратный отсчет.

    В итоге, он уезжает с чистым лобовым стеклом и с чувством удовлетворения от того, что помог кому-то, хотя и странным способом, соблюсти свою часть письменного соглашения. Он появляется и позже, в городе, в котором живут одни адвокаты да полицейские… Предлагаю вам попытаться представить, что там произошло, или, по крайней мере, насладиться фильмом.

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

    Такова природа различных контрактов в Windows 8, которые, в целом, возможно, являются одной из наиболее мощных возможностей во всей системе. Главную цель контрактов можно описать как "Запуск приложения с определенной целью и в определенном контексте". Таким образом, вместо того, чтобы запускать приложения изолированно, контракты позволяют запускать их в связи с нуждами других приложений в контексте этих приложений. Информация может быть, таким образом, передана для реального использования напрямую из приложения в приложение, вместо передачи ее через обычное посредничество файловой системы, где теряется связь между приложениями.

    В случае с любым контрактом, одна сторона – это потребитель или приемник информации, передаваемой посредством контракта. Другая сторона – это источник или поставщик этой информации. Сам по себе контакт – это нечто общее: ни одна из сторон не нуждается в знании подробностей о другой, ей лишь нужно знать о своей стороне контракта. Это может звучать не особенно сильно, но это дает высокую степень расширяемости, которая становится все больше и больше при установке в систему приложений, которые поддерживают те или иные контракты. Я полагаю, что когда пользователи начнут испытывать возможности, которые предоставляют контракты, они все больше и больше будут искать в Магазине Windows приложения, которые используют контракты для обогащения их системы и создания более насыщенного опыта взаимодействия с системой.

    Что касается приложений, использование контрактов обычно происходит посредством вызовов API, таких, как средство выбора файлов, или через использование встроенных возможностей интерфейса системы, таких, как Панель чудо-кнопок. Предоставление информации для контрактов часто выглядит интереснее, так как приложению нужно отреагировать на специфические события (если оно выполняется), или сообщить о возможностях посредством манифеста и затем обрабатывать различные варианты активации контрактов.

    Таблица ниже содержит краткое описание всех контрактов и расширений Windows 8 (в алфавитном порядке), некоторые из которых позволяют приложениям работать вместе, в то время как другие позволяют приложениям расширять функциональность системы. Их полное описание можно найти в материале "Контракты и расширения приложений" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh464906%28v=VS.85%29.aspx). Те, о которых речь идет в этой лекции, выделены зеленым: Общий доступ (Share), Поиск (Search), сопоставление типов файлов и схем универсальных кодов ресурсов (URI) (file type and URI scheme association), средства выбора файлов (file pickers), обновление кэшированных файлов (cached file updater) и окно выбора контактов (людей) (contacts (people)). Другие контракты либо обсуждаются в указанных лекциях, некоторые из них я оставил для вашего самостоятельного изучения с использованием документации и примеров.

    Совет. Для того чтобы сравнить различные возможности обмена данными – контракт Общий доступ (Share), буфер обмена (clipboard), контракт средства сохранения файлов (file save picker), посмотрите материал "Общий доступ к данным и обмен данными" (http://msdn.microsoft.com/library/windows/apps/hh464923.aspx) в Центре разработчиков Windows. Он показывает различные сценарии для каждой из возможностей, и случаи, когда вы можете реализовать больше, чем одну из них в приложении.

    Кроме того, обратите внимание на то, что эти контракты используют множество событий WinRT, поэтому помните о необходимости вызова removeEventListener, как это описано в лекции 3 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript".

    Контракт / Расширение Поставщик Потребитель Описание, Документация и Примеры
    Поставщик аватаров (Account picture provider) (лекция 3) Приложение, которое может работать с изображениями. Windows (изображение в учетной записи) Когда пользователь меняет аватар, он может либо выбрать из существующих изображений, либо получить его от какого-либо приложения-поставщика. Смотрите пример "Имя для аватара" (http://code.msdn.microsoft.com/windowsapps/Account-picture-name-sample-912baff1).
    Автозапуск (AutoPlay) (лекция 4) Приложение, которое может быть перечислено в списке действий при автозапуске. Windows Смотрите материал "Запуск приложения с помощью автозапуска" (http://msdn.microsoft.com/library/windows/apps/hh452731.aspx) и пример "Съемные запоминающие устройства" (http://code.msdn.microsoft.com/windowsapps/Removable-Storage-52cc49f0).
    Фоновые задачи (Background tasks) (лекции 2 и 3) Приложения, имеющие фоновые задачи Windows Позволяет приложение исполнять небольшие задачи в фоновом режиме (то есть, когда, в противном случае, приложение приостановлено или не исполняется), без необходимости взаимодействия с пользователем. Смотрите материал: "Введение в фоновые задачи" (http://www.microsoft.com/en-us/download/details.aspx?id=27411) и лекцию 2. Фоновая передача файлов – это особый случай, поддерживаемый специальным API; смотрите материал "Передача данных в фоновом режиме" (http://msdn.microsoft.com/library/windows/apps/hh452979.aspx) и лекцию 3.
    Контракт обновления кэшированных файлов (Cached file updater) Приложения, которые предоставляют доступ к своим данным с помощью средства выбора файлов и нуждаются в синхронизации их обновления. Приложения, использующие API средства выбора файлов и файловые API для управления ими. Приложение-поставщик может позволить потребителю получить кэшированную копию файла. С помощью контракта поставщик может синхронизировать обновления между локальной копией и исходным файлом. Смотрите материал "Интеграция с контрактами "Средство выбора файлов" (http://msdn.microsoft.com/library/windows/apps/hh465174.aspx).
    Параметры камеры (Camera settings) Приложения с настраиваемым пользовательским интерфейсом камеры Пользовательский интерфейс камеры Windows Windows Camera Capture UI Смотрите материал "Разработка приложений Магазина Windows для камер" (http://msdn.microsoft.com/library/windows/hardware/hh454870)
    Окно выбора контактов (Contact picker) Приложения, которое работает с данными контактов (наподобие адресной книги). Приложения, которые используют API выбора контактов (наподобие приложений электронной почты) Запускает приложение для предоставления списка, из которого можно выбирать контакты. Смотрите материал "Управление контактами пользователя" (http://msdn.microsoft.com/library/windows/apps/hh464939.aspx)
    Активация файла (сопоставление типа файла) (File activation (file type association)) Приложения, которые могут открывать файлы конкретного типа. Проводник Windows и приложения, которые используют API запуска файлов. Запускает приложение для открытия или обработки файла при необходимости. Смотрите материалы "Обработка активации файла" (http://msdn.microsoft.com/library/windows/apps/hh452684.aspx), и "Автоматический запуск с сопоставлением файлов и универсальных кодов ресурсов (URI)" (http://msdn.microsoft.com/library/windows/apps/hh452691.aspx).
    Контракты выбора файлов в окне открытия/сохранения (File open picker/file save picker) Приложение с данными, которые могут выглядеть для других приложений как файлы, которые можно открывать и / или сохранять (два разных контракта). Приложения, использующие API средства выбора файлов (а так же, определенные возможности Windows) Дает доступ к данным, которые, в противном случае, скрыты внутри приложения и управляются его средствами. Эти данные видны пользователю как часть файловой системы. Смотрите материал "Интеграция с контрактами "Средство выбора файлов" (http://msdn.microsoft.com/library/windows/apps/hh465174.aspx).
    Проводник игр (Game explorer) Игровое приложение с файлом описания игры (Game Definition File) Windows (Служба семейной безопасности (parental controls) Управляет возрастными ограничениями для игр. Смотрите материал "Создание файла описания игры" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh465153.aspx).
    Воспроизведение на устройстве (Play To) (лекция 4 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript") Приложения, которые могут воспроизводить цифровое мультимедиа на DLNA-устройствах Windows (Чудо-кнопка "Устройства" (Devices) > Подключиться (Connect)) Смотрите материал "Потоковая передача мультимедиа на устройства с помощью функции воспроизведения на устройстве" (http://msdn.microsoft.com/library/windows/apps/hh465176.aspx).
    Параметры задачи печати (Print task settings) Приложения, работающие с принтерами Windows (Чудо-кнопка "Устройства" (Devices) > Печать (Print)) Смотрите материал "Разработка приложений Магазина Windows для принтеров" (http://msdn.microsoft.com/library/windows/hardware/br259129).
    Активация протокола (сопоставление со схемой URI) (Protocol activation (URI scheme association)) Приложение, которое открывает URI, начинающиеся с определенной схемы URI). Проводник Windows и приложения, которые используют API запуска файлов. Запускает приложения для открытия или обслуживания URI при необходимости. Смотрите материалы "Обработка активации протокола" (http://msdn.microsoft.com/library/windows/apps/hh452686.aspx) и "Автоматический запуск с сопоставлением файлов и универсальных кодов ресурсов (URI)" (http://msdn.microsoft.com/library/windows/apps/hh452691.aspx).
    Поиск (Search) Приложение с данными, по которым можно осуществлять поиск Windows (Чудо-кнопка Поиск (Search)) Представляет легко доступную во всей системе возможность по поиску в любом приложении. Смотрите материал "Добавление поиска в приложение" (http://msdn.microsoft.com/library/windows/apps/hh465231.aspx).
    Параметры (Settings) (Глава 2 курса "Пользовательский интерфейс приложений для Windows 8, созданных с использованием HTML, CSS и JavaScript") Приложения, имеющие параметры Windows (Чудо-кнопка Параметры (Settings)) Предоставляет единую точку доступа к параметрам приложения. Смотрите материал "Добавление параметров приложений" (http://msdn.microsoft.com/library/windows/apps/hh770540.aspx).
    Общий доступ (Share) Приложения с данными для совместного использования. Приложения, которые могут принимать данные для включения в состав собственных данных или для отправки на устройства. Предоставляет средство для передачи данных между приложениями, в результате, приложение-источник не нуждается в знании особенностей реализации приложения-получателя, наподобие Facebook, Twitter и так далее. Смотрите материал "Общий доступ к содержимому и его получение" (http://msdn.microsoft.com/library/windows/apps/hh758314.aspx).
    SSL/сертификаты (SSL/certificates) Приложение, которое нуждается в установке сертификата Приложение, которое нуждается в поддержке сертификата для доступа к стороннему сервису. Смотрите материал: "Шифрование данных и работа с сертификатами" (http://msdn.microsoft.com/ru-ru/library/windows/apps/hh465012.aspx).

    Общий доступ

    Хотя чудо-кнопка Поиск расположена первой на Панели чудо-кнопок, певый контракт, который я хочу подробно рассмотреть – это Общий доступ. В конце концов, это одна из первых вещей, которую узнают дети! Я начинаю с Общего доступа, так как мы уже видели его со стороны источника, в Главе 2 курса "Введение в разработку приложений для Windows 8 с использованием HTML, CSS и JavaScript", в приложении "Here My Am!", а здесь, в конце этого раздела, мы так же коснемся старого доброго буфера обмена.

    Вот, что мы уже знаем об Общем доступе, более подробно процесс работы с ним показан на рис. 1.1.

  • Приложение с содержимым, подходящим для общего доступа, прослушивает событие datarequested объекта, возвращаемого Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView(). Это событие WinRT (при работе с которым вы должны помнить об использовании removeEventListener) вызывается, когда пользователь активирует чудо-кнопку Общий доступ. Заметим, что если приложение вовсе не прослушивает это событие, панель Общего доступа отобразит сообщение по умолчанию "Это приложение не поддерживает общий доступ "unable to share" (это сообщение, несомненно, разочарует пользователей!).
  • В обработчике события приложение определяет, есть ли в его текущем состоянии что-то для общего доступа. Если есть, оно заполняет Windows.ApplicationModel.DataTransfer.DataPackage, предоставленный в событии. (Здесь возможны варианты в зависимости от наличия или отсутствия выделения. Если пользователю нужно сделать выделение для того, чтобы общий доступ заработал, приложение может отобразить сообщение об этом).
  • На основании форматов данных в пакете, Windows, то есть – брокер общего доступа, управляющий контрактом, определяет целевые приложения общего доступа для отображения пользователю. Пользователь так же может управлять тем, какие приложения следует отображать, посредством параметра Изменение параметров компьютера (Change PC Settings) > Общий доступ (Share).
  • Когда пользователь выбирает цель общего доступа, активируется соответствующее приложение и принимает пакет данных для обработки.
  • (рис 1.1) Обработка реализации контракта Общий доступ, инициированная после активации пользователем чудо-кнопки Общий доступ

    Приложение-источник (Source App)

    Прослушивает событие datarequested объекта DataTransferManager (Listens for datarequested event on DataTransferManager)

    Принимает событие и заполняет DataPackage (Receives events and fills DataPackage)

    Завершает асинхронный вызов (посредством отложенной операции) и возвращается из операции обработки (Completes async calls (via deferrals) and returns)

    Необязательный прослушиватель для события targetApplicationChosen объекта DataTransferManager (Optional listen for targetApplicationChosen event on DataTransferManager)

    Брокер общего доступа(Share Broker)

    Чудо-кнопка Общий доступ активирована, вызвано событие datarequested для приложения переднего плана (Share charm is invoked, datarequested fired to foreground app)

    Отфильтрованный список целевых приложений и быстрых ссылок (Filters list of target apps and Quicklinks base on format)

    Пользователь выбирает целевое приложение или быструю ссылку (User selects target app or Quicklink)

    Активация целевого приложения с пакетом данных (Activate target app with data package)

    Целевое приложение общего доступа (Share Target App)

    Активация для общего доступа (Activated for sharing)

    Обрабатывает содержиме DataPackage (вывод запросов) (Processes DataPackage contents (requests rendering))

    Сообщает о завершении операции и операция завершена (Reports complete and sharing is complete)

    Все это предоставляет пользователям удобный способ взять что-то, что им нравится, в одном приложении и передать в другое приложение, воспользовавшись простым жестом у края экрана и выбором целевого приложения. Это похоже на буфер обмена с широкими семантическими возможностями, работая с которым, вы не задумываетесь о том, как подключиться к другим приложениям. Что особенно приятно в случае с контрактом Общий доступ, другими словами, что приложение-источник не должно заботиться о том, что произойдет с данными – его единственная задача – предоставить данные, подходящие для общего доступа в тот момент, когда пользователь активирует чудо-кнопку Общий доступ (если, на самом деле, это подходящие данные, а иногда это не так). Это освобождает приложение-источник от необходимости предсказывать, предвидеть или предугадывать то, что пользователи могут захотеть сделать с данными. Может быть, пользователь решит отправить их по электронной почте, может быть – в социальную сеть, или захочет поместить их в приложение для управления контентом… кто знает?

    Да, только пользоваель и знает, и брокер общего доступа делает с данными то, что решит пользователь! Получив пакет данных из источника, брокер сравнивает формат данных в пакете с форматами, которые поддерживают целевые приложения, объявив о них в манифесте. Затем брокер показывает список этих приложений пользователю. Этот список может содержать приложения, и то, что называется быстрой ссылкой (quicklink) (если быть точным, то это объекты Windows.ApplicationModel.DataTransfer.ShareTarget.Quicklink), которые поддерживают некоторые приложения, но более конкретным образом. Например, когда приложение электронной почты отображается в качестве целевого для нужд общего доступа, лучшее, что оно может сделать – это создать новое сообщение без указания конкретного адресата. Быстрая ссылка, однако, может идентифицировать конкретных получателей электронного письма, например, человека или людей, которым вы часто пишете письма. Быстрая ссылка, таким образом, это возможность выбрать целевое приложение с добавлением конкретной конфигурационной информации.

    В любом случае, когда пользователь выбирает цель, запускается какое-то приложение. В случае с контрактом Общий доступ, приложение запускается с видом активации shareTarget. Это сообщает ему о том, что ему не нужно показывать свой интерфейс по умолчанию, но, вместо этого, нужно показать специальную панель общего доступа (с возможностью автоматического скрытия при неактивности). С ее помощью пользователь может уточнить, что и как следует добавить в приложение из данных общего доступа. Например, на панели общего доступа для приложений социальных сетей часто предоставляют место для ввода комментария к данным перед их отправкой. Приложение электронной почты может предоставить средства для правки сообщения перед отправкой. Клиент сервиса для работы с фотографиями может позволить добавить подпись, указать место, где была снята фотография, людей, изображенных на фото и так далее. В общем, вы поняли. Все это, собрано вместе для обеспечения плавного взаимодействия пользователя и системы – от выбора данных, которыми он хочет поделиться, до указания приложения и настройки этих данных.

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

    Приложениям-источникам так же не нужно обновляться, когда, например, новая цель общего доступа становится популярной (например – новая социальная сеть): все, что нужно – это единственное целевое приложение. Что касается этих целевых приложений, им не нужно возвещать о себе всему миру: посредством контрактов приложения-источники автоматически получают возможность использовать любые целевые приложения, которые станут доступны в будущем. И, с точки зрения конечного пользователя, работа с чудо-кнопкой Общий доступ становится все интереснее и интереснее, когда он устанавливает больше программ, поддерживающих возможность Общего доступа.

    В то же время, приложение-источник может кое-что узнать о том, как использованы данные, предоставленные для общего доступа. Вместе с событием datarequested, DataTransferManager так же запускает событие targetApplicationChosen для прослушивающего это событие приложения-источника. В данном случае eventArgs содержит лишь одно свойство – applicationName (имя приложения). Это не особо полезно для любых других API WinRT, однако, эти сведения вы можете использовать для целей собственной аналитики. Подобные данные могут помочь вам понять, обеспечиваете ли вы лучший опыт взаимодействия, предоставляя в общий доступ больше форматов данных, например, или, если типичные целевые приложение поддерживают пользовательские форматы, вы можете включить их поддержку в будущих обновлениях программы.

    Приложения-источники

    Придем к окончательному пониманию приложений-источников, изучив некоторые подробности, которые мы еще не рассматривали, преимущественно касающиеся того, как приложение-источник заполняет пакет данных, и параметров, которые у него есть для обработки запроса. Для этой цели я предлагаю вам загрузить и запустить пару примеров: "Приложение-источник для общего доступа" (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Source-App-d9bffd84) и "Приложение-цель для общего доступа" (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782). Мы рассмотрим оба, а последний содержит хороший пример того, как целевое приложение принимает пакет данных, созданный в приложении-источнике.

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

    Windows.ApplicationModel.DataTransfer.DataTransferManager.showShareUI();

    Такой вызов, как и в случае, когда пользователь нажимает на чудо-кнопку, вызывает событие datarequested, где eventArgs.request – это объект ). Объект запроса содержит два свойства и два метода:

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

    deadline – это свойство типа Data, показывающее время в будущем, когда данные, которые вы сделали доступными, будут неактуальны (таким образом, не будут обработаны). Это позволяет учесть ситуацию, когда между запросом данных и реальной попыткой их использовать может пройти неопределенное время. В случае с отложенной обработкой данных, как отмечено выше для свойства data, возможно, что некоторые непостоянные источники данных могут исчезнуть. Когда это время отмечено в deadline, запросы на обработку, которые происходят позже него, будут проигнорированы.

    failWithDisplayText – это метод, который сообщает брокеру общего доступа, что в данный момент предоставление данных в общий доступ невозможно, так же предоставляется строка, которая сообщит пользователю, почему это так (возможно, ему нужно выделить что-нибудь). Вы вызываете это тогда, когда нет выделенных данных, формат которых подходит для предоставления в общий доступ, если произошла ошибка при заполнения пакета данных по любой другой причине. Текст, который вы предоставите, будет отображен в панели чудо-кнопки Общий доступ (и, таким образом, его следует локализовывать). Сценарий 8 примера о приложении-источнике показывает использование этого подхода в простом случае, когда он не предоставляет данных в ответ на событие datarequested.

    getDeferral предоставляется для асинхронных операций, которые могут вам понадобиться для заполнения пакета данных (это те же самые отложенные операции, которые используются везде в WinRT API). Отметим, что событие datarequested имеет тайм-аут в 200 мс, после чего в интерфейсе чудо-кнопки Общий доступ отобразится сообщение о невозможности немедленного предоставления данных в общий доступ. Запрос отложенной операции не меняет этот тайм-аут, он лишь предотвращает ситуацию, когда datarequested считает, что пакет данных готов как только вы возвратились из обработчика.

    Обычная структура обработчика datarequested, таким образом, направлена на заполнение минимальных свойств eventArgs.request.data и вызов eventArgs.request.failWithDisplayText по возникновению ошибки. Мы встретимся с этой структурой в большинстве сценариев примера:

     var dataTransferManager =
        Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
        // Удалите этот прослушиватель в соответствии с требованиями
        dataTransferManager.addEventListener("datarequested", dataRequested);
    
        function dataRequested(e) {
        var request = e.request;
    
        // Нужен заголовок (Title)
        var dataPackageTitle = document.getElementById("titleInputBox").value;
    
        if ( /* Проверяем, есть ли подходящие для целей общего доступа данные */ ) {
        request.data.properties.title = dataPackageTitle;
    
        // Параметр description необязателен.
        var dataPackageDescription = document.getElementById("descriptionInputBox").value;
        request.data.properties.description = dataPackageDescription;
        // Вызываем request.data.setText, setUri, setBitmap, setData, и так далее.
        } else {
        request.failWithDisplayText(/* Сообщение об ошибке */ );
        }
        }

    Как мы здесь видим, объект )), это то место, куда вы записываете данные наподобие заголовка и описания пакета данных. Вот другие свойства:

  • ).
  • applicationName – это строка, которая помогает целевому приложению получить ту же информацию, которую источник может получить из события targetApplicationChosen.
  • ), но он может содержать и сведения о пользовательских форматах.
  • size – количество элементов, если данные в пакете – это коллекция, например, коллекция файлов.
  • thumbnail – поток, содержащий изображение-эскиз. Обычно именно из-за надобности получения этого изображения и используют метод DataRequest.getDeferral.
  • Помимо этого объект data.properties так же поддерживает пользовательские свойства, посредством своих методов insert, remove и других. Это делает для приложения-источника возможным передавать пользовательские свойства вместе с пользовательскими форматами, делая все это расширяемым, если новые форматы данных станут широко распространенными в будущем.

    В вышеприведенном коде, основная задача приложения-источника заключается в заполнении пакета данных с помощью вызова различных set*-методов пакета. Для стандартных форматов, которые описаны в перечислении StandardDataFormats, это отдельные методы: setText, setUri, setHtmlFormat, setRtf (rich text format, довольно ранний предшественник HTML), setBitmap, и setStorageItems (для папок и файлов). Все эти методы, кроме setRtf, представлены в коде примера.

    Общий доступ к тексту – Сценарий 1 (js/text.js):

    var dataPackageText = document.getElementById("textInputBox").value;
        request.data.setText(dataPackageText);

    Передача в общий доступ ссылки – Сценарий 2 (js/link.js). Это можно использовать и для локального и для удаленного содержимого:

     request.data.setUri(new Windows.Foundation.Uri(document.getElementById("linkInputBox").value));

    Общий доступ к изображению и элементу хранения – Сценарий 3 (js/image.js):

          var imageFile; // StorageFile, полученный через средство выбора файлов
          //В событии datarequested
          var streamReference =
          Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
          request.data.properties.thumbnail = streamReference;
          // Рекомендуется всегда, для предоставления общего доступа, использовать и setBitmap и setStorageItems
          // для изображения, так как целевое приложение может поддерживать либо то, либо другое
    
          // Поместим файл изображения в массив и передадим его setStorageItems
          request.data.setStorageItems([imageFile]);
    
          // Метод setBitmap требует RandomAccessStreamReference
          request.data.setBitmap(streamReference);
        

    Общий доступ к файлам – Сценарий 4 (js/file.js)

    var selectedFiles; // Коллекция объектов StorageFile, полученных из средства выбора файлов
    
        // В событии datarequested
        request.data.setStorageItems(selectedFiles);

    Что касается общего доступа к HTML, то это может быть очень простой задачей, если HTML у вас есть в виде строки:

     request.data.setHtmlFormat(someHtml);

    Для этой цели вы можете воспользоваться полезным объектом Windows.ApplicationModel.DataTransfer.HtmlFormatHelper (http://msdn.microsoft.com/library/windows/apps/hh738437.aspx), который предоставляет методы для создания правильно отформатированной разметки. Справедливо по отношению к HTML и то, что он часто ссылается на другое содержимое, наподобие изображений, которые не включены непосредственно в разметку. Что же делать в такой ситуации? К счастью, дизайнеры API поработали над этим: вы можете использовать свойство пакета данных resourceMap для связывания относительных URI в HTML с потоком изображения. Мы видим это в Сценарии 6 (js/html.js):

      var path = document.getElementById("htmlFragmentImage").getAttribute("src");
        var imageUri = new Windows.Foundation.Uri(path);
        var streamReference =
        Windows.Storage.Streams.RandomAccessStreamReference.createFromUri(imageUri);
        request.data.resourceMap[path] = streamReference;

    Еще одна интересная часть Сценария 6 – это та, которая заменяет пакет данных в eventArgs на новый, который она создает следующим образом:

    var range = document.createRange();
        range.selectNode(document.getElementById("htmlFragment")); request.data
        = MSApp.createDataPackage(range);

    Как вы можете видеть, метод ) берет диапазон DOM (в данном случае – часть текущей страницы) и создает из него пакет данных, где, при обработке, вызывается метод пакета setHtmlFormat (поэтому вы не увидите явного вызова этого метода в Сценарии 6). Ценно заметить, что имеется еще и метод ), который выполняет то же самое с текущим выделенным фрагментом DOM. Очевидно, вы воспользуетесь этим, если у вас есть элемент, который можно редактировать, данные которого вы хотите предоставить в общий доступ.

    Организация общего доступа к данным разных форматов

    Как показано в Сценарии 3, не только разрешено, но и рекомендовано, предоставлять в общий доступ к данным во всех возможных форматах, таким образом, получая больше потенциальных целевых приложений. Все это значит, что вы вызываете все методы set*, которые имеют смысл, в обработчике datarequested. Это включает в себя вызов setData для пользовательских форматов и setDataProvider для отложенной обработки, как описано в следующих двух разделах.

    Пользовательские форматы данных: schema.org

    Я думаю, что много лет назад дизайнеры API решили, что пытаться предвидеть все форматы данных, которыми могут обмениваться приложение, это – бесполезное занятие. API WinRT следует этой идее, поэтому вместе с методами set* для конкретных форматов, в DataPackage мы можем найти и общий метод setData. Он принимает идентификатор формата (строку) и данные для общего доступа. Это показано в Сценарии 7 примера с использованием формата "http://schema.org/Book" и данных в строковом формате JSON (js/custom.js):

     request.data.setData(dataFormat, JSON.stringify(book));

    Так как идентификатор пользовательского формата данных – это обычная строка, вы можете использовать здесь все, что хотите. Например, здесь могут быть полезны весьма специфичные форматы данных, например, в сценарии обмена данными, в котором участвует весьма специфичное целевое приложение, возможно то, которое вы сами и создали. Однако, если только вы не оповестили всех разработчиков о своем формате данных (и если только у вас нет бюджета для этого!), есть вероятность, что другие целевые приложения не будут иметь никакого понятия о ваших форматах данных.

    К счастью, имеется растущее количество соглашений, касающихся пользовательских форматов данных, которые поддерживает http://schema.org/ . Этот сайт является местом, где хранятся соглашения по пользовательским форматам, таким образом, мы настоятельно рекомендуем, чтобы вы брали форматы оттуда. Их полный список можно найти http://schema.org/docs/schemas.html .

    Вот JSON-данные в формате book, использованные в примере:

    var book = {
    type: "http://schema.org/Book", properties: {
    image: "http://sourceuri.com/catcher-in-the-rye-book-cover.jpg", name: "The Catcher in the Rye",
    bookFormat: "http://schema.org/Paperback",
    author: "http://sourceuri.com/author/jd_salinger.html", numberOfPages: 224,
    publisher: "Little, Brown, and Company", datePublished: "1991-05-01",
    inLanguage: "English", isbn: "0316769487"
    }
    };
        

    Вы можете легко выразить те же данные в виде обычного текста, HTML (или RTF), в виде ссылки (возможно, на страницу с этой информацией), и изображения (обложка книги). Так вы можете заполнить пакет данных полностью стандартными форматами вместе со специфическими пользовательскими форматами.

    Отложенные операции и отложенный рендеринг

    Откладывание, как упомянуто ранее, это простой механизм для задержки завершения события ) показывает пример использования этого механизма при загрузке файла изображения:

    var deferral = request.getDeferral();
    
    Windows.ApplicationModel.Package.current.installedLocation.getFileAsync( "images\\smalllogo.png")
    .then(function (thumbnailFile) {
    request.data.properties.thumbnail = Windows.Storage.Streams.
    RandomAccessStreamReference.createFromFile(thumbnailFile);
    return Windows.ApplicationModel.Package.current.installedLocation.getFileAsync( "images\\logo.png");
    })
    .done(function (imageFile) {
    request.data.setBitmap( Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile));
    deferral.complete();
    });
        

    Отложенный рендеринг – это другое дело, хотя процесс обычно использует откладывание. Его цель зкалючается в предотвращении рендеринга данных общего доступа до тех пор, пока целевое приложение не получит их, иногда это называют операциями отложенного общего доступа (pull operations). Методы set*, которые мы видели, выполняют копирование полных данных в пакет. Отложенный рендеринг (обработка) подразумевает вызов метода пакета данных setDataProvider (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.datatransfer.datapackage.setdataprovider.aspx) с идентификатором формата данных и функцией, которую нужно вызвать, когда понадобятся данные. Вот как это реализовано в Сценарии 5 примера приложения-источника, где imageFile выбирают с помощью средства выбора файлов (js/image.js):

    // Обеспечивая общий доступ к изображению, не забудьте установить эскиз для DataPackage
    var streamReference =
    Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
    request.data.properties.thumbnail = streamReference;
    request.data.setDataProvider(
    Windows.ApplicationModel.DataTransfer.StandardDataFormats.bitmap,
    onDeferredImageRequested);
        

    Как показано в комментариях, хорошо будет предоставить экскиз при использовании операции отложенного рендеринга, таким образом, у целевого приложения будет что показать пользователю. Таким образом, когда целевому приложению понадобятся полные данные, будет вызвана функция провайдера данных, в данном случае – onDeferredImageRequsted:

    function onDeferredImageRequested(request) {
    if (imageFile) {
    // Здесь мы предоставляем обновленные данные изображения с использованием отложенного рендендеринга
    var deferral = request.getDeferral();
    
    var imageDecoder, inMemoryStream;
    
    imageFile.openAsync(Windows.Storage.FileAccessMode.read).then(function (stream) {
    // Декодируем изображение
    return Windows.Graphics.Imaging.BitmapDecoder.createAsync(stream);
    }).then(function (decoder) {
    // Перекодируем изображение до 50% ширины и высоты
    inMemoryStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
    imageDecoder = decoder;
    return Windows.Graphics.Imaging.BitmapEncoder.createForTranscodingAsync(
    inMemoryStream, decoder);
    }).then(function (encoder) {
    encoder.bitmapTransform.scaledWidth = imageDecoder.orientedPixelWidth * 0.5;
    encoder.bitmapTransform.scaledHeight = imageDecoder.orientedPixelHeight * 0.5;
    return encoder.flushAsync();
    }).done(function () {
    var streamReference = Windows.Storage.Streams.RandomAccessStreamReference
    .createFromStream(inMemoryStream);
    request.setData(streamReference);
    deferral.complete();
    }, function (e) {
    // операция не выполнена, но нам нужно выйти из отложенной операции deferral для того
    //чтобы целевое приложение не зависло
    deferral.complete();
    });
    }
    }
        

    Обатите внимание на то, что эта функция принимает упрощенный гибрид объектов ), который содержит свойства deadline и formatId, метод getDeferral и метод setData, посредством которого вы предоставляете данные, которые соответствуют formatId. Свойство deadline, как вы можете догадаться, это то же свойство, что обработчик datarequested может сохранить в объекте DataRequest.

    Целевые приложения

    Возвращаясь к рис. 1.1, мы можем видеть, что хотя взаимодействие между приложением-источником и брокером общего доступа к данным управляется единственным событием datarequested, взаимодействие между брокером и целевым приложением устроено немного сложнее. С одной стороны, брокер должен определить, какое приложение потенциально может обработать конкретный пакет данных, для чего каждое целевое приложение содержит соответствующие детали в своем манифесте. Когда приложение выбрано, оно запускается с видом активации shareTarget, в ответ на это оно должно показать специальный пользовательский интерфейс общего доступа, вместо полного интерфейса приложения.

    Посмотрим, как все это работает с помощью примера "Приложение-цель для общего доступа" (http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782), вид которого показан на рис. 1.2. Убедитесь в том, что сначала запустили приложение в Visual Studio, чтобы оно было установлено и появилось бы в списке приложений, когда мы активируем чудо-кнопку Общий доступ.

    (рис 1.2) Внешний вид примера целевого приложения

    Первый шаг целевого приложения заключается в объявлении форматов данных, которые оно может принимать, в разделе Объявления (Declarations) манифеста, вместе со страницей, которая будет открыта, когда предложение будет выбрано в качестве целевого. Как показано на рис. 1.3., в примере целевого приложения указано, что приложение может работать с текстом, URI, изображениями, HTML и форматом http://schema.org/Book , так же заявлено о том, что оно может обрабатывать любые файлы, которые могут содержаться в пакете данных (вы можете задать здесь конкретные типы файлов). В нижней части панели указано, что страница приложения target.html будет использоваться в качестве страницы, выводимой на панель Общего доступа.

    (рис 1.3) Объявления в манифесте приложения из примера целевого приложения

    Начальная страница для общего доступа – это обычная HTML-страница с любым необходимым вам макетом для выполнения задачи общего доступа. Эта страница обычно функционирует независимо от основного приложения. Когда приложение выбирают в качестве цели для общего доступа, эта страница загружается и активируется самостоятельно и, таким образом, имеет полностью собственный скриптовый контекст. На этой странице не следует размещать навигационные элементы, ведущие к другим частям приложения, и она должа содержать лишь код, который необходим для задач общего доступа к данным (Параметры Исполняемый файл (Executable) и Точка входа (Entry point) не используются приложениями, написанными на HTML и JavaScript, они существуют для приложений, написанных на других языках).

    Большая часть ее структуры может быть создана автоматически с использованием Шаблона элемента контракта получателя данных (Share Target Contract item template), который предоставляется Visual Studio и Blend, как показано на рис. 1.4. Диалоговое окно появляется, после того, как вы щелкнете правой кнопкой мыши по проекту и выберете команду Добавить > Создать элемент (Add > New Item), или воспользуетесь командой меню Проект > Создать новый элемент (Project > Add New Item).

    (рис 1.4) Шаблона элемента контракта получателя данных в Visual Studio и Blend

    Данный шаблон элемента предоставит вам HTML, JS и CSS-файлы для создания страницы целевого приложения и добавит эту страницу в объявление манифеста вместе с указанием поддержки текстового формата и формата URI. Вам лишь останется соответствующим образом отредактировать эти данные.

    Прежде чем мы рассмотрим код, вот несколько замечаний о дизайне страницы для приложения-получателя данных, они представляют собой краткое изложение материала "Руководство по общему доступу к содержимому" ( http://msdn.microsoft.com/library/windows/apps/hh465251.aspx):

  • Сохраняйте индивидуальность приложения, его внешний вид, и удобство работы с ним, на уровне основного приложения.
  • Обеспечьте простоту взаимодействий для быстрого выполнения задач по общему доступу. Избегайте форматирования текста, пометок людей на фотографиях или задач по установке, но предоставьте возможности по редактированию содержимого, особенно, если отправляете данные в социальные сети или отправляете сообщение. (Посмотрите на рис. 12.5., где в качестве примера приведено приложение Mail (Почта)). Целевые приложения социальных сетей обычно подразумевают возможность комментирования, в приложения-получателя фотографий, возможно, есть смысл включить функцию добавления подписи к фотографии.
  • Сведите к минимуму навигацию: задача общего доступа предусматривает собственную рабочую среду, поэтому используйте встроенные элементы управления и встроенные сообщения об ошибках вместо переключения на другие страницы. Другая причина избегать этого заключается в том, что страница обеспечения функциональности общего доступа исполняется в собственном скриптовом контексте, поэтому возможность перехода в приложение, в другой контекст, может смутить пользователя.
  • Избегайте использования ссылок, которые могут отвлечь пользователя от задачи общего доступа или увести его в другое место. Помните, что общий доступ – это способ упростить процесс получения данных из одних приложений в другие, который традиционно является достаточно утомительным. Поэтому сконцентрируйте все усилия интерфейса общего доступа целевого приложения на этой задаче.
  • Избегайте использования автоматического скрытия неактивных всплывающих элементов, так как интерфейс чудо-кнопки Общий доступ уже обладает подобной функциональностью.
  • Подтверждайте действия пользователя, когда вы начинаете отправлять данные (на сетевой сервис, например), чтобы пользователь знал, что что-то действительно происходит.
  • Расположите важные кнопки в пределах досягаемости больших пальцев. Обратитесь к материалу "Состояние сенсорного ввода Windows 8" (http://msdn.microsoft.com/library/windows/apps/hh465415.aspx#touch_posture) для того, чтобы прочесть руководство по размещению элементов.
  • Постарайтесь сделать то, как выглядят элементы в режиме предварительного просмотра, соответствующим их реальному внешнему виду. Другими словами, не показывайте пользователю фокусы!
  • В случае с дизайном этой страницы, полезно знать, что вам не нужно беспокоиться о различных режимах просмотра – страница существует лишь в одном состоянии (как всплывающий элемент, она не может отображаться в прикрепленном режиме). Однако, ей нужно подстраиваться под различные размеры экрана, помните об этом, но не под различные режимы просмотра. Здесь хорошо подойдет макет, основанный на CSS-сетке с дробными размерами строк и столбцов.

    Предупреждение. Так как целевое приложение может принимать данные от любого приложения-источника, ему следует расценивать такое содержимое как недоверенное и потенциально опасное, особенно когда речь идет об HTML, URI и файлах. Целевое приложение должно избегать добавления подобного HTML или содержимого файлов в DOM, исполнять код из URI, переходить по URI или к каким-то другим страницам на основе URI, модифицировать записи базы данных, использовать eval с данными и так далее.

    (рис 1.5) Интерфейс общего доступа в приложении Windows Mail (Почта Windows) (нижняя пустая часть была обрезана). Этот пользовательский интерфейс позволяет править адрес получателя, тему и тело сообщения и отправлять изображение в виде вложения или ссылки на файл в SkyDrive

    Подсмотрим на полное содержимое JavaScript-файла шаблона, так как это показывает нам основные механизмы целевого приложения. Во-первых, как вы можете видеть, у нас есть те же структуры, что и в обычном default.js приложения, мы используем методы и события объекта WinJS.Application.

    (function () { "use strict";
    
    var app = WinJS.Application;
    var share;
    
    function onShareSubmit() {
    document.querySelector(".progressindicators").style.visibility = "visible";
    document.querySelector(".commentbox").disabled = true;
    document.querySelector(".submitbutton").disabled = true;
    
    // TODO: Выполните какие-либо действия с данными общего доступа из переменной 'share'.
    
    share.reportCompleted();
    }
    
    // Эта функция ответственна за различные виды активации приложения.
    app.onactivated = function (args) {
    var thumbnail;
    
    if (args.detail.kind ===
    Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
    document.querySelector(".submitbutton").onclick = onShareSubmit;
    share = args.detail.shareOperation;
    
    document.querySelector(".shared-title").textContent =
    share.data.properties.title;
    document.querySelector(".shared-description").textContent =
    share.data.properties.description;
    
    thumbnail = share.data.properties.thumbnail;
    if (thumbnail) {
    // Если данные общего доступа содержат эскиз, отобразим его.
    args.setPromise(thumbnail.openReadAsync().then(
    function displayThumbnail(stream) {
    document.querySelector(".shared-thumbnail").src =
    window.URL.createObjectURL(stream, { oneTimeOnly: true });
    }));
    } else {
    // Если эскиз не представлен, развернем элементы описания и
    // заголовка для того, чтобы заполнить неиспользуемое пространство.
    document.querySelector("section[role=main] header").style
    .setProperty("-ms-grid-columns", "0px 0px 1fr");
    document.querySelector(".shared-thumbnail").style.visibility = "hidden";
    }
    }
    };
    
    app.start();
    })();
        

    Когда загружается и активируется эта страница, в течение этого времени отображается экран-заставка приложения, выполняется ее событие WinJS.Application.onactivated – снова, независимо от обработчика activated основного приложения, который обычно находится в default.js. Так как мы работаем с целевым приложением для общего доступа к данным, мы проверяем, является ли тип активации shareTarget, после чего ваша основная задача – предоставить предварительный просмотр данных, которые поступают в приложение вместе с любым пользовательским интерфейсом, который предусмотрен для редактирования данных, комментирования и так далее. Обычно здесь так же имеется кнопка для завершения операции или передачи данных, нажатие на которую сообщает брокеру общего доступа, что операция завершена.

    Ключевым моментом здесь является объект ), свойство data которого содержит пакет данных только для чтения, который называется DataPackageView (http://msdn.microsoft.com/library/windows/apps/windows.applicationmodel.datatransfer.datapackageview.aspx), откуда вы получаете все, что вам нужно:

  • Для того чтобы проверить, содержатся ли в пакете данные в форматах, которые может принять ваше приложение, используйте метод contains или коллекцию availableFormats.
  • Для того, чтобы получить данные из пакета, используйте его методы get*, такие, как getTextAsync, getBitmapAsync, и getDataAsync (для пользовательских форматов). При вставке HTML вы так же можете использовать метод getResourceMapAsync для получения URI связанных ресурсов. Свойства (properties), имеющие отношение к отображению, такие как thumbnail, так же полезны для предоставления возможности предварительного просмотра данных.
  • Как видите, код из шаблона элемента контракта получателя данных, приведенный выше, ничего не делает с полученными данными, лишь отображает заголовок, описание и эскиз. Очевидно, ваше приложение будет делать нечто большее, чем просто запрашивать данные из пакета, как этот пример. Его файл js/target.js содержит обработчик activated для страницы target.html (в корне проекта) и она так же отображает эскиз из пакета данных по умолчанию. Затем они просматривает пакет на предмет различных форматов данных и выводит это содержимое, если оно присутствует:

    if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.
    text)) {
    shareOperation.data.getTextAsync().done(function (text) {
    displayContent("Text: ", text, false);
    });
    }
    Похожий код появляется и для простых форматов. Прием данных изображения требует немного больше работы, но он весьма прост:
    if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.
    bitmap)) {
    shareOperation.data.getBitmapAsync().done(function (bitmapStreamReference) {
    bitmapStreamReference.openReadAsync().done(function (bitmapStream) {
    if (bitmapStream) {
    var blob = MSApp.createBlobFromRandomAccessStream(bitmapStream.contentType, bitmapStream);
    document.getElementById("imageHolder").src = URL.createObjectURL(blob,
    { oneTimeOnly: true });
    document.getElementById("imageArea").className = "unhidden";
    
    }
    });
    });
    }
        

    Для обработки HTML, он просматривает разметку на предмет поиска элементов img, затем устанавливает их атрибуты src в соответствии с картой ресурсов (iframe к этому моменту уже содержит HTML-содержимое из пакета)

    var images = iFrame.contentDocument.documentElement.getElementsByTagName("img");
    if (images.length > 0) {
    shareOperation.data.getResourceMapAsync().done(function (resourceMap) {
    if (resourceMap.size > 0) {
    for (var i = 0, len = images.length; i < len; i++) {
    var streamReference = resourceMap[images[i].getAttribute("src")];
    if (streamReference) {
    // Вызов вспомогательной функции для установки src элементов изображений
    // на соответствующие URL больших двоичных объектов, созданных из streamReference 
    setResourceMapURL(streamReference, images[i]);
    }
    }
    }
    });
    }

    Вспомогательная функция setResourceMapURL выполняет довольно много операций, специфичных для обработки изображений. В частности, в ней вызывается openReadAsync для потока, осуществляется вызов MSApp.createBlobFromRandomAccessStream, полученный большой двоичный объект передается URL.createObjectURL, результат записывается в img.src, и поток закрывается.

    После того, как целевое приложение завершило операцию получения данных, оно должно вызвать метод ShareOperation.reportCompleted, как показано ранее в коде шаблона. Это позволяет системе узнать, что пакет данных принят, набор операций по предоставлению общего доступа к данным завершен, и все связанные с этим ресурсы можно освободить. Целевое приложение в примере выполняет это, когда вы нажмете на кнопку, предназначенную для этой цели, но обычно вы автоматически вызываете метод, когда вы завершаете операцию общего доступа. Хочу предупредить вас, что вызов reportCompleted закроет интерфейс работы с общими данными целевого приложения, поэтому старайтесь не вызывать его как только целевое приложение активировалось: желательно, чтобы пользователь чувствовал уверенность в том, что операция была проведена.

    Операции, выполняемые длительное время

    Когда вы запустите пример реализации целевого приложение и нажмете на чудо-кнопку Общий доступ, находясь в подходящем приложении-источнике данных, внизу будет небольшой разворачиваемый элемент, подписанный как "Поддержка общего доступа, требующего большого количества времени" ("Long-running Share Support"). Если вы развернете этот элемент, вы увидите некоторые дополнительные элементы управления и много описаний, как показано на рис. 1.6. Кнопки, показанные здесь, связаны с другими методами объекта ShareOperation наряду с reportCompleted. Это помогает Windows точно понять, как операция общего доступа обрабатывается внутри целевого приложения: reportStarted, reportDataRetrieved, reportSubmittedBackgroundTask, и reportError. Как вы можете видеть из рис. 1.6, это имеет отношение к тому, чтобы сообщить Windows, когда приложение закончит, так сказать, готовить обед, и система может вымыть посуду и убраться на кухне.

  • reportStarted сообщает Windows, что ваша операция общего доступа может занять некоторое время, как в случае, если вы отправляете данные из пакета в другое место, или просто отправляете в виде вложения электронной почты большие изображения и тому подобное. Этот метод показывает, что вы приняли весь необходимый ввод пользователя и что панель общего доступа может быть закрыта.
  • reportDataRetrieved сообщает Windows, что вы извлекли из пакета данных все, что вам нужно, и он, таким образом, может быть освобожден. Если вы, например, вызывали MSApp.createBlobFromRandomAccessStream для потока изображения, полученный большой двоичный объект теперь содержит копию изображения, которая является локальной для целевого приложения. Если вы используете изображения из свойства пакета resourceMap, с другой стороны, вам не нужно вызывать reportDataRetrieved до тех пор, пока вы явным образом не сделаете копию данных, на которые ссылаются URI внутри пакета данных. В любом случае, если вам нужно сохранять пакет в течение всей операции, вам не нужно вызывать этот метод, так как позже вы вызовете reportCompleted для освобождения пакета.
  • ). Как следует из описания, приведенного на рис. 12.6., это позволяет Windows знать, что она может приостановить целевое приложение и не беспокоиться об операции общего доступа. Если вы вызываете этот метод, работая с локальной копией данных для загрузки, пройдите дальше и вызовите метод reportCompleted, таким образом Windows сможет освободить пакет. В противном случае дождитесь окончания передачи данных.
  • reportError позволяет Windows узнать, не произошла ли ошибка в течение операции общего доступа.
  • (рис 1.6) Развернутое окно, демонстрирующее поддержку общего доступа, требующего большого количества времени, в примере целевого приложения. Кнопка Repopt Completed (Сообщить о завершении) отображается всегда и не является специфической для подобных операций, несмотря на ее расположение в пользовательском интерфейсе примера. Не позвольте этому вас запутать!

    Быстрые ссылки

    Последний аспект контракта Общий доступ, который нам осталось изучить, это то, о чем мы уже упоминали раньше: быстрые ссылки (quicklinks). Они служат для более рациональной реализации операций общего доступа, таким образом, что пользователям не нужно повторно вводить информацию в целевые приложения. Например, если пользователь часто передает данные конкретным людям по электронной почте, каждый контакт может выступать в роли быстрой ссылки для приложения электронной почты. Если пользователь обычно отправляет данные разным людям или группам людей посредством приложения для работы с социальными сетями, эти люди, или группы, так же могут быть представлены в виде быстрых ссылок. И, так как эти целевые объекты более специфичны для конкретного пользователя, чем обычные цели общего доступа, пользовательский интерфейс чудо-кнопки Общий доступ выводит их в верхней части списка (рис. 1.7).

    Каждая быстрая ссылка связана с конкретным целевым приложением и обслуживается им, просто предоставляя идентификатор для этого целевого приложения. Когда целевое приложение активируется посредством быстрой ссылки, оно использует идентификатор для получения данных, связанных с данной быстрой ссылкой и осуществляет предварительное заполнение или иную настройку пользовательского интерфейса. Важно понимать, что быстрые ссылки содержат только идентификатор, таким образом, целевое приложение должно хранить и получать связанные с ним данные из каких-то других источников, обычно из локальных данных приложения, где идентификатор является именем файла, именем контейнера параметров и так далее. Целевое приложение может так же использовать для этой цели перемещаемые данные приложения или облачные данные, но сами быстрые ссылки не перемещаются на другие устройства – они ограничены локальным использованием. Таким образом, имеет смысл хранить связанные с ними данными локально.

    Сами по себе быстрые ссылки – это лишь экземпляры класса ). Их создают с помощью оператора new и затем заполняют их свойства title, thumbnail, supportedDataFormats, supportedFileTypes, и id. Форматы данных и типы файлов – это то, что Windows использует для того, чтобы определить, следует ли показывать конкретные быстрые ссылки в списке целевых объектов для данных, предоставляемых в общий доступ из приложения-источника (независимо от объявлений в манифесте). Свойства title и thumbnail используются для отображения быстрых ссылок в интерфейсе чудо-кнопки Общий доступ, id – это то, что передается целевому приложению при выборе быстрой ссылки.

    Совет. Для эскизов (thumbnail), используйте изображение, которое способно точно представить быструю ссылку (например, фотографию из контакта), вместо изображения, соответствующего целевому приложению. Это помогает отличить быструю ссылку от общего элемента для вызова целевого приложения.

    Затем приложение регистрирует быструю ссылку в системе, передавая ее методу ShareOperation.reportCompleted. Так как это единственный способ регистрации быстрых ссылок, это говорит нам о том, что создание быстрой ссылки всегда происходит как часть другой операции общего доступа. Это способо создания конкретных целей, которые могут сберечь пользователю немного времени и вдохновить его на использование вашего целевого приложения снова в будущем.

    Посмотрим, как все это работает в примере целевого приложения для общего доступа. Для начала, когда вы активируете чудо-кнопку Общий доступ и выбираете приложение-пример, вы увидите, что оно предоставляет флаг для создания быстрой ссылки (рис. 1.7). Когда вы устанавливаете этот флаг, он предоставляет поля, в которые вы можете ввести идентификатор (id) и заголовок (title) (эскиз (thumbnail) просто использует приложение по умолчанию). Когда вы нажимаете на кнопку Report completed (Сообщить о завершении), вызывается метод reportCompleted и быстрая ссылка регистрируется в системе. При последующих обращениях к чудо-кнопке Общий доступ, при наличии у приложения-источника подходящих данных, эта быстрая ссылка появится в списке, как показано на рис. 1.8, а название приложения, обслуживающего быструю ссылку всегда отображается под заданным заголовком быстрой ссылки.

    (рис 1.7) Элементы управления для создания быстрой ссылки в примере целевого приложения для общего доступа (рис 1.8) Быстрая ссылка для приложения из примера целевого приложения для общего доступа появляется в списке целевых объектов чудо-кнопки Общий доступ

    Вот как в этом примере создается быстрая ссылка в функции reportCompleted (js/target.js), которая связана с кнопкой Report completed (Сообщить о завершении) (некоторые проверки ошибок опущены):

    if (addQuickLink) {
    var quickLink = new Windows.ApplicationModel.DataTransfer.ShareTarget.QuickLink();
    
    var quickLinkId = document.getElementById("quickLinkId").value;
    quickLink.id = quickLinkId;
    
    var quickLinkTitle = document.getElementById("quickLinkTitle").value;
    quickLink.title = quickLinkTitle;
    
    // Для быстрых ссылок поддерживаемые типы файлов (FileTypes) и 
    форматы данных (DataFormats) задаются независимо
    
    // от манифеста
    var dataFormats = Windows.ApplicationModel.DataTransfer.StandardDataFormats;
    quickLink.supportedFileTypes.replaceAll(["*"]);
    quickLink.supportedDataFormats.replaceAll([dataFormats.text, dataFormats.uri,
    dataFormats.bitmap,
    dataFormats.storageItems, dataFormats.html, customFormatName]);
    
    // Подготавливаем значок для QuickLink
    Windows.ApplicationModel.Package.current.installedLocation.getFileAsync(
    "images\\user.png").done(function (iconFile) {
    quickLink.thumbnail = Windows.Storage.Streams.RandomAccessStreamReference
    .createFromFile(iconFile);
    shareOperation.reportCompleted(quickLink);
    });
        

    Опять же, здесь лишь создается объект QuickLink, устанавливаются его свойства (возможно, более точно передающий его смысл эскиз, такой, как изображение из контактных сведений), и он передается в reportCompleted. В примере целевого приложения вы можете заметить, что для быстрой ссылки не хранятся локальные данные, в данном случае достаточно свойств самой быстрой ссылки. Большинство целевых приложений, однако, скорее всего будут хранить некоторые данные для быстрой ссылки, связанные с ее свойством quicklink.id и загружающие данные, когда приложение активировано посредством быстрой ссылки.

    Когда приложение активируется таким способом, объект eventArgs.detail.shareOperation в обработчике события активации будет содержать quicklinkId. Целевое приложение из примера просто отображает этот идентификатор, однако, на практике его обычно используют для загрузки данных приложения и предварительного заполнения пользовательского интерфейса:

    // Если приложение было активировано через быструю ссылку,  QuickLink, показать QuickLinkId
    if (shareOperation.quickLinkId !== "") {
    document.getElementById("selectedQuickLinkId").innerText = shareOperation.quickLinkId;
    document.getElementById("quickLinkArea").className = "hidden";
    }
        

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

    Буфер обмена

    Еще до того, как был придуман контракт Общий доступ, механизм, который мы знакм как буфер обмена (clipboard) представлял собой яркий пример средства для организации обмена данными между приложениями. И хотя сегодня он не может привлечь к себе большого внимания, он по-прежнему остается проверенным и надежным средством для обмена данными.

    Для приложений Магазина Windows взаимодействие с буфером обмена построено на том же самом механизме DataPackage, который мы уже видели в применении его к механизму общего доступа. Поэтому все, что мы узнали о заполнении этого пакета, об использовании пользовательских форматов, об использовании отложенного рендеринга применимо и к буферу обмена. В самом деле, если вы делаете данные доступными в буфере обмена, вам следует убедиться, что те же данные доступны для контракта Общий доступ!

    Вопрос заключается в том, как подключить команды, наподобие команд Копировать, Вырезать, Вставить, из панели приложения, контекстного меню или инициированные сочетаниями клавиш, которые приложению следует предоставить для собственного содержимого (многие элементы управления автоматически работают с буфером обмена). Для этих целей мы можем обратиться к классу ).

    Как показано в примере "Буфер обмена" (http://code.msdn.microsoft.com/windowsapps/Clipboard-App-sample-309ec122), этот процесс достаточно прост. В частности, для копирования и вырезания:

  • Создайте новый Windows.ApplicationModel.DataTransfer.DataPackage (или используйте MSApp.createDataPackage или MSApp.createDataPackageFromSelection), и заполните его нужными данными.
      var dataPackage = new Windows.ApplicationModel.DataTransfer.DataPackage();
        dataPackage.setText(textValue);
        //...
  • (Не обязательно) установите свойство пакета ): copy, move , link, или none (последнее используется для отложенного рендеринга). Отметим, что эти значения можно комбинировать, используя побитовый оператор ИЛИ. Например:
     var dpo = Windows.ApplicationModel.DataTransfer.DataPackageOperation;
        dataPackage.requestedOperation = dpo.copy | dpo.move | dpo.link;
  • Передайте пакет данных Windows.ApplicationMode.DataTransfer.Clipboard.setContent:
     Windows.ApplicationModel.DataTransfer.Clipboard.setContent(dataPackage);
  • Для выполнения операции вставки:

  • Вызовите ):
      var dataView = Windows.ApplicationModel.DataTransfer.Clipboard.getContent();
  • Проверьте, с помощью метода contains, содержит ли он форматы, которые вы можете принять (в качестве альтернативы, вы можете проверить содержимое вектора availableFormats):
     if (dataView.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.
          text)) {
          //...
          }
  • Получите данные, используя методы get*, такие, как getTextAsync, getBitmapAsync, и getDataAsync (для пользовательских форматов). Вставляя HTML вы так же можете использовать метод getResourceMapAsync для получения URI ресурсов. Свойства представления, наподобие thumbnail, так же полезны, как и значение или значения requestedOperation.
     dataView.getTextAsync().done(function (text) {
          // Принимаем данные
          }
  • Если вы, в любое время, захотите очистить содержимое буфера обмена, воспользуйтесь методом clear класса Clipboard. Так же вы можете убедиться в том, что данные доступны другим приложениям даже при закрытии вашего приложения, вызвав метод flush (он инициирует любые операции отложенного рендеринга, которые вы предусмотрели).

    Приложения, которые используют буфер обмена, так же нуждаются в информации о том, когда нужно активировать или деактивировать команду вставки в зависимости от доступных форматов. В любое время вы можете получить отображение пакета данных из буфера обмена и использовать его метод contains или свойство availableFormats и принять соответствующее решение. Так же вам следует прослушивать событие contentChanged (это событие WinRT) объекта Clipboard, которое будет выполнено, когда ваше приложение, или какое-то другое приложение, вызовет метод setContetn буфера обмена. Во время, заданное параметром time, вы активируете или деактивируете команды. Конечно, вы не будете принимать эти события, если ваше приложение приостановлено, поэтому, если вы хотите обновить сведения о состоянии этих команд, выполните это в обработчике возобновления работы.

    Пример работы с буфером обмена предоставляет примеры этих сценариев, в том числе, копирование и вставку текста и HTML (Сценарий 1); копирование и вставку изображения (Сценарий 2); копирование и вставу файлов (Сценарий 3); и очистку буфера обмена, перечисление форматов и обработку contentChanged (Сценарий 4).

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

    Вернуться к учебному плану