Иногда кажется, что изучать что-то новое и потом это новое использовать в работе очень сложно. Но довольно часто новые, ранее незнакомые инструменты могут быть очень полезными.

Сегодня мы поговорим о том, как собрать библиотеку wxWidgets, а точнее ее порт wxWinCE, который используется для разработки приложений, работающих под управлением Windows Mobile и значительно упрощает процесс разработки GUI-приложений для карманных компьютеров и смартфонов под упралвением этой ОС. Для того чтобы собрать wxWinCE мы будем использовать Visual Studio 2008.

Итак, для начала нам необходимо загрузить исходный код wxWidgets с официального сайта. Сделать это можно здесь. На странице доступны различные версии дистрибутива wxWidgets, а также пакеты для различных ОС. На данный момент последней версией является 2.8.8. Лучше всего будет загрузить пакет wxALL (пакет, содержащий исходный код wxWidgets для всех поддерживаемых платформ и операционных систем).

После того как исходный код библиотеки загружен, распаковываем его и переходим в папку wxWidgets-2.8.8/build/wince. Здесь находятся файлы проектов для wxWinCE.

Открываем файл проекта wx_mono.vcp. При открытии Visual Studio предложит преобразовать файл проекта к новому формату.

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

В этом посте для примера будет использована платформа Pocket PC 2003 и Windows Mobile 6 Professional. Почему выбраны именно эти платформы? Pocket PC 2003 выбрана как самая старая. Приложения, собранные под эту платформу будут также работать под управлением более поздних версий Windows Mobile. Windows Mobile 6 Professional выбрана как самая новая.

Итак, открываем окно свойств проекта и переходим в раздел Configuration Properties -> General. В этом разделе в свойстве Output Directory устанавливаем значения:

  • Для платформы Pocket PC 2003 – “..\..\lib\evc_armv4_lib”
  • Для платформы Windows Mobile 6 Professional – “..\..\lib\evc_armv4t_lib”

Сделать это нужно для обеих конфигураций, Debug и Release.

Переходим в раздел Librarian -> General и в свойстве Output File устанавливаем значение $(OutDir)\$(ProjectName).lib для Release конфигурации и $(OutDir)\$(ProjectName)d.lib для Debug конфигурации.

Для платформы Windows Mobile 6 Professional переходим в раздел C/C++ -> Advanced и в свойстве Compile for Architecture устанавливаем значение ARM4T (QRarch4t).

Идем в раздел C/C++ -> Code Generation и в свойстве Enable C++ Exceptions устанавливаем значение No. Необходимо помнить, что сделать это нужно для обеих конфигураций и для обеих платформ.

Пытаемся собрать библиотеку, жмем Build. И что мы видим? Ошибки!!! Первое с чем прийдется столкнуться, это ошибка вида

—— Build started: Project: wx_mono, Configuration: Debug Pocket PC 2003 (ARMV4) ——
Creating ..\..\lib\evc_armv4_lib\winced\wx\msw\rcdefs.h
“clarm.exe” не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
Project : error PRJ0019: A tool returned an error code from “Creating ..\..\lib\evc_armv4_lib\winced\wx\msw\rcdefs.h”
Build log was saved at “file://e:\wxWidgets-2.8.8\build\wince\Pocket PC 2003 (ARMV4)\Debug\BuildLog.htm”
wx_mono – 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Лечится она просто, необходимо повторно запустить сборку проекта.

Смотрим дальше, ошибка вида

e:\wxWidgets-2.8.8\include\wx/aui/floatpane.h(33) : error C2504: ‘wxMiniFrame’ : base class undefined
..\..\src\aui\framemanager.cpp(2453) : error C2039: ‘SetTransparent’ : is not a member of ‘wxAuiFloatingFrame’
e:\wxWidgets-2.8.8\include\wx/aui/floatpane.h(32) : see declaration of ‘wxAuiFloatingFrame’

Лечится она тоже довольно просто, открываем файл floatpane.h и меняем декларацию макроса wxAuiFloatingFrameBaseClass чтобы оно выглядел так:

#if defined( __WXMSW__ ) || defined( __WXMAC__ ) ||  defined( __WXGTK__ )
#include "wx/minifram.h"
#define wxAuiFloatingFrameBaseClass wxFrame
#else
#define wxAuiFloatingFrameBaseClass wxFrame
#endif

Следующее, ошибка вида

..\..\src\msw\window.cpp(5965) : error C3861: ‘VkKeyScan’: identifier not found

лечится добавлением функции-заглушки


unsigned int VkKeyScan(int)
{
return 0;
}

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

Ну вот, теперь можно собирать библиотеку. Собираем Debug и Release конфигурацию для обеих платформ.

Дальше, для удобства использования wxWinCE в проектах, нам необходимо добавить переменную окружения WXWIN и присвоить ей в качестве значения путь папке с исходным кодом wxWidgets.

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

Previous ArticleNext Article
Технический директор IT-Dimension, компании-разработчика кросс-платформенного программного обеспечения

This post has 40 Comments

40
  1. Радуешь, спасибо:)

    А почему полная студия, а не экспресс? для большинства было бы куда более политически правильным:)

  2. А Windows Mobile SDK не поддерживает работу с Express-студией, оно даже не ставится если у тебя установлена только Express. Такова политика Microsoft.

  3. щет. это значит что бесплатно и лицензионно чисто не получится писать под винмобайл или я ошибаюсь?

  4. Ну.. где-то так.. без студии оно ставиться не хочет.

  5. T-Rex:
    У меня пара вопросов. Наткнулся собственно на этот блог, так как появилась необходимость писать под WM (и при этом, чтоб под 6й работало).
    Скачал собственно wxWidgets 2.8.9 (.8.8 небыло, погуглил – нашел несколько мертвых ссылок на китайском)
    В самом начале настройки появились проблемы – платформы Windows Mobile 6 Professional вообще нет. Пока плюнул, полез в настройки – полное отсутствие раздела Configuration Properties > General, соответственно ничего не компилит.
    Не подскажете советом? Мыло я указал.

  6. Для того чтобы полатформа Windows Mobile 6 появилась в списке доступных в Visual Studio надо скачать Windows Mobile 6 SDK и установить его.
    ЗЫ: Там кстати для 2.8.9 немного по-другому надо сорцы править при сборке. Если возникнут проблемы, пиши сюда.

  7. [quote]Там кстати для 2.8.9 немного по-другому надо сорцы править при сборке. Если возникнут проблемы, пиши сюда.[/quote]

    Собсна вот 🙂

    1>..\..\src\aui\auibar.cpp(745) : error C2039: ‘SetBitmap’ : is not a member of ‘wxMenuItem’
    1> ..\..\include\wx/msw/menuitem.h(27) : see declaration of ‘wxMenuItem’

  8. обернуть в #if defined(__WXWINCE__) && (CEVER < 0x500)

    #endif
    вроде для более старших версий чем 2003 есть иконка. если вдруг нету (я не помню), то просто оставить про __WXWINCE__

  9. Спасибо, помогло. На пути к wxWidget под ВыньМоб встал следующий эррор:
    1>..\..\src\msw\filedlg.cpp(441) : error C2065: ‘FNERR_INVALIDFILENAME’ : undeclared identifier

    Пофиксил вот так:
    #define FNERR_INVALIDFILENAME 0x3002
    Правильно?

  10. я просто #ifdef’ами заэкранировал. но если с редефайном пашет то гут.

  11. Статья очень полезная, давно искал такое.

    вопрос по поводу ошибки
    1>..\..\src\aui\auibar.cpp(745) : error C2039: ‘SetBitmap’ : is not a member of ‘wxMenuItem’

    Что именно там надо обернуть в #if … #endif ?

  12. т.к. при любой попытке обернуть код выводит такой еррор:

    Error 1 fatal error C1012: unmatched parenthesis : missing ‘)’ c:\wxWidgets-2.8.9\src\aui\auibar.cpp 743

  13. В auibar.cpp в методе ShowDropDown

    wxMenuItem* m = new wxMenuItem(&menuPopup, item.GetId(), text, item.GetShortHelp());
    #ifndef __WXWINCE__
    m->SetBitmap(item.GetBitmap());
    #endif

  14. хм… пересоберу потом, т.к. недождавшись ответа просто закоментировал
    //m->SetBitmap(item.GetBitmap());
    и компилятор съел(прога тоже сумела запуститься кстати)

  15. хммм… а эта инструкция только для 2.8.8?

    А то 2.8.10 примерно по инструкции вроде собралась, но глючит (сообщения в wm5,wm6 не доставляются в функции-обработчики, ни через Connect, ни через карты сообщений а в эмуляторе PPC2003 всё нормально)

  16. 2.8.9 нормально собралась. 2.8.10 не пробовал, пока не было необходимости.
    А какие у вас евенты не работают? UpdateUI вроде вобще на WM не отрабатывает

  17. А все евенты не доходят. Может, я называю это евентами неправильно?

    Вот скопировал минимальное приложение, там в меню файл пункт exit. выбираю его, а он не работает. даже отладчиком проверил:внутрь OnExit не заходит.Даже если я карту евентов макросами делаю, а не коннектом – один хрен. Так под wm5,а под PPC2003 всё вроде работает.

    А кстати собрался 2.8.10 прекрасно, исходники не требовалось править вообще. Вот только работает фигово:)

  18. етитская сила! собрал 2.8.9, всё работает как надо!!!

    Собрал 2.8.10 на 100%-свежей машине – тот же баг под wm5.

    Вывод: мерзкий глюк!!! А так как такой мерзкий глюк до сих пор никто не поймал и интернет молчит, значит wxWinCE 2.8.10 мало кто использует для программирования winCE. Жаль:(

    Интересно кстати, есть ли wx под айфон и под нокия s60.

  19. Для iPhone пока нет, но из того что вычитал в wxBlog’е, работа над этим ведется, а точне работа над портом wxOSX, который долен собираться и под десктоп и под iPhone.

  20. По-моему на прошлом GSoC был в кандидатах такой проект, вроде никто не взялся. Вобще все порты можно посмотреть в репозитории SVN. Там на офф. сайте есть адрес репозитория.

  21. Собрал свое приложение для WM 2003 с WX 2.8.10. Нажатие кнопок в тулбаре не вызывает событий, те же обработчики “привязанные” к опциям меню работают ОК 🙁

  22. Ммм? Какие это “те же самые”?
    Для меню надо прописывать макрос
    EVT_MENU() а для кнопки EVT_BUTTON()

  23. Для кнопок в тулбаре и меню события одинаковые – EVT_MENU.

    Да баг это, баг в 2.8.10. Понаменяли в frame.cpp и не проверили для wince.

  24. Вот тут описано лекарство:

    групс точка гугл точка ком/group/wx-dev/browse_thread/thread/dbaabd7260e51faa

    Там про четыре строчки. Сам бы не додумался. Работает.

  25. +1, сегодня пересобрал свое добро все под 2.8.10, очень огорчился что менюшки не работают. Даже странно как-то.
    За лекарство спасибо, посмотрю тоже.

  26. hello t-rex
    what values should be in General-> Output Directory for WinCE 5.0 and Mobile 5.0 ?
    and I´ve got this error after fix floatpane.h and window.cpp: fatal error LNK1104: cannot open file ‘$ (OutDir) \ $ (ProjectName) d.lib’ mae for PocketPC2003, do you know where I´m wrong?

  27. Привет. Делал все как ты описал в статье, только у меня wxWidgets-2.9.0. Выдает следующие ошибки:
    Warning 1 warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc

    Error 2 error C3861: ‘strnlen’: identifier not found

    Подскажи как быть

  28. Доброго времени суток. У меня вопрос на счет менюшек для версии 2.8.10. Они видимо как у многих не работают. Читал про лекарство описанное выше, добавил четыре строчки в файле frame.cpp, но менюшки так и не ожили. Кто нибудь разобрался с этой проблемой? Как оживить меню?

  29. Спасибо за совет, я сделал как там написано, и не помогло. Кто нибудь пробовал добавлять четыре строчки? Заработало? Лично у меня нет.

  30. а тупо на 2.8.9 перейти не? она стабильная и надёжная.

  31. “четыре строчки” работают! Я же писал выше. Попробуйте еще повнимательнее. Это “запарка обыкновенная” 🙂
    То есть в состоянии неуверенности из-за наложения нескольких багов можно подумать что не работает нечто вполне работоспособное 🙂
    Потом разберешься спокойно и все станет OK. 🙂

  32. Что то я не догоняю, скачал wxWidgets 2.9.0, распаковал, открыл папку /build/wince, а там нет проектов! Только папка missing. Ладно, скачал транк из репозитория – тоже нету проектов? Что делать, куда бечь?

  33. Теоретически, там есть CMakeLists.txt и из него с помощью CMake можно погенерить все проекты для WM. Но я непробовал. Но оно должно работать.

  34. Собрал библиотеку, сделал тестовое приложение с одной формой на wxFormBuilder, но русский язык не хочет отображать, хотя в свойствах проекта программы и библиотеки включен юникод, и при компиляции библиотеки в файле setup.h значение директивы wxUSE_UNICODE поменял на 1 (0 тоже пробовал).

    Есть ли какие-то идеи, как с этим справиться?

  35. Давайте кусок кода с русскими буквами.
    Проверяли кодировку файлов в исходниках?

Leave a Reply

Your email address will not be published. Required fields are marked *

С.

Странности с dropdown-окном в wxComboBox/wxChoice в Windows Mobile

После долгого перерыва решил снова заняться разработкой для Windows Mobile – доработать программу-переводчик, использующую Google Translate. В программе используется wxChoice cо списком языков. Так как поддерживаемых языков довольно много, то общая высота списка wxChoice получается много больше чем высота экрана КПК. В результате получаем что-то подобное:

Ошибка в вычислении размера dropdown-окна в wxComboBox/wxChoice

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

Перепробовав разные комбинации SetSize()/SetInitialSize()/SetMinSize()/SetMaxSize() нашел вот какое решение:

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

bool wxGoogleTranslateClientApp::OnInit()
{    
	wxGoogleTranslateClientMainFrame* mainWindow = new wxGoogleTranslateClientMainFrame( NULL );
	mainWindow->Show(true);
	// Очень плохое решение, но только оно и работает
	mainWindow->m_SourceLanguageChoice->SetClientSize(
		mainWindow->m_SourceLanguageChoice->GetClientSize().GetWidth(), 120);
	mainWindow->m_ResultLanguageChoice->SetClientSize(
		mainWindow->m_ResultLanguageChoice->GetClientSize().GetWidth(), 120);
    return true;
}

В результате получаем вот такой результат:
wxComboBox/wxChoice Dropdown Size Problem Fixed

О.

Отображаем анимированный GIF под Windows Mobile

Как-то печально обстоят дела с отображением анимации на устройствах под управлением Windows Mobile. Искал решение на .NET Compact Framework, нашел на Stack Overflow. Там предлагают писать собственный контрол, который будет делить изображение на кадры и отображать их с заданной периодичностью. Там в ответах ссылка на статью в MSDN. Собственно, везде это решение рекомендуют, но мне оно как-то не очень понравилось ввиду того, что позволяет отображать только специально подготовленное изображение, что во многих случаях очень неудобно.

А вот для тех, кто пишет ПО для Windows Mobile на C++ с wxWinCE эта проблема решается намного проще, с помощью wxAnimationCtrl. Вобще никаких лишних телодвижений делать не надо:

void wxAnimateMobileMainFrame::OnOPENClick( wxCommandEvent& event )
{
	wxFileDialog * dlg = new wxFileDialog(this, wxFileSelectorPromptStr, wxEmptyString,
		wxEmptyString, _("GIF Files (*.gif)|*.gif"));
	if(dlg->ShowModal() == wxID_OK)
	{
		m_AnimationCtrl->LoadFile(dlg->GetPath());
		m_AnimationCtrl->Play();
	}
	dlg->Destroy();
}

Из полезных возможностей:

  • Загрузка GIF-изображений с любым количеством кадров
  • Поддержка различных интервалов задержки для различных кадров
  • Циклическое воспроизведение (прописывается в самом GIF-файле)

Оказывается, все-таки, для некоторых задач C++ пользовать удобнее (хотя все равно для меня остается загадкой почему в .NET CF этого функционала нет).

Исходный код примера можно загрузить здесь.