Программируем для Windows 7 в Visual Studio 2010

Несколько недель назад, всего за два дня до выпуска Windows 7, разработка Visual Studio достигла очередного важного этапа – стала доступна вторая CTP-сборка Visual Studio 2010, также известная как Visual Studio 2010 Beta 2. Мне всегда было интересно наблюдать за тем, как развиваются различные инструменты и инфраструктуры, как они приобретают новые возможности. Кажется, что каждый следующий выпуск этого продукта становится лучше и лучше, предлагая разработчикам поддержку все большего числа языков программирования и позволяя им создавать проекты для постоянно растущего числа областей, таких как web-приложения, клиентские приложения, приложения для мобильных платформ и программы, использующие параллельные вычисления, консоли и другие устройства.

Несмотря на то, что на данный момент новая версия среды разработки Microsoft находится на стадии «бета», уже сейчас работать с Visual Studio 2010 гораздо проще, чем с VS 2008. Стало намного легче управлять решениями и, что еще более важно, намного проще писать код и документацию к нему. Пользовательский интерфейс VS был значительно улучшен; он использует Windows Presentation Foundation (WPF), чтобы достичь большей упорядоченности и визуальной целостности, к тому же разработчики отказались от использования в интерфейсе устаревших трехмерных фасок у элементов UI. Использование WPF помогает пользователям сконцентрировать внимание на важных элементах интерфейса, корректно распределяя рабочее пространство среды разработки между окнами и выделяя доминантным цветом текущее окно, снижая при этом цветовое выделение фона. Помимо этого, в новой версии есть также маленькие, простые и приятные улучшения, такие как возможность управления размером текста. Вы также можете перетащить отдельное окно из главного приложения Visual Studio на второй монитор, что означает еще и поддержку многомониторных конфигураций клиентскими приложениями VS.

Улучшения в технологии IntelliSense, наконец-то облегчат процесс создания проектов на C++. Также не стоит забывать о новом окне отладчика, поддерживающего параллельную отладку и позволяющего увидеть параллельные стеки.

Также в новой версии появилась поддержка языка F# (язык функционального программирования) и многочисленные обновления C#, включая поддержку динамических ключевых слов. Операции над динамическими объектами реализуются в период выполнения приложения (подробнее об этом можно узнать из статьи Скотта Хансельмана (Scott Hanselman)). Также появилась поддержка новой версии спецификаций языка C++ – С++X0, включающих в себя, например, лямбда-выражения. Сборка решений C++ осуществляется MSBuild, что должно понравиться многим.

Как обычно, обратная совместимость чрезвычайно важна, а потому необходимо упомянуть о том, что Visual Studio 2010 обладает свойством настройки для различных версий (multi-targeting). Это означает, что Visual Studio 2010 может обеспечить работу с .NET 2.0 через .NET 4.0, что позволяет работать со старыми проектами в VS 2010 и пользоваться всеми улучшениями, о которых мы говорили выше.

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

.NET 4 и Windows 7

Visual Studio 2010 включает в себя законченную новую, четвертую версию CLR. Это не просто очередное расширяющее обновление поверх CLR 2 (.NET Framework 2). Эта версия включает в себя новые расширения для языков программирования, такие как динамические ключевые слова. А новая WPF-версия несет в себе поддержку таких технологий, как оболочки и интеграция с панелью задач, а также мультисенсорный ввод.

WPF и интеграция с панелью задач

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

Есть два типа категорий в списке – задачи (tasks) и элементы (items); для работы с ними можно использовать JumpTask и JumpPath, соответственно. С ними можно работать с помощью XAML, выделенного (code-behind) кода, или их комбинации. Следующий фрагмент кода демонстрирует простую интеграцию задач в список переходов:

 <JumpList.JumpList>
   <JumpList>
      <JumpTask ApplicationPath="notepad.exe" 
                         CustomCategory="External Tools" 
                Description="Take Notes" 
                Title="Start Notepad" 
                IconResourcePath="notepad.exe" 
                IconResourceIndex="0" />
 
      <JumpTask ApplicationPath="calc.exe"
                         CustomCategory="External Tools" 
                         Description="Perform some calculations" 
                        Title="Start Calculator"
                        IconResourcePath="calc.exe" 
                        IconResourceIndex="0" />
    </JumpList>
</JumpList.JumpList>

Точно так же вы можете использовать XAML для добавления кнопок к эскизам окон панели задач, как показано в следующем фрагменте кода:

 <TaskbarItemInfo.ThumbButtonInfos>
   <ThumbButtonInfo DismissWhenClicked="True" 
                    ImageSource="images/booktrip.png"
                    Command="{Binding BookItinerary}"
                    Description="Book the itinerary now" />
</TaskbarItemInfo.ThumbButtonInfos>

Код:

Основной файловый диалог поддерживает работу с библиотеками

По непонятным для меня причинам стандартное диалоговое окно для работы с файлом (Common File Dialog, CFD) WPF версий 3 и 3.5 не поддерживало обновленную версию CFD, представленную в Windows Vista. В Windows 7 диалог был обновлен для поддержки библиотек и обеспечения более удобного интерфейса пользователя. Теперь он поддерживает мгновенный поиск, а также некоторые функции для опытных пользователей. Благодаря новому WPF 4 приложения могут использовать всю мощь нового CFD напрямую из WPF, без необходимости импортировать CFD из пространства имен WinForm (что было единственным возможным вариантом для использования обновленного CFD из WPF 3 и 3.5).

WPF поддерживает мультисенсорный ввод

WPF 4.0 приносит с собой поддержку технологии multi-touch напрямую из WPF API, без необходимости обращения к «естественному» сервису. Данная новая функция доступна только в Windows 7 и автоматически отключается, когда приложение запускается в старой операционной системе, так что вам не придется самостоятельно заниматься определением версии операционной системы. WPF 4.0 добавляет новый API для обработки манипуляций жестами в базовый класс UIElement. Эта поддержка позволит разработчикам отслеживать множественные касания и генерировать как отдельные манипуляции, так и их совокупность. Прежде всего, это позволяет преобразовывать объект в координатах X и Y, переворачивать и масштабировать его.

WPF будет предоставлять события манипуляций, если свойство IsManipulationEnabled элемента будет установлено в «true». По умолчанию оно имеет значение «false» , так что вам придется самостоятельно включать это свойство для каждого элемента, для которого вы хотите использовать манипуляции жестами. Для этого нужно просто добавлять строчку IsManipulationEnabled=true в XAML-код, как это показано в следующем примере:

 <Border Margin="10,5" 
    BorderBrush="DarkGoldenrod" 
    BorderThickness="2" 
        CornerRadius="10" 
    MinHeight="75" 
    IsManipulationEnabled="true">

Дополнительно можно также связать события ManipulationStarting и ManipulationCompleted для обеспечения выделенного кода реализации этих событий.

WPF 4.0 также поддерживает низкоуровневые сообщения о касаниях или необработанный ввод касаний. Таким образом можно взаимодействовать с событиями любых объектов UIElement, используя TouchDown, TouchMove и TouchUp. Для каждого из них есть версия для предварительной обработки. Это может быть полезно, если вы пытаетесь отслеживать несколько касаний, которые управляют разными объектами, или когда вы хотите обеспечить различную реакцию приложения на касания и передвижения мыши. В скором времени мы подробнее напишем про технологию мультисенсорного ввода в Windows 7 в общем и в WPF в частности.

Обновления MFC

В Visual Studio 2010 среды С++ и MFC получили несколько обновлений, среди которых такие полезные функции, как расширения IntelliSense и возможности C++X0. Серьезному обновлению подверглась библиотека MFC, особенно в отношении панели задач, технологии multi-touch и функции Restart and Recovery:

Панель задач

Панель задач MFC обеспечивает весь функционал, предоставляемый родным COM API панели задач. Нет ничего, что могла бы выполнить одна, и не могла другая. По сути MFC просто «обертывает» Win32 API (как и обычно) в «MFC-подобный» API, который соответствует рекомендациям по стилю программирования MFC Framework. Например, приведенный ниже фрагмент кода устанавливает многослойные иконки:

 CMainFrame* mainFrm = 
dynamic_cast<CMainFrame*>(AfxGetApp()->GetMainWnd());
if (mainFrm)
    mainFrm->SetTaskbarOverlayIcon(IDI_ICON_INFO,L"Info");

Код:

Для начала нужно получить дескриптор для главного окна приложения (окна верхнего уровня), который соответствует Win32 HWND. Затем, вы просто вызываете метод SetTaskbarOverlayIcon, на вход которому в виде параметра подаются HICON и строка содержащая в себе версию текста информации, переданной оверлеем, для соответствия требования доступности. Просто, не так ли?

Класс CFrameWnd библиотеки MFC предоставляет функционал однооконного интерфейса (Single Document Interface, SDI) Windows, перекрывающихся или вплывающих окон Frame Window. В новом MFC этот класс был обновлен, и теперь он поддерживает такие функции панели задач, как многослойные иконки (overlay icon), индикатор выполнения (Progress Bar), списки переходов (jump list) и эскизы (thumbnail).

В панель задач MFC по умолчанию встроена поддержка эскизов, а потому эти эскизы будут отображать любое изменение в пределах просматриваемого окна. Следовательно, за исключением реализации своих собственных способов прорисовки окна, вам не понадобится писать никакого кода для обновления изображения в эскизе.

Для включения эскизов панели задач в MFC-приложении в мастере создания MFC-приложения все пользователям необходимо будет выбрать тип приложения «Multiple document» с включенной опцией «Tabbed documents». Когда приложение запущено, MFC будет делать снимки каждого окна и отправлять их в Taskbar API для отображения в эскизах.

image

Результат будет выглядеть примерно так:

image

Мультисенсорный ввод

В Visual Studio 2010 библиотека MFC также обзавелась поддержкой технологии multi-touch. По умолчанию на touch-совместимых устройствах (таких, как сенсорный экран) Windows 7 посылает сообщения о жестах любому приложению; т.е. по умолчанию Windows 7 отсылает сообщение WM_GESTURE целевым окнам. Все, что делает MFC, это отображает такие сообщения на свои дескрипторы сообщений. MFC предоставляет множество переопределенных дескрипторов сообщений, которые могут получать любой тип жеста, и каждый из которых возвращает булево значение. Если жест был обработан сообщением, соответствующий ему переопределенный дескриптор возвращает TRUE; иначе – FALSE. Потому, если вам, например, нужен дескриптор для жеста «увеличение/уменьшение», все, что вам надо – это реализовать соответствующий дескриптор. Вот список поддерживаемых дескрипторов:

 // Gesture handlers
virtual BOOL OnGestureZoom(CPoint ptCenter, long lDelta);
virtual BOOL OnGesturePan(CPoint ptFrom, CPoint ptTo);
virtual BOOL OnGestureRotate(CPoint ptCenter, double dblAngle);
virtual BOOL OnGesturePressAndTap(CPoint ptFirstFinger, long lDelta);
virtual BOOL OnGestureTwoFingerTap(CPoint ptCenter);

Точно так же, вы можете зарегистрироваться для получения необработанных сообщений о касаниях и стандартных сообщений о жестах. В Windows 7 сообщения о жестах и необработанные сообщения о касаниях являются взаимоисключающими. Если вы зарегистрировались для получения необработанных сообщений о касаниях для какого-либо конкретного окна, это окно прекратит получать сообщения о жестах. Если вы выбрали обработку необработанных сообщений о касаниях, вы должны реализовать следующий дескриптор:

 virtual BOOL OnTouchInput(
                        CPoint pt, 
                        int nInputNumber, 
                        int nInputsCount, 
                        PTOUCHINPUT pInput);

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

Перезагрузка и восстановление через Restart Manager

В Visual Studio 2010 библиотека MFC также обеспечивает естественную поддержку Restart Manager – инструмента, который был представлен еще в операционной системе Windows Vista. Он может помочь приложениям сохранить свои данные, когда обновление требует завершения работы этого приложения или когда происходит неожиданная программная ошибка. Вместо неправильного завершения работы, Restart Manager позволяет приложению выполнить сохранение данных перед закрытием. Кроме того, он может повторно запустить приложение, позволив ему восстановить свое состояние до аварийного завершения работы.

Для новых MFC-приложений можно использовать функцию Restart and Recovery, воспользовавшись мастером MFC Application Wizard, как показано на следующем экране:

Все настраиваемые части API Restart Manager предоставляются пользователю через виртуальные элементы, которые могут быть переопределены.

.NET и платформа Location

.NET 4 включает в себя новое пространство имен Device, которое поддерживает Windows 7 Location API (часть платформы Windows 7 Sensors and Location). Пространство имен System.Device.Location позволяет разработчикам приложений легко получать доступ к информации о местоположении пользователя, использую один единственный API. Информация о местоположении может исходить от множества провайдеров, таких как GPS, триангуляция Wi-Fi и триангуляция с использованием вышек сотовой связи. Классы System.Device.Location образуют единый API для объединения нескольких провайдеров местоположения в компьютере и поддерживают «бесшовную» систему приоритетов и переходов между ними. Разработчику приложений, которые будет использовать этот API, необязательно знать, какая из технологий определения местоположения доступна на отдельно взятом компьютере; таким образом, он освобожден от бремени адаптации приложения к определенной аппаратной конфигурации.

Чтобы получить доступ к информации о местоположении, вам нужно создать объект GeoLocationProvider. Это главный объект Location Manager, через который можно зарегистрироваться для получения уведомлений LocationChange и синхронно считывать последние данные о местоположении. Далее вы должны вызвать метод Start для начала процесса получения данных от текущего провайдера местоположения. Чтобы проверить, доступны ли эти данные, можно воспользоваться свойством Status. Если данные доступны, можно получить данные о местоположении единожды, или же, воспользовавшись событием LocationChanged, непрерывно получать обновления текущего местоположения. Следующий фрагмент кода является значительно упрощенным примером, показывающим как получить текущие координаты GeoCoordinates (широта, долгота):

 GeoLocationProvider provider = new GeoLocationProvider();
provider.Start();
GeoCoordinate coordinate = provider.Location.Coordinate;
if (coordinate != GeoCoordinate.Unknown)
{
  //Business logic here
}

К сожалению, .NET 4 поддерживает только Location API, а не всю платформу Sensor and Location – предполагается, что .NET-реализация функции Location все еще не содержит части Sensor. Для доступа к функции Sensor через управляемый код можно использовать Windows API Code Pack.

Параллельные вычисления и поддержка многоядерности Windows 7

Параллельное программирование в Visual Studio 2010 имеет множество аспектов, таких как Parallel LINQ или другие расширения .NET, требующих поддержки параллельных вычислений, включая операторы, подобные Parallel.For, которые используют System.Threading.Tasks.Task. Разработчики C++ будут рады узнать, что концепции Task также присутствуют в 10-ой версии языка C++, которая поставляется с VS 2010. В случае с неуправляемым кодом параллельная среда выполнения (Concurrency Runtime, ConcRT) знает о процессорных группах Win7 и способна работать с максимум 256 ядрами; ConcRT также использует преимущества планирования непривилегированного режима (User Mode Scheduling, UMS) потоков. Именно поэтому любой вычислительный процесс, построенный на ConcRT, получает выгоду от использования многоядерности. Другими словами, благодаря тому, что Parallel Pattern Library (PPL) и Asynchronous Agents включены в состав Visual C++ 10 CRT и имеют в своей основе ConcRT, любой вычислительный процесс, который вы построите на их базе, будет масштабироваться между 256 ядрами (конечно, вам все равно придется писать код, однако масштабирование будет бесплатным).

Для приложений на управляемом коде ситуация не такая радужная. Управление потоком управляемого стека по умолчанию основывается на .NET ThreadPool (System.Threading.ThreadPool). В нем не применяются API новых процессорных групп Windows 7, и потому он не может автоматически использовать возможности Windows 7 по масштабированию. Максимальное число процессов, которые может использовать threadpool, равно 64. Но еще не все потеряно – вполне возможно написать дополнительный TaskScheduler, который смог бы работать с более чем 64 процессами, и использовать остальную часть библиотеки Task Parallel Library с этим специальным планировщиком. Это было бы крутым проектом для CodePlex, правда?

Visual Studio 2010 включает в себя массу новых технологий и усовершенствований, которые представляют собой своего рода глазурь поверх пирога Windows 7.