Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

04.12.2008 11:18 | Zloy Kak Pё$

Начинаем цикл публикаций, призванных помочь начинающим программистам в создании контекстно-зависимых приложений для Windows 7. Об этом много говорили на PDC да и мы неоднократно писали о этом новом классе приложений. Пользователи Windows 7 build 6801 могли заметить появление в гаджете погоды опции автоматического определения местоположения компьютера. И сегодня у вас появилась уникальная возможность попробовать себя в создании подобных приложений.

Я решил немного поиграть с Windows Location Platform, входящей в состав Windows 7 build 6801, которая была роздана посетителям конференции PDC 2008, и решил попробовать создать свое WPF-приложение, которое показывало бы карту Virtual Earth и мое местоположение на ней.

В сборке 6801 всем СОМ-классы Location API обозначены как ThreadingModel = Free (MTA). Поэтому, для того чтобы вызвать их из другой потоковой модели (STA), придется прибегнуть к промежуточным классам. Похоже, что сборка, генерируемая VS (LocationDispLib.dll), не включает в себя эти самые промежуточные классы для COM-распределения. Таким образом, для получения доступа к Location API нам необходимо использовать другой поток, который позволит использовать эти данные в нашем WPF-приложении.


Что нужно для создания приложения



Сценарии, которые позволяет реализовать приложение

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



Запускаем приложение.

Нажимаем на кнопку Show Me on Map, Windows Location Platform получает координаты, приложение отмечает текущее местоположение на карте.

Приложение отслеживает перемещения и ежесекундно отмечает их.

Как это реализовано
Windows Location Platform API представлены COM- и Win32-объектами. Для упрощения программирования мы воспользуемся COM-версией API, которая внедрена в файл LocationDisp.dll в папке %Windir%\System32\ (в x86-версии). Для использования данного API нам необходимо добавить в проект ссылку на эту библиотеку.

1. Так как API запускаются в режиме MTA, а основное WPF-приложение в STA, нам нужно использовать отдельный поток для того, чтобы наше приложение могло получить информацию от API.

  • BackgroundWorker m_worker предназначен для обработки изменения местоположения, а второй BackgroundWorker m_workerStatus добавляем в определение Window1:

    BackgroundWorker m_worker = new BackgroundWorker();
    BackgroundWorker m_workerStatus = new
    BackgroundWorker();
    private LatLongReport m_report = new LatLongReport();
    private LocationPlatformStatus m_status = new LocationPlatformStatus();
    DispatcherTimer m_timerAutoTracking = new DispatcherTimer();
    DispatcherTimer m_timerLocPlatformStatus = new DispatcherTimer();
    bool m_useAutoTracking = false;



    Таймеры будут использоваться для обработки изменения местоположения (m_timerAutoTracking). LatLongReport - .NET упаковщик для класса DispLatLongReport из Interop.LocationDisp.dll, которая была создана из LocationDisp.dll силами Visual Studio. Она необходима для того, чтобы несколько упростить COM-функцию, вызываемую в .NET-приложении.

  • В конструкторе Window1 мы инициализируем и фоновые исполнители, и таймеры:

    public Window1()
            {
                InitializeComponent();

                m_worker.DoWork += new DoWorkEventHandler(worker_DoWork);
                m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

                m_workerStatus.DoWork += new DoWorkEventHandler(m_workerStatus_DoWork);
                m_workerStatus.RunWorkerCompleted += new RunWorkerCompletedEventHandler

    (m_workerStatus_RunWorkerCompleted);

                m_timerAutoTracking.Interval = new TimeSpan(0, 0, 0, 0, 1000);
                m_timerAutoTracking.Tick += new EventHandler(m_timer_Tick);

                m_timerLocPlatformStatus.Interval = new TimeSpan(0, 0, 0, 0, 1000);
                m_timerLocPlatformStatus.Tick += new EventHandler(m_timerLocPlatformStatus_Tick);

                // enabling Status Timer

                m_timerLocPlatformStatus.Start();
            }



    Здесь мы просто инициализировали асинхронные обработчики событий DoWork и RunWorkerCompleted для обоих исполнителей Background Worker, настров интервал в 1 секунду для таймеров и обработчиков их событий.

  • Вызов Windows Location Platform API
    Нажав кнопку Show Me On Map, пользователь инициализирует в приложении соответствующую команду и она запускает асинхронный исполнитель Background Worker m_worker:

    public void ShowMeOnMapCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
    try
    { m_worker.RunWorkerAsync();
    } catch
    {
    // some times it can't do the job at 1 sec
    }
    }



    Тут, однако, есть маленькая проблема. Так как мы не подписываемся на события через Location API, но при этом вызываем их, используя таймеры, исполнители Background Worker могут столкнуться с проблемой, при которой они не успели завершить свою работу. Чтобы не усложнять приложение, я решил добавить здесь блок.

    RunWorkerAsync() включает событие DoWork() из фонового исполнителя m_worker:

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
    LatLongReportFactoryClass factory = new LatLongReportFactoryClass();
    m_report = new LatLongReport(factory.LatLongReport);
    }



    Именно здесь происходит реальное обращение к Windows Location API. То есть нам необходимо сослаться на LatLongReportFactoryClass и получить от него LatLongReport, который и будет использоваться в приложении. В действительности, первое, что нам необходимо сделать - проверить поле LatLongFactoryClass.Status, чтобы убедится, что сенсоры доступны и работают.

  • Когда фоновый исполнитель m_worker завершит получение LatLongReport, нам нужно создать на карте новый PushPin, дать ему текущие координаты и показать на карте.

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
    if (e.Cancelled)
    {
    //Cancelled
    }
    else if (e.Error != null)
    {
    //Exception Thrown }
    else
    {
    //Completed
    PushPin pushPin = new PushPin();
    pushPin.Latitude = m_report.Latitude;
    pushPin.Longitude = m_report.Longitude; t
    his.VirtualEarth.PushPins.Add(pushPin);
    pushPin.CenterInMap();
    }
    }



    В данном методе мы центрируем карту, чтобы созданная отметка показывалась по центру Virtual Earth. В случае если сенсоры присутствуют, включены и доступны, нажатие кнопки Show Me on Map покажет в центре карты Virtual Earth нашу позицию.



2. Для реализации автоматического обновления местоположения мы используем таймер Dispatcher Timer m_timer, который автоматически будет запускать Background Worker m_worker для получения информации о местоположении.

Для этого мы просто добавим в обработчик вызова кнопки Show/Stop showing My Trip on Map Automatically вызов Start/Stop m_timer, а для отметки на карте - m_worker.RunWorkerA.

3. Чтобы очистить карту, требуется вызвать метод “Clear” из коллекции контролов “PushPins”.

Теперь вы знаете, как вызывать Windows 7 Location Platform API с целью получить информацию о местоположении пользователя, и использовать ее в WPF-приложении.

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


Источник: http://blogs.msdn.com/semantics
Перевод: Zloy Kak Pё$

Комментарии

Не в сети

Спасибо за статью!!!
Не зря все-таки ставил W7 Будем пробовать...

04.12.08 12:05
0
Не в сети

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

06.12.08 13:03
0
Не в сети

Ribbon использовать удобно для того, чтобы пальцами взаимодействовать с пользовательским интерфейсом. Плюс я планирую добавить новый фукнционал, так что польза от Риббон-Интерфейса ;)

скачать программу для Windows 7 Beta можно тут: http://blogs.msdn.com/wincontext/archive/2009/01/22/windows-7-windows-7-navigation-application.aspx

22.01.09 16:25
0
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.029 секунд (Общее время SQL: 0.014 секунд - SQL запросов: 57 - Среднее время SQL: 0.00024 секунд))
Top.Mail.Ru