Мобильное программирование: Visual Basic .NET приходит на мобильные устройства (исходники, документация)

Описывается, как разрабатывать Windows-приложения для интеллектуальных устройств, поддерживающих .NET Compact Framework, с помощью SDE (Smart Device Extensions) for Visual Studio .NET. Рассматривается весь цикл разработки, отладки и развертывания приложения, а также показываются отличия между .NET Framework и .NET Compact Framework.

Smart Device Extensions (SDE) for Microsoft Visual Studio .NET позволяет применить весь ваш опыт .NET-программирования при разработке Windows-приложений для "интеллектуальных" устройств, поддерживающих Microsoft .NET Compact Framework. С помощью SDE можно создавать приложения для платформ Pocket PC и Microsoft Windows CE .NET, используя знакомые языки - Microsoft Visual Basic .NET (или Microsoft Visual C#) и те же инструментальные средства и библиотеки классов, что и при разработке .NET-приложений для настольных компьютеров и серверов. Так как интеллектуальные устройства не поддерживают все возможности, предоставляемые их полноразмерными "сородичами", самое сложное - выяснить, какие составные части Microsoft .NET Framework претерпели изменения из-за приведения этой инфраструктуры в соответствие с ограниченными возможностями мобильных устройств. К счастью, среда Visual Studio полностью поддерживает мобильные устройства и, в частности, позволяет отлаживать на настольном компьютере приложения, рассчитанные на эти устройства.

Создавать SDE-приложения в Visual Basic .NET настолько просто, что у вас может возникнуть соблазн сразу же приступить к созданию SDE-проекта, поместить элементы управления на форму и написать какой-либо код. В ближайшее время мы так и поступим. Но, кроме того, я рассмотрю весь цикл разработки, отладки и развертывания и покажу, где проявляется особая природа SDE-программирования и становятся заметными отличия от разработки для настольных приложений. А тем, кого интересует техническая сторона, я расскажу, что происходит "за кулисами".

Приложение "Hello World"

Начнем с традиционного приложения "Hello World" - несмотря на очевидную тривиальность, его вполне достаточно для демонстрации всего процесса разработки, который применительно к интеллектуальным устройствам состоит из следующих этапов.

  1. Создание приложения в Visual Studio .NET на настольном компьютере.
  2. Развертывание приложения на устройстве.
  3. Отладка приложения в Visual Studio .NET.

Будем считать, что вы установили Visual Studio .NET и SDE (Smart Device Extensions) и что у вас имеется подключенное устройство или (при отсутствии настоящего устройства) эмулятор Pocket PC.

  1. Создание нового SDE-проекта в Visual Basic .NET.
    1. Откройте диалоговое окно "New Project" и выберите шаблон "Smart Device Application" из группы "Visual Basic Projects" (рис. 1).

      Рис. 1. Диалоговое окно New Project, шаблон Smart Device Application

    2. При необходимости измените местонахождение проекта в поле Location. Возможно, вам будет удобнее создать для разработки SDE-приложений отдельный подкаталог, находящийся вне используемого по умолчанию дерева каталогов исходного кода.
    3. В поле Name введите имя приложения (например, "HelloWorld"). В каталоге, указанном в поле Location, будет создан новый каталог с исходным кодом вашего приложения.
    4. Щелкните OK.
  2. Это приведет к запуску Smart Device Application Wizard (рис. 2). Вам нужно выбрать платформу, для которой ведется разработка, - Windows CE или Pocket PC (где Pocket PC является специфическим типом устройства Windows CE). От этого выбора зависит, какой шаблон проекта будут использоваться для построения изначально пустого приложения. Так, в форме шаблона "Windows Application" для Pocket PC присутствует элемент управления MainMenu, которого нет в шаблоне для платформы Windows CE.

    Рис. 2. Smart Device Application Wizard

    1. Выберите платформу (если будете использовать эмулятор, укажите Pocket PC).
    2. Выберите тип проекта. Для нашего первого приложения, которое просто будет показывать форму на устройстве, выберите "Windows Application".
    3. Щелкните OK, после чего мастер создаст проект (это может занять какое-то время).

    Вы должны увидеть приложение на Visual Basic .NET, выглядящее, как показано на рис. 3. Расположение окон у вас скорее всего будет немного другим, так как Visual Studio запоминает позиции окон, заданные при работе с другими проектами.

    Рис. 3. SDE-проект, открытый в Visual Basic .NET

Уделите пару секунд изучению окон Visual Studio. Обратите внимание: вы видите почти то же, что и при разработке настольных приложений на Visual Basic .NET. Первое, что бросается в глаза, - отсутствие в первой версии SDE некоторых компонентов, показываемых на вкладке Device Controls окна Toolbox, например диалоговых окон (Color, Files, Font, Print) и "продвинутых" элементов пользовательского интерфейса (Calendar, ImageList, DataGrid). Кроме того, появилась панель инструментов Device Extensions. И если вы выберете что-нибудь на форме (размер которой задан в соответствии с характеристиками целевого интеллектуального устройства), то увидите, что в окне Properties показывается меньше свойств.

Теперь выполним оставшиеся действия по созданию небольшой тестовой программы.

  1. Поместите на форму кнопку (элемент управления Button). Обратите внимание на плоский вид кнопки - такой стиль обычно используется на портативных устройствах.
  2. Дважды щелкните кнопку (или как-то иначе откройте окно кода) и в обработчике события Click кнопки введите следующий код:

    MsgBox("Hello World")
  3. Нажмите <F9>, чтобы установить в этой строке точку прерывания.
  4. Нажмите <F11>, чтобы начать пошаговое выполнение приложения. При этом приложение компилируется (информация о ходе компиляции показывается в окне Output), а затем открывается диалоговое окно Deploy.
  5. Выберите целевое устройство (мы будем использовать Pocket PC Emulator) и щелкните Deploy, чтобы приступить к развертыванию. Как и при компиляции, информация о ходе развертывания показывается в окне Output, а в строке состояния Visual Studio .NET выводится текущая информация.
    Примечание Если в вашей конфигурации SDE есть какие-либо ошибки, они проявятся именно на этом этапе. Если вы прочитали и выполнили инструкции по установке, то, как правило, проблема может возникнуть только одна: не удается соединиться с устройством. Заметьте, что в данной версии SDE даже при использовании эмулятора требуется, чтобы у компьютера был сетевой адрес. Если проблемы с установкой соединения решить не удалось, пожалуйста, прочитайте соответствующую документацию.

Visual Studio .NET свяжется с устройством и установит вашу программу. Прежде всего на устройство установится .NET Compact Framework, если этой инфраструктуры еще не было на устройстве. Затем ваше приложение будет скопировано в каталог Windows (по умолчанию). И, наконец, приложение запустится.

Итак, программа выполняется на интеллектуальном устройстве (или эмуляторе), и в то же время вы отлаживаете ее в Visual Studio .NET на настольном компьютере. Вы можете исследовать приложение по своему усмотрению или выполнить следующие демонстрационные операции:

  1. Поскольку выполняется пошаговая отладка, вы находитесь сейчас на первой строке программы:Application.Run(New Form1())
  2. Обратите внимание: вам полностью доступна привычная среда разработки Visual Studio .NET, в частности такие окна, как Locals, Immediate (Command), Call Stack и т. д.
  3. Продолжайте выполнение программы в пошаговом режиме. Теперь вы попадете в конструктор (New), а затем в подпрограмму InitializeComponent. После выполнения оператора Application.Run в методе Main устройство снова получит фокус (при использовании эмулятора), и на экране появится форма.
  4. Щелкните кнопку на форме. Вы снова вернетесь в Visual Studio .NET, так как мы установили точку прерывания в обработчике события Click кнопки.
  5. Продолжайте пошаговое выполнение программы, пока на интеллектуальном устройстве не откроется диалоговое окно (рис. 4).

    Рис. 4. Диалоговое окно "HelloWorld", показываемое на устройстве

  6. Щелкните кнопку OK в правом верхнем углу диалогового окна устройства, чтобы закрыть это окно.
  7. Снова перейдите в отладчик, в пошаговом режиме закройте диалоговое окно и вернитесь в исходную точку.
  8. Щелкните кнопку OK в правом верхнем углу формы на интеллектуальном устройстве.
  9. При этом вы вернетесь в Visual Studio .NET в конец метода. Заметьте, что приложение исчезло с экрана устройства.
  10. Выполните еще один или несколько шагов программы для выхода из отладчика.

Итак, мы создали приложение (пусть и тривиальное), развернули его на интеллектуальном устройстве и отладили в Visual Studio .NET на настольном компьютере. Все это наверняка показалось вам очень знакомым, так как при разработке других приложений в Visual Studio .NET вы делали почти то же самое. Теперь закончим разработку приложения и создадим редистрибутивный пакет, чтобы вы могли поделиться этой мощной программой с друзьями и удивить их своим мастерством программирования для интеллектуальных устройств! О, так вы и вправду считаете, что эта программа ниччего не может? Нет проблем - чуть позже мы что-нибудь придумаем.

Заключительная часть разработки приложения

Так как мы хотим, чтобы наша программа для интеллектуального устройства выглядела как настоящее профессиональное приложение, добавим в нее значок (icon) и создадим редистрибутивный CAB-файл. Затем CAB-файл можно будет открыть и запустить щелчком или касанием указателя (tap), либо предварительно скопировать этот файл на устройство. CAB-файл можно запускать из любого места, так как он содержит всю информацию по установке, необходимую интеллектуальному устройству. При запуске CAB-файла из него автоматически извлекаются файлы приложения и помещаются в подкаталог каталога Program Files с тем же именем, что и проект для интеллектуального устройства.

Вы можете управлять тем, куда устанавливаются файлы приложения. Для этого нужно перед запуском мастера CAB-файлов указать свой INF-файл (с расширением .inf) и при необходимости библиотеку Setup.dll. В INF-файле задаются каталоги, файлы, параметры и конфигурации. В файле Setup.dll (необязательном) содержатся функции, реализующие операции, которые выполняются при установке или удалении вашего приложения. Дополнительную информацию по этой теме см. в документации SDE.

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

  1. Выберите Properties в меню Project, а в узле Common Properties - подузел Build.
  2. В поле Application Icon, предназначенном для задания местоположения значка приложения, найдите и выберите подходящий значок (ICO-файл). С Visual Studio .NET поставляется много значков. По умолчанию они устанавливаются в подкаталог C:Program FilesMicrosoft Visual Studio .NETCommon7Graphicsicons. В нашем примере выберем exclem.ico из подкаталога Misc.
  3. К файлам проекта будет добавлен значок, а параметру Build Action для файла значка будет присвоено значение Content.
    Теперь все готово к компиляции приложения и созданию редистрибутивного пакета.
  4. Выберите Build Cab File в меню Build. При этом в подкаталоге inDebug вашей программы будет создан свой CAB-файл для каждой аппаратной платформы, поддерживаемой SDE. Поскольку имя нашего приложения - "HelloWorld", файл для Pocket PC получит имя HelloWorld_PPC.ARM.cab, а аналогичный файл для эмулятора - HelloWorld_PPC.X86.cab.

На этом этапе CAB-файл программы можно скопировать на устройство. Однако сначала следует убедиться, что на устройстве уже установлена .NET Compact Framework. Если известно, что эта инфраструктура не установлена на устройстве или что требуется создать дистрибутив для других пользователей, тогда вы должны создать CAB-файл для инфраструктуры. По умолчанию эти CAB-файлы устанавливаются с SDE в каталог:


C:Program FilesMicrosoft Visual Studio .NET
CompactFrameworkSDKv1.0.3300Windows CEwce300

CAB-файлы хранятся в подкаталогах в соответствии с типами процессоров устройств - например, файл с версией инфраструктуры для Pocket PC находится в подкаталоге arm под именем netcf.cjk.ppc3.arm.cab. Файл с инфраструктурой для эмулятора содержится в подкаталоге x86 под именем netcf.cjk.ppc3.x86.cab.

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

  1. Создайте для приложения общий сетевой каталог.
    1. Создайте на настольном компьютере каталог для размещения CAB-файлов приложения и инфраструктуры.
    2. Сконфигурируйте этот каталог как доступный через сеть.
    3. Скопируйте CAB-файлы приложения и инфраструктуры .NET Compact Framework в этот каталог.
    4. (При необходимости) Обычно у устройств размер дисплея значительно меньше, чем у настольных компьютеров, поэтому длинные имена файлов "обрезаются". Возможно, вам покажется удобным переименовать CAB-файлы, присвоив им более короткие имена (чтобы было проще просматривать эти файлы на устройстве).
  2. Скопируйте файлы по сети.
    1. Щелкните значок доступа к общим каталогам (Network Share) внизу устройства (рис. 5).

      Рис. 5. Значок, используемый для доступа к общим каталогам

    2. Откроется диалоговое окно Open. Введите имя настольного компьютера, чтобы посмотреть список общих каталогов или сразу введите полное UNC-имя каталога, чтобы к нему подключиться.
      Примечание Вы можете получить сообщение об ошибке, утверждающее, что устройство с таким именем уже есть в сети. Тогда переименуйте устройство, выполнив на нем следующее.
      1. Выберите Settings в меню Start.
      2. Выберите вкладку System.
      3. Щелкните или выберите значок About.
      4. Выберите вкладку Device ID.
      5. Введите новое имя устройства.
      6. Щелкните или выберите кнопку OK в правом верхнем углу диалогового окна.
    3. Если откроется диалоговое окно Logon to Network Server, введите в поля User name, Password и Domain соответственно имя пользователя, пароль и имя домена. Щелкните флажок Save password, чтобы это диалоговое окно не открывалось в дальнейшем.
    4. На вашем устройстве появится содержимое общедоступного каталога (рис. 6).

      Рис. 6. Общий каталог на настольном компьютере

    5. Чтобы скопировать на устройство CAB-файл .NET Compact Framework, выберите CAB-файл (удерживая нажатым перо или кнопку мыши) и выберите Copy во всплывающем меню.
    6. Затем перейдите в какой-нибудь каталог устройства (например, My Documents). Щелкните Edit внизу устройства и выберите Paste. Должно открыться диалоговое окно, информирующее о ходе операции копирования.
    7. Для запуска установки щелкните или выберите CAB-файл. .NET Compact Framework установится на устройство, а CAB-файл будет удален, чтобы не занимать память.
      Примечание Возможно, вы получите сообщение об ошибке "The application cannot run on this device type". Это означает, что вы скопировали не тот CAB-файл, поэтому нужно снова выполнить предыдущие шаги и скопировать правильный CAB-файл.
    8. Наконец, выполните эти действия с CAB-файлом приложения. При этом в каталоге Program Files создается подкаталог с таким же именем, что и у приложения, и в этот каталог устанавливаются приложение и используемые им файлы (рис. 7).

      Рис. 7. Приложение"HelloWorld" на устройстве

  3. Последняя операция, которую вы, вероятно, захотите выполнить, - создание ярлыка программы в меню Start устройства.
    1. Найдите файл приложения HelloWorld в подкаталоге WindowsHello World.
    2. Выберите файл и удерживайте в нажатом состоянии кнопку (или перо на реальном устройстве), чтобы открыть контекстное меню, затем выберите Copy.
    3. Перейдите в подкаталог WindowsStart MenuPrograms, щелкните или выберите меню Edit в левом нижнем углу и выберите Paste Shortcut.
    4. Так как по умолчанию имя ярлыка начинается с "Shortcut to . . ." (рис. 8), возможно, имеет смысл воспользоваться удобным случаем и переименовать ярлык.

    Рис. 8. Ярлык "HelloWorld" на устройстве

Что внутри?

Итак, что же происходит в действительности, когда вы создаете и запускаете SDE-приложение HelloWorld? Самое важное, о чем нужно знать: когда вы выбираете создание SDE-проекта, вы начинаете работать с другим шаблоном, чем при создании настольного проекта. В частности, разработка ведется для .NET Compact Framework, а не для полной версии инфраструктуры.

Рассмотрим структуру только что созданной программы HelloWorld (в принципе, подойдет любой SDE-проект). Окна проекта показаны на рис. 9.

  1. Откройте окно Solution Explorer.
  2. Раскройте узел References.
  3. Выберите ссылку (например, System).
  4. Посмотрите свойство Path в окне Properties:


C:Program FilesMicrosoft Visual Studio .NETCompactFrameworkSDKv1.0.3300Windows CESystem.dll

Рис. 9. Ссылки SDE-проекта

При разработке настольных приложений используются .NET Framework-сборки, размещаемые в Global Assembly Cache (GAC). Эти сборки находятся в кэше на каждом настольном компьютере, на котором установлена .NET Framework. Однако чтобы воспользоваться сборками при программировании для мобильного устройства, их приходится развертывать на этом устройстве. При установке SDE эти сборки копируются в подкаталог CompactFrameworkSDKv1.0.3300Windows CE каталога Microsoft Visual Studio .NET. Если вы просмотрите содержимое этого подкаталога, то обнаружите подкаталоги arm, mips, sh3 и x86, соответствующие типам процессоров, поддерживаемых .NET Compact Framework. В этих подкаталогах находятся редистрибутивные CAB-файлы, о которых я рассказывал в разделе, посвященном развертыванию HelloWorld.

А сейчас немного базовой информации. При компиляции проекта в Visual Studio .NET исходный код компилируется в одну или несколько сборок (файлов с расширениями .EXE и .DLL). В этих .NET-сборках содержатся метаданные и код на языке MSIL (Microsoft Intermediate Language). Машинный исполняемый код в сборках не содержится. Вместо этого во время выполнения осуществляется компиляция по запросу (JIT-компиляция) MSIL-кода в машинный. Конечно, в ваших приложениях активно используются типы, определенные в библиотеке классов .NET Framework, которая также является набором сборок, содержащих метаданные и MSIL-код. Эти сборки скомпилированы и хранятся на вашем настольном компьютере в каталоге исполняющей среды.

Как вы могли догадаться, в SDE при компиляции сборок, использующих .NET Compact Framework, применяются те же принципы. Поскольку эти сборки содержат MSIL, а не машинный код, при разработке программы на настольном компьютере используются, по сути, те же сборки .NET Compact Framework, что и сборки, развертываемые на устройстве! Можно всесторонне исследовать какую-нибудь из сборок .NET Compact Framework, например, system.dll, с помощью утилиты ildasm.exe из состава .NET Framework SDK (она устанавливается с Visual Studio .NET) (рис. 10).

Рис. 10. Исследование сборки NET Compact Framework system.dll с помощью ILDASM

Visual Studio .NET

При установке Smart Device Extensions (SDE) for Visual Studio .NET, помимо всего прочего, устанавливается и .NET Compact Framework SDK размером 111 Мбайт, размещаемый в папке C:Program FilesMicrosoft Visual Studio .NETCompactFrameworkSDK. Кроме того, при установке SDE вносится несколько тонких изменений в Visual Studio .NET. Например, одной из особенностей SDE является возможность развертывания и тестирования приложений на эмуляторе интеллектуального устройства. Для настройки эмулятора выберите Options в меню Tools, перейдите на вкладку Device Extensions, выберите Devices и, наконец, выберите Pocket PC Emulator.

Рис. 11. Настройка параметров эмулятора

Самые важные параметры конфигурации - размеры экрана (меньшие, чем у настольного компьютера и обычно составляющие 240 ? 320 пикселов).

При установке SDE появляется дополнительная команда в меню Build, позволяющий выполнять развертывание прямо на устройство. Кроме того, меню Build дает возможность осуществлять пакетную сборку (batch build), при которой за один прием компилируются конфигурации для нескольких проектов, и создавать CAB-файл для дистрибутива.

Compact'ный .NET Framework

Пожалуй, основная проблема при работе с мобильными устройствами - их аппаратные ограничения. Очевидно, размер экрана портативных устройств меньше, чем у компьютеров (обычно 320 ? 240 пикселов). Мощность процессора у них еще меньше (в первую очередь по соображениям продления срока работы от аккумуляторной батареи). Объем памяти, обычно используемой для длительного хранения данных, у таких устройств тоже намного меньше, чем у компьютеров. Кроме того, используются несколько иные методы ввода. У типичного целевого устройства SDE имеется от 16 до 64 Мбайт памяти для постоянного хранения программ и для их выполнения.

В состав полной .NET Framework входят фундаментальная библиотека классов, общеязыковая исполняющая среда (Common Language Runtime, CLR) и другие инфраструктуры вроде ASP.NET. Полная .NET Framework распространяется в CAB-файле размером 16 Мбайт и занимает при установке на настольный компьютер около 43 Мбайт дискового пространства (общие требования к дисковому пространству вдвое больше, так как большинство сборок образует Global Assembly Cache). Самая маленькая Windows Forms-программа использует файлы общим объемом более 8 Мбайт. Очевидно, что полная .NET Framework предъявляет к пространству для хранения данных и к памяти требования, слишком высокие для мобильных устройств с ограниченными аппаратными возможностями.

При установке .NET Compact Framework требуется примерно 1,3 Мбайт дискового пространства (общий размер файлов - 2,0 Мбайт, но он сокращается за счет оптимизации хранения файлов в Windows CE). При запуске SDE-программы на устройстве загружаются CLR и код приложения, так что для работы SDE-программы, использующей Windows Forms, требуется минимум 1 Мбайт. Дополнительные копии такого приложения будут требовать значительно меньше памяти (около 0,75 Мб каждая).

Так как общий размер файлов .NET Compact Framework примерно в 20 раз меньше, чем в полной .NET Framework, и, например, Windows Forms-программа для устройства требует в 8 раз меньше памяти, очевидно, что .NET Compact Framework тщательно оптимизирована самыми разными способами.

Интеллектуальные устройства не работают Web-серверами ASP.NET (хотя это, конечно, интригующая идея), так что в компактной версии инфраструктуры не нужна поддержка Web Forms и языковых компиляторов, входящих в состав .NET Framework. Поскольку приложение разрабатывается на настольном компьютере и только потом развертывается на устройстве, не нужна и поддержка таких средств, как визуальные дизайнеры, а также серверной функциональности, например Active Directory и Enterprise Services. В табл. 1 сравниваются размеры (в Кбайт) основных пространств имен, используемых в полной и компактной версиях .NET Framework.

Табл. 1. Размеры пространств имен библиотеки классов (в Кбайт)

  Полная      Компактная      Пространство имен   
1374 140 Microsoft (языки и поддержка)
3044 540 System
1148 755 System.Data
1708 78 System.Web
452 34 System.Drawing
1936 118 System.Windows.Forms
1264 192 System.XML
1652 0 System.Design
1491 82 System (прочее)
14 068  1938   

Примечание Таблица не отражает сжатие .NET Compact Framework на Windows CE-устройствах, что сокращает общий размер файлов примерно до 1,5 Мбайт.

Библиотека поддержки Visual Basic

Одной из областей, в которых при переходе к .NET-программированию для мобильных устройств сохранилась большая часть функциональности, - библиотека поддержки Visual Basic .NET, содержащаяся в сборке Microsoft.VisualBasic.dll. У Visual Basic .NET больше нет собственной исполняющей среды (приложения, написанные на нем, используют те же CLR и .NET Framework, что и остальные .NET-приложения), но Microsoft поставляет эту сборку с многочисленными функциями, типами и константами для совместимости с предыдущими версиями Visual Basic. В версии этой DLL, используемой в .NET Compact Framework, сохранена большая часть такой функциональности (размер DLL примерно в 2 раза меньше размера полной версии).

В частности, в версии этой библиотеки для мобильных устройств полностью поддерживаются класс Collection, функции преобразования типов, управляющие символы, DateTime, MsgBox и общеупотребительные константы вроде CrLf. Но из библиотеки удалены:

  • константы FileAttributes, FileSystem и Open;
  • вариантные типы (vbArray, vbBoolean, vbNull и другие типы данных Variant, а также функции VarType);
  • преобразования регистра, языка и другие строковые преобразования;
  • функция Len (не та, которая работает со строками);
  • функции AppActivate, Shell и Environment;
  • CreateObject, GetObject, CallByName.

Если проанализировать, какие возможности отсутствуют в .NET Compact Framework, то окажется, что большинство этих упрощений вполне оправданно. Например, в Windows CE используются собственная файловая система, так что код файлового ввода-вывода для Windows CE-устройств будет совершенно другим, чем для настольных компьютеров. В .NET Compact Framework также нет поддержки взаимодействия с COM-компонентами, поэтому не нужны функции, используемые COM (например, CreateObject), и вариантные типы (работать с COM-типами данных не требуется).

Windows Forms

В большинстве программ для интеллектуальных устройств применяется пользовательский интерфейс на основе Windows. Поэтому изменения, внесенные в Windows Forms, представляют огромный интерес для разработчиков, желающих писать программы для устройств с малым форм-фактором. Поскольку приложения, использующие формы, должны быть отлично знакомы программисту на Visual Basic, ваш предыдущий опыт окажется весьма кстати.

Для начала посмотрим на список элементов управления, входящих в версию Windows Forms для .NET Compact Framework:


Button PictureBox
CheckBox ProgressBar
Combobox RadioButton
DomainUpDoan StatusBar
HScrollBar TabControl
Label TextBox
ListBox Timer
MainMenu TrackBar
NumericUpDown VScrollBar
Panel  

Как видите, основные элементы управления (и не только основные) по-прежнему присутствуют, так что разработка небольших приложений и утилит для интеллектуальных устройств не составляет сложности. Однако некоторые "продвинутые" элементы управления полной версии .NET Framework недоступны. Многие из них, например Command, PropertyStore и ToolTip, или не годятся для портативных устройств, или должны реализовываться в Windows CE совершенно по-другому. Некоторые элементы управления, например Splitter, требуют выполнения пользовательским интерфейсом операций, непривычных большинству пользователей, работающих с портативными устройствами. Другие элементы управления вроде CheckedListBox можно имитировать, комбинируя элементы более низкого уровня. Вы также обнаружите, что недоступны и другие возможности полной версии Windows Forms, такие как HTML Help и средства прямого взаимодействия с операционной системой, например NativeWindows, SendKeys, OSFeature (используется для поддержки тем) и SystemInformation.

Форма и элементы управления

В версии класса Form .NET Compact Framework поддерживаются более трех четвертей событий и методов и примерно половина свойств класса Form полной версии. Можно задавать цвета, некоторые стили, подключать меню. Нельзя создать MDI-приложение, показать форму в панели задач, реализовать операции drag-and-drop и обрабатывать ряд событий клавиатуры (например, нажатие кнопки Cancel), не используемые на портативных устройствах.

Рассмотрим один из элементов управления - TabControl - и обсудим, что в версии для .NET Compact Framework осталось прежним, а что изменилось. Как и раньше, вкладки настраиваются в TabPage Collection Editor:

Рис. 12. Элемент управления TabControl в TabPage Collection Editor

Возможностей для настройки внешнего вида вкладок меньше, чем в полной версии. Не поддерживаются такие "продвинутые" параметры, как свойства группы Behavior (AllowDrop, ContextMenu, ImeMode) и AutoScroll. Но эти параметры используются не часто. Единственное широко применяемое свойство, отсутствующее в компактной версии, - свойство Tag. То же относится и к самому TabControl: основные свойства UI сохранились, но некоторые возможности не применимы к Windows CE-устройствам, поэтому, например, свойства ContextMenu и ToolTipText отсутствуют в компактной версии. Другие свойства просто убраны для сокращения размера элемента управления. Отсутствуют и такие свойства, как Accessibility и DataBinding, - они зависимы от других средств .NET Framework, которые также отсутствуют.

Разработка SDE-приложений

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

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

.NET Compact Framework SDK, поставляемый с SDE, включает набор программ-примеров, демонстрирующих базовые приемы разработки для платформ портативных устройств. Вы можете использовать эти программы как основу для своих приложений. Доступны следующие примеры.

  • Bubble - рисование и заливка графических фигур с помощью кисти на Windows-форме. Также демонстрируется создание потока (thread).
  • Calculator - демонстрирует программирование для Windows Forms, в том числе работу с элементами управления и обработку событий.
  • Scribbler - версия классической программы рисования Scribble, в которой для рисования на Windows-форме используется GDI+. Кроме того, показывается, как рисовать на поверхности, находящейся за экраном, и отслеживать перемещение мыши.
  • Inventory - демонстрирует сериализацию набора данных в XML, использование ADO.NET для доступа к SQL Server и работу с Windows Forms. Кроме того, показывается, как загружать ресурсы с изображениями из файлов.
  • Stock Quote - вызов Web-сервиса XML в Windows Forms. В примере содержится и сам Web-сервис.
  • WaitCursor - объявление Win32-функций и обращение к ним.

Кроме того, к этому документу прилагаются два примера, демонстрирующие некоторые аспекты программирования для интеллектуальных устройств на Visual Basic.

  • Authors - заполнение ListView записями DataSet, создаваемого по XML-документу.
  • PowerStatus - объявление Win32-функций операционной системы Windows CE и обращение к ним.

Использование ListView

Одним из элементов управления, чаще всего используемых разработчиками на Visual Basic, является сетка того или иного вида, в которой показываются табличные данные. Хотя в .NET Compact Framework сетки отсутствуют, вместо них можно применить элемент управления ListView, выглядящий так же, как сетка:

Рис. 13. Пример ListView на мобильном устройстве

Как все это работает, показывается в примере Authors, прилагаемом к данному документу. Прежде всего нужно передать данные на устройство. В нашем примере XML-файл копируется на устройство на этапе разработки. Сначала вы должны добавить файл в проект, и обычно для этого используется команда Add Existing Item в Solution Explorer.

Кроме того, можно указать папку, в которую будут помещаться при развертывании исполняемый файл приложения и файл данных. Для этого нужно или задать Output File Folder в окне Properties проекта, или войти в диалоговое окно Properties проекта, выбрать подузел Device Extensions узла Common Properties и ввести путь в поле Output file folder. В нашем примере использовалась папка SamplesVB.NET, так что в исходном коде также выполняется обращение к файлу в этой папке:


Private Const AUTHORSXML As String = "SamplesVB.NETAuthorsDB.xml"

Затем объявляем DataSet:


Private dsAuthors As System.Data.DataSet

Теперь мы готовы к тому, чтобы загрузить XML-файл в DataSet методом ReadXml:


Private Sub loadXMLData()
dsAuthors = New DataSet("AuthorsDB")
Try
Dim fs As New FileStream(AUTHORSXML, FileMode.Open)
Dim xr As New XmlTextReader(fs)
dsAuthors.ReadXml(xr)
xr.Close()
fs.Close()
Catch e As System.IO.FileNotFoundException
MessageBox.Show("File " & AUTHORSXML & " not found.")
Catch e As XmlException
MessageBox.Show("XmlException occured")
End Try
End Sub

А вот обработчик события Load класса Form, где вызывается процедура загрузки, а затем DataSet перебирается в цикле, в котором все записи добавляются в элемент управления ListView:


Private Sub frmAuthors_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
loadXMLData()
Dim dr As DataRow
Dim it As ListViewItem
For Each dr In dsAuthors.Tables("Authors").Rows
it = New ListViewItem(dr("id").ToString())
it.SubItems.Add(dr("name").ToString())
it.SubItems.Add(dr("phone").ToString())
lvCompanies.Items.Add(it)
Next
End Sub

Наконец, мы задаем свойства элемента управления, в частности Columns. Это делается так же, как и для элемента управления ListView в полной версии .NET Framework, - или в период выполнения, или в редакторе свойств:

Рис. 14. Набор Columns элемента управления ListView

Вызов Web-сервиса

Теперь посмотрим, как вызвать Web-сервис с устройства. В проектах StockQuoteService и StockQuote содержится исходный код Web-сервиса и SDE-проекта соответственно. В отличие от использования XML-файла в примере с ListView здесь XML-файл помещается в главную сборку. Для встраивания файла в сборку требуется присвоить свойству XML-файла Build Action значение Embedded Resource.

Web-сервис StockQuoteService может выполняться как на настольных компьютерах, так и на интеллектуальных устройствах и содержит всего один Web-метод (код обработки ошибок не показан):


<WebMethod()> _
Public Function getQuoteDataSetX() As DataSet
Dim dsIn As New DataSet()
Dim sIn As Stream = [Assembly].GetExecutingAssembly(). _
GetManifestResourceStream _
("StockQuoteService.stockdata.xml")
Dim srXMLReader As New StreamReader(sIn)
dsIn.ReadXml(srXMLReader)
srXMLReader.Close()
sIn.Close()
Return dsIn
End Function

Так как ресурс содержится внутри сборки, используется метод GetManifestResourceStream, загружающий именованный ресурс в Stream. Затем XML считывается из потока методом DataSet.ReadXml.

Клиент StockQuote, обращающийся к Web-сервису, выглядит следующим образом:

Рис. 15. Пример StockQuote, выполняемый на интеллектуальном устройстве

Как и при разработке настольного клиента Web-сервиса, необходимо получить ссылку на файл StockQuoteService.asmx:


http://machine/stockquoteservice/stockquoteservice.asmx

После получения ссылки на Web-сервис для выборки данных в DataSet достаточно написать всего три строки кода:


Private sq As New StockQuoteService.StockQuoter()
Private ds As DataSet
ds = sq.getQuoteDataSet()

Как и при работе с XML-файлом в Web-сервисе, в этом примере также используются встроенные графические файлы, считываемые методом GetManifestResourceStream.

Вызов API-функций

Программисты на Visual Basic традиционно использовали прямые обращения к DLL, входящим в состав Windows (а также к другим DLL), чтобы получить доступ к функциональности, не предоставляемой VB и его исполняющей средой. Первоначально Microsoft Win32 API применялся для работы с INI-файлами, затем - с реестром, а в дальнейшем Win32-функции стали широко использоваться для решения более сложных задач, таких как синхронизация процессов (например, WaitForMultipleObjects) или графические операции (BitBlit, StretchBlit и др.). Большинство этих функций теперь вызывается через классы базовой Framework Class Library. Без преувеличения можно сказать, что доступны тысячи таких классов. Но в некоторых приложениях все же приходится обращаться к Win32-функциям, не имеющим эквивалента в NET Framework (например, к GetPrivateProfileString). В управляемом коде для этого используется подмножество сервисов Interop, называемое PInvoke (сокращение от Platform Invocation). Имейте в виду, что при использовании PInvoke, разработчик не должен забывать о проблемах безопасности, возникающих при вызове неуправляемого кода, и учитывать их в своих программах.

И там, где .NET Compact Framework реализует лишь подмножество полной Framework Class Library, вы можете с помощью PInvoke получить доступ к отсутствующей функциональности, напрямую вызывая соответствующие функции Windows CE API. Так, в .NET Compact Framework-версии Windows Forms класс Cursor не реализован. К счастью, мы можем задействовать Win32-функции LoadCursor и ShowCursor для изменения вида курсора. В Windows CE эти функции находятся в библиотеке coredll.dll, и их объявления выглядят примерно так:


Declare Function LoadCursor Lib "coredll.dll" (ByVal zeroValue As Integer,
ByVal cursorID As Integer) As Integer
Declare Function SetCursor Lib "coredll.dll" (ByVal cursorHandle As
Integer) As Integer

Какой-либо инструмент, например API Text Viewer, входящий в состав Visual Basic 6.0, позволяет выполнить большую часть работы по определению вида соответствующего оператора Declare. Кроме того, вам может потребоваться доступ к Windows CE SDK, чтобы определить, как именно должны вызваться API-функции на платформе Windows CE. В частности, вам может понадобиться передать функциям соответствующие константы и даже структуры. Например, чтобы задать форму курсора как в Windows, нужно знать числовой идентификатор такого курсора:


Private hourGlassCursorID As Integer = 32514 ' &H7F02

Тогда задать нужную форму курсора довольно легко:


cursorHandle = LoadCursor(0, hourGlassCursorID)

Законченная программа, показывающая, как все это работает, есть в примере WaitCursor, поставляемом с .NET Compact Framework SDK. Обратите внимание, что курсор "песочные часы" на интеллектуальном устройстве выглядит совершенно по-другому.

Windows CE API

Конечно, есть и функциональность, доступная только в Windows CE; к ней тоже можно обращаться через PInvoke. Например, функция GetSystemPowerStatusEx имеется только в Windows CE API и предназначена для получения информации о состоянии дополнительной аккумуляторной батареи. В стандартном Win32 API такой функции нет. Объявление этой функции несколько сложнее, чем предыдущее объявление:


Declare Function GetSystemPowerStatusEx Lib "coredll" _
Alias "GetSystemPowerStatusEx" _
(<[In](), Out()> ByVal lpSystemPowerStatus As SYSTEM_POWER_STATUS_EX, _
ByVal fUpdate As Boolean) As Long

Первое, что бросается в глаза, - указание типов параметра в объявлении. Эти типы используются, чтобы задать, какие параметры являются входными и какие параметры будут возвращаться. Так как "In" является еще и ключевым словом Visual Basic, приходится заключать "In" в квадратные скобки. Типы "In" и "Out" определяются в InteropServices, следовательно, вы должны импортировать это пространство имен:


Imports System.Runtime.InteropServices

Далее вы заметите, что функция возвращает структуру SYSTEM_POWER_STATUS_EX. Чтобы работать с этой структурой, можно или воспользоваться ключевым словом Structure, или поместить ее определение в класс и соответственно упорядочить члены класса:


<StructLayout(LayoutKind.Sequential)> _
Public Class SYSTEM_POWER_STATUS_EX
Public ACLineStatus As Byte
Public BatteryFlag As Byte
Public BatteryLifePercent As Byte
Public Reserved1 As Byte
Public BatteryLifeTime As Int16
Public BatteryFullLifeTime As Int16
Public Reserved2 As Byte
Public BatteryBackupFlag As Byte
Public BackupBatteryLifeTime As Byte ' Ошибка в документации
Public Reserved3 As Byte
Public BackupBatteryLifePercent As Byte ' Ошибка в документации
Public BackupBatteryFullLifeTime As Byte
End Class

Обратите внимание, что два члена - BackupBatteryLifeTime и BackupBatteryLifePercent - на самом деле надо поменять местами, а в документации они идут в неправильном порядке.

Теперь вызов функции не представляет сложности:


Dim sps As New SYSTEM_POWER_STATUS_EX()
ret = GetSystemPowerStatusEx(sps, False)

Ниже показан внешний вид нашей программы-примера и вкладки Power из апплета System в Settings при выполнении на карманном компьютере iPAQ, к которому подключена внешняя батарея. Для устройства, работающего от батареи и успевшего частично ее разрядить, мы увидим следующую картину:

Рис. 16. GetPowerStatusEx и Power на устройстве с частично разряженными батареями

Важно заметить, что не обязательно будут использоваться все поля структуры. Например, iPAQ не передает для внешней батареи, подключаемой по кабелю, BatteryBackupFlag и бит Charging, так что и в нашем примере, и во встроенном модуле Power показывается не вся возможная информация.

Миграция и портирование

Как разработчику на Visual Basic, вам, возможно, потребуется переносить код существующих приложений на новые платформы, поддерживающие .NET Compact Framework. Может, вы будете портировать настольное приложение, использующее полную инфраструктуру, а может, и программы, написанные с применением старых инструментальных средств Microsoft для портативных устройств вроде Embedded Visual Basic 3.0.

Перенос приложений, разработанных с использованием полной версии .NET Framework, на SDE не особо сложен, но может потребовать много времени. Если в одном экземпляре Visual Studio .NET открыть настольную версию, а в другом - создать SDE-проект, окажется, что можно просто скопировать многие элементы управления из настольной версии и вставить их на SDE-форму. При этом многие свойства сохраняются. Конечно, с элементами управления, не поддерживаемыми .NET Compact Framework, так поступить не получится. Поэтому, если выполнение вашего приложения зависит от кода обработчиков событий этих элементов управления, эту часть приложения придется переработать. Также придется потратить некоторое время на "сжатие" элементов управления, чтобы они умещались на небольшом дисплее портативного устройства.

С другой стороны, код процедур переносится проще. Скорее всего окажется, что можно скопировать большую часть объявлений и обработчиков событий, находящихся в определении формы. Если каки-то объектов и их членов в .NET Compact Framework нет, можно сгенерировать по ним список записей TODO в Task List, а перед компиляцией приложения - отреагировать на эти записи.

Перенос приложения, разработанного на Embedded Visual Basic 3.0, потребует куда большей работы. В частности, старая версия Visual Basic больше напоминала VBScript, чем хорошо нам знакомая настольная версия Visual Basic. В ней поддерживался только тип данных Variant, не поддерживались UDT (User Defined Types) и не было большинства элементов управления, применяемых в настольной версии Visual Basic. К тому же, приложения, разрабатываемые с помощью инструментов старого поколения, создавались с применением компонентов, объектов доступа к данным и элементов управления, опирающихся на COM. В .NET Compact Framework всего этого нет. В конечном итоге может оказаться, что придется разрабатывать приложение заново.

Заключение

Цель этого документа - дать вам, как разработчику на Visual Basic, представление о том, что представляет собой программа для интеллектуального устройства, в которой используется SDE for Visual Studio .NET. Я рассказал о различиях между .NET Framework и .NET Compact Framework. Кроме того, я показал весь цикл разработки, отладки и развертывания приложения. Даже если у вас нет интеллектуального устройства, разработку можно вести с помощью полнофункционального программного эмулятора.

В то же время я описал далеко не все аспекты SDE-разработки. Есть и другие области, которые могут заинтересовать разработчиков на Visual Basic, уже использующих SDE, чтобы быстро создавать приложения для интеллектуальных устройств. В частности, у разработчика может возникнуть желание поэкспериментировать с написанием собственных элементов управления. Если вам нужна мощная функциональность для работы с базами данных, можно установить Microsoft SQL Server Windows CE Edition.

Примечание Экранные снимки для этого документа получены с помощью программного эмулятора и Remote Display Control. Если вы хотите сделать экранные снимки своего устройства, например для написания документации, то можете скачать Remote Display Control с Web-сайта Microsoft, посвященного мобильным устройствам.

Дополнительную информацию по Visual Studio .NET и .NET Compact Framework см. на Web-сайте Device Development, посвященном разработке для устройств с применением Visual Studio .NET.


Страница сайта http://test.interface.ru
Оригинал находится по адресу http://test.interface.ru/home.asp?artId=1789