Aug
16

Странности с 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

Mar
13

Как создать фигурное окошко в Windows Mobile

И вот еще один небольшой пример, демонстрирующий создание окна непрямоугольной формы в Windows Mobile с библиотекой wxWinCE.

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

Ну а затем нужно выполнить вот такой финт ушами:

  • Создать изображение (черно-белое)
  • Создать для него контекст устройства
  • Нарисовать что-либо (черные пикселы станут прозрачными, белые – видимыми)
  • Создать регион из изображения (wxRegion)
  • Указать форме регион для отображения
void wxMobileTransparencyMainFrame::ChangeShape()
{
        int width(0), height(0);
        // Получаем размер окна
        GetClientSize(&width, &height);
        // Создаем изображение
        wxBitmap bitmap(width, height);
        // Создаем Device Context для изображения
        wxMemoryDC mdc(bitmap);
        // Заполняем черным цветом
        mdc.SetBackground(*wxBLACK_BRUSH);
        mdc.Clear();
        // Устанавливаем кисть белого цвета
        mdc.SetPen(*wxWHITE_PEN);
        wxPoint center(width/2, height/2);
        int radius = wxMin(width, height)/2;
        // Рисуем круг в центре
        mdc.DrawCircle(center, radius);
        // Устанавливаем кисть черного цвета
        mdc.SetPen(*wxBLACK_PEN);
        mdc.SetBrush(*wxBLACK_BRUSH);
        // Рисуем
        mdc.DrawCircle(center.x - radius/3, center.y-radius/4, radius/6);
        mdc.DrawCircle(center.x + radius/3, center.y-radius/4, radius/6);
        mdc.DrawEllipticArc(center.x-radius/3, center.y+radius/4, 
                2 * radius / 3, radius/2, 
                180, 360);
        // Освобождаем Device Context
        mdc.SelectObject(wxNullBitmap);
        // Создаем новый регион
        m_Region = new wxRegion(bitmap, *wxBLACK);
#if defined(__WXWINCE__)
        // Для wxWinCE метод SetRegion() ничего не делает, просто возвращает false.
        // Поэтому приходится устанавливать регион вручную
        HRGN hRgn = (HRGN)m_Region->GetHRGN();
        ::SetWindowRgn((HWND)GetHWND(), hRgn, FALSE);
#else
        int offset = GetSize().GetHeight()-GetClientSize().GetHeight();
        m_Region->Offset(0, offset);
        // Устанавливаем регион
        SetShape(*m_Region);
#endif
}

Создаем окно непрямоугольной формы в Windows Mobile
Скачать исходник: Создаем окно непрямоугольной формы в Windows Mobile

Mar
11

Как сменить тему в Windows Mobile программно

Как сменить тему в Windows Mobile программноЗадался тут вопросом о программной смене темы в Windows Mobile. Оказывается это не так просто, как может показаться. Информация с MSDN’овских форумов и из самой MSDN мягко говоря не соответствует действительности. В Интернете полно топиков с подобными вопросами, но вменяемый результат выудить оттуда тоже почти нереально.

После нескольких часов мучений получил вроде вполне рабочий результат. А результатом, собственно, стал небольшой класс для установки и получения темы для Windows Mobile.

Но перед тем, как мы перейдем к рассмотрению примера, давайте, все же, определимся с последовательностью действий:

  • Имя файла текущей темы находится в реестре по адресу “HKEY_CURRENT_USER\Software\Microsoft\Today\Skin”
  • Первым шагом для смены темы в Windows Mobile является запуск утилиты \Windows\wcrload.exe c параметрами /noui /nouninstall /delete 0 “путь_к_файлу_темы.tsk” (кавычки нужны для того, чтобы правильно обрабатывались пути с пробелами. Это важно!).
  • Затем надо удалить в реестре значение по адресу “HKEY_LOCAL_MACHINE\Software\Microsoft\Color\BaseHue” иначе после применения темы изменится только фоновая картинка в Today, а цветовая схема останется прежней (тоже долго искал почему не применяется тема полностью, это тоже важный момент).
  • Затем надо удалить значение в реестре по адресу “HKEY_CURRENT_USER\Software\Microsoft\Today\UseStartImage”.
  • После этого нужно прописать прописать путь к файлу темы в реестре по адресу “HKEY_CURRENT_USER\Software\Microsoft\Today\Skin”.
  • И последнее, что нужно сделать, это разослать всем окнам сообщение об изменении настроек системы с помощью ::PostMessage(HWND_BROADCAST, WM_WININICHANGE, 0xF2, 0)

А теперь пример:

#ifndef _MOBILE_THEME_SWITCH_H
#define _MOBILE_THEME_SWITCH_H

#include 
#include 
#include 

class MobileThemeSwitch
{
public:
        static wxString GetTheme()
        {
                wxString result;
                do 
                {
                        wxRegKey key(wxRegKey::HKCU, wxT("Software\\Microsoft\\Today"));
                        if(!key.Exists()) break;
                        if(!key.Open(wxRegKey::Read)) break;
                        const wxString skinValueName(wxT("Skin"));
                        if(!key.HasValue(skinValueName)) break;
                        if(!key.QueryValue(skinValueName, result)) break;
                } 
                while (false);
                if(result.IsEmpty()) result = _("default");
                return result;
        }
        static bool SetTheme(const wxString & value)
        {
                wxRegKey  * key(NULL);
                do 
                {
                        wxString wceLoadFileName = wxT("\\Windows\\wceload.exe");
                        if(!wxFileExists(wceLoadFileName)) 
                        {
                                wxLogDebug(_("'wceload.exe' does not exist"));
                                break;
                        }
                        wxString commandLine = wxString::Format(
                                wxT("%s /noui /nouninstall /delete 0 \"%s\""),
                                wceLoadFileName.GetData(),
                                value.GetData());
                        long execResult = wxExecute(commandLine, wxEXEC_SYNC);
                        if(execResult != 0)
                        {
                                wxLogDebug(_("'wceload.exe' returned error (%l)"), execResult);
                                break;
                        }
                        key = new wxRegKey(wxRegKey::HKLM, wxT("Software\\Microsoft\\Color"));
                        if(!key->Exists())
                        {
                                wxLogDebug(_("'Software\\Microsoft\\Color' registry key does not exist"));
                                break;
                        }
                        if(!key->Open(wxRegKey::Write))
                        {
                                wxLogDebug(_("Unable to open registry key 'Software\\Microsoft\\Color'"));
                                break;
                        }
                        const wxString baseHueValueName(wxT("BaseHue"));
                        if(key->HasValue(baseHueValueName))
                        {
                                key->DeleteValue(baseHueValueName);
                        }
                        key->Close();
                        wxDELETE(key);
                        key = new wxRegKey(wxRegKey::HKCU, wxT("Software\\Microsoft\\Today"));
                        if(!key->Exists())
                        {
                                wxLogDebug(_("'Software\\Microsoft\\Today' registry key does not exist"));
                                break;
                        }
                        if(!key->Open(wxRegKey::Write))
                        {
                                wxLogDebug(_("Unable to open registry key 'Software\\Microsoft\\Today'"));
                                break;
                        }
                        const wxString useStartImageValueName(wxT("UseStartImage"));
                        if(key->HasValue(useStartImageValueName))
                        {
                                key->DeleteValue(useStartImageValueName);
                        }
                        const wxString skinValueName(wxT("Skin"));
                        if(!key->SetValue(skinValueName, value))
                        {
                                wxLogDebug(_("Unable to change value 'Skin' in 'Software\\Microsoft\\Today'"));
                                break;
                        }
                        key->Close();
                        wxDELETE(key);
                        ::PostMessage(HWND_BROADCAST, WM_WININICHANGE, 0xF2, 0);
                        return true;
                } 
                while (false);
                wxDELETE(key);
                return false;
        }
};

#endif

Скачать исходный код примера + исполняемый файл для Windows Mobile 6.0.

Mar
09

Учимся скачивать файлы программно в Windows Mobile

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

Для того чтобы скачать файл в C++ приложении с wxWinCE надо совсем немного кода. В простейшем случае для реализации однопоточной загрузки файла мы можем использовать класс wxURL, скормив ему адрес загружаемого ресурса.
читать далее…

Feb
14

Видео-урок: Работа с SQLite в Windows Mobile

Новый скринкаст о том как собрать минимальное приложение для Windows Mobile, работающее с базой данных SQLite.

Из видео можно узнать:

  • Как создать минимальное приложение для Windows Mobile с wxWinCE.
  • Собрать библиотеку SQLite3 для Windows Mobile 5.
  • Собрать библиотеку-обертку wxSQLite3 для работы с базами данных SQLite.
  • Создать базу данных SQLite.
  • Создать таблицы в базе данных SQLite.
  • Сделать выборку данных из таблицы.
  • Обработать исключения, возникающие при ошибках доступа к базам SQLite.
Feb
08

Работаем с журналом звонков в Windows Mobile

В этот раз я расскажу о том, как работать с журналом звонков на С++ в Windows Mobile.

Для доступа к журналу звонков Windows Mobile имеет такую вещь, как Phone API.

Непосредственно для наших целей необходима всего небольшая часть функций, доступных в рамках Phone API, а именно:

  • PhoneOpenCallLog – открывает журнал звонков для чтения и возвращает хэндл, использующийся впоследствии для доступа к записям журнала.
  • PhoneGetCallLogEntry - получает данные о записи журнала звонков и заполняет структуру CALLLOGENTRY этими данными
  • PhoneCloseCallLog - закрывает хэндл журнала звонков.

читать далее…

Dec
15

Пишем мобильную игру на wxWidgets

Введение

В этот раз речь пойдет о разработке мобильных приложений, а если быть точным, то мобильных игр, с библиотекой wxWidgets (порт wxWinCE).
О том, как собрать wxWidgets для разработки приложений для Windows Mobile я уже писал ранее здесь. Как создать простейшее приложение с wxWinCE, рассказано в этой статье.
Здесь и далее по тексту подразумевается, что читатель уже может самостоятельно создать простейшее приложение с wxWinCE, а также настроить параметры сборки для PocketPC и Smartphone.

Каркас приложения

Так случилось, что я решил попробовать себя в написании мобильных игр. После небольшого исследования пришел к выводу, что в простейшем случае для этой задачи вполне может подойти архитектура Документ/Представление (Document/View).
читать далее…

Dec
08

Отображаем анимированный 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 этого функционала нет).

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

Nov
25

Настраиваем средства разработки для Windows Mobile (C++/wxWinCE) в Linux

Благодаря стараниям Станислава Блинова у нас появилась возможность разрабатывать ПО для Windows Mobile в Linux, используя компилятор cegcc и библиотеку wxWidgets. О том как настроить средства разработки для Windows Mobile под Linux рассказано в ниже следующей статье:

Захотелось мне тут выяснить, насколько “умерла” бесплатная разработка софта под WinCE. Великий Гугель вывел меня на штуку под названием cegcc – кросс-компилятор, позволяющий собирать WinCE приложения под Линуксом. После возвращения из осадка, в который я выпал, узрев данный инструмент, я решил его проверить на практике.

читать далее…

Oct
31

Пишем мобильный клиент для Google Translate на C++

В этот раз я хочу рассказать о том как работать с еще одним online-сервисом, а именно с сервисом online-переводов Google Translate.

Для работы с этим сервисом у Google есть свой программный интерфейс, а именно AJAX Language API for Translation And Detection. Именно его мы и будем использовать.

Для того чтобы осуществить online-перевод текста необходимо сделать http-запрос к сервису переводов, доступному по адресу:


http://ajax.googleapis.com/ajax/services/language/translate

Параметры, которые необходимо передать сервису:

  • v=1.0 – версия сервиса
  • q= – URL-encoded текст для перевода.
  • langpair=%7C – пара названий языков: исходного и результирующего

читать далее…

Дипломы, курсовые, рефераты: купить диплом о высшем образовании. ; online cialis

top