вторник, 25 декабря 2007 г.

Человеческая реализация Find&Replace для wxTextCtrl

Мда _человеческая_ реализация Find&Replace для wxTextCtrl требует мозгов, почти рабочий день и кучу тестирования. Интересно почему не добавят такую возможность к стандартному контролу?

понедельник, 24 декабря 2007 г.

Реализуем поиск в wxTextCtrl

Потребовалось мне значит добавить стандартные процедуры -  find, find next, replace. wxTextCtrl напрямую их не поддерживает, так что приходится писать руками. Полез искать примеры - самому писать немного муторно - надо много чего учитывать, а велосипед изобретать не хотелось - задача то по идее тривиальная. Как оказалось легче все таки самому:) Все велосипеды, что нашлись были или сильно самописыными (без использования стандартных диалогов) или вообще кривыми самокатами. Наиболее подходящим оказался вот этот код, сразу видно писал крутой программист и ему было не до тестрования.

И еще не могу понять почему все пытаются использовать Get\SetInsertionPoint когда помоему правильнее юзать только Get\SetSelection?

void FlashnoteFrame::OnFind()
{
     wxString find = m_findData.GetFindString();
    int flags = m_findData.GetFlags();
   

    bool forward(flags & wxFR_DOWN);
    long m_foundPos, StartFromBack, StartFromForward;
    m_Note->GetSelection(&StartFromBack, &StartFromForward);

    wxString string = forward ? m_Note->GetRange(StartFromForward, m_Note->GetLastPosition()) : m_Note->GetRange(0, StartFromBack);

    if (flags & wxFR_MATCHCASE)
            m_foundPos = forward ? string.find(find) : string.rfind(find);
    else
           m_foundPos = forward ? string.Lower().find(find.Lower()) : string.Lower().rfind(find.Lower());

    if (m_foundPos==-1) return;

    long startPos = forward ? StartFromForward + m_foundPos : m_foundPos;
    long endPos = startPos + find.length();

    m_Note->SetSelection(startPos, endPos);
}

воскресенье, 23 декабря 2007 г.

Копайте и выкопаете

Я уже писал про проблему навигации по дереву из другого контрола. Все таки я ее решил.

Задача - в окне есть дерево и другие контролы (у меня только редактор, но думаю что решение масшабируется),  необходимо дать юзеру возможность перемешаться по ветвям дерева не заставляя его сначала переключить туда фокус а потом вернутся назад.

Решение  - для навигации используется 6 клавиш (стрелки и Page Down\UP), для навигации из другого контрола используем АЛТ+соответствующая клавиша. Отслеживаем все нажатия клавиш и редиректим нужные нашему дереву.

Код:

Сразу предупреждаю что решение только для Винды. Как сделать для Макоса и Юникса еще не знаю, но очень хочу:)

1. В наше дерево добавляем метод

#ifdef __WIN32__

void

CMyFNTreeCtrl::EmulateKeyPress(const wxUint32 keycode)

{

    wxWindow * OldFocus=FindFocus();

    SetFocus();

     keybd_event((BYTE)keycode, 0, 0

/* key press */, 0);

     keybd_event((BYTE)keycode, 0, KEYEVENTF_KEYUP, 0);

      wxYield();

     OldFocus->SetFocus();

}

#endif // __WIN32__

Поскольку я все равно сабкласю дерево - то я добавил метод в него , но разумеется это можно сделать и прям в основном коде или просто процедурой - как угодно, главное код.

 

2. У меня есть процедура которая обрабатывает все нажатия на форме и в дочерних контролах. В ней пишем:

 

void FlashnoteFrame::OnChar( wxKeyEvent& event )
{
    wxChar key=event.GetKeyCode();
    wxObject * object=event.GetEventObject();

    if (event.GetModifiers() == wxMOD_ALT )
    {
        switch(key)
        {   
#ifdef __WIN32__ // Navigation through tree from any place with ALT
            case WXK_RIGHT:            
            case WXK_LEFT:
            case WXK_UP:
            case WXK_DOWN:
            case WXK_PAGEDOWN:
            case WXK_PAGEUP:
                if (object!=m_Tree)
                {
                    m_Tree->EmulateKeyPress(event);
                    return;
                }
#endif // __WIN32__
            default: ;
        }
    }
    event.Skip();
}

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

 

#ifdef __WIN32__
void CMyFNTextCtrl::OnKeyUp( wxKeyEvent& event )
{
    // Съдаем отпускание альта, иначе после навигации по дереву из редактора с альтом, первое нажатие буквенно цифровой клавиши
    // глючит или артефакт (квадратик) или другая буква или вообще ничего не происходит
    if (event.GetModifiers() == wxMOD_ALT ) return;

    event.Skip();       
}
#endif // __WIN32__

Разумеется это обработчик события отпускания клавиши для эдита.

суббота, 22 декабря 2007 г.

wxLaunchDefaultBrowser and FireFox

Обнаружил что wxLaunchDefaultBrowser работает криво. У меня FF стоит по умолчанию, если броузер уже запущен руками - то wxLaunchDefaultBrowser работает нормально. Но если FF закрыт, то облом - запускает фаерфокс, открывает новую вкладку - но пустую. Второй выбор этого же пунта меню для перехода на домашнюю страницу - опять открывает пустую вкладку и так пока не закроешь все вкладки и не откроешь броузер руками. Причем если в такую "открытую" вкладку руками вбить адрес - все равно ФФ не работает. жопа. Если дождусь письмо от sourceforge.net для активации аккаунта - запощю баг в трекер.


Updated: Как всегда если вам кажется что компьютер или система глючит - проверяйте себя. Оказалось проблема в моей системе - Firewall блокировал, дебаг версию - в результате чего был такой баг.

пятница, 21 декабря 2007 г.

Сохранение Layout'a

Научился нормально сохранять размеры\положение окна, тоже вам скажу не тривиальная задачка, хотя может я тормоз - но целый день с ней провозился, надо наверное запостить на днях алгоритм сюда. Но сейчас речь о другом - хочется еще и внутренний лайот сохранять. Использую AUI, лайот простой вот тут скриншотик можно глянуть. Вообщем варианта целых два : либо храним весь лайот в виде строки в файле использую AUI Save\LoadLauoyut или делаем все ручками - благо мне для этого дизайна всего 3 параметра надо хранить. Оба способа не фонтан.

Второй, в принципе хорош для данного приложение - но особо не масштабируется, а это софтина просто тренировка\проверка wx перед более сложной.

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

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

Shit happens

Эхх, клонирую свою MFC программу под wxWidgets. Необходимо находясь в эдит контроле иметь возможность навигации по соседнему дереву, там я  просто просто в PreTranslateMessage в эдите отлавливал alt+стрелки\Page Down\UP менял обьект у события и форвадил дереву для обработки. На wx сделать не получалось, спросил в wx-users at lists.wxwidgets.org, в ответ от Vadim Zeitlin  получил

There is no way to make this work with native controls (such as wxTreeCtrl
under MSW): they have no idea about wx events so sending them to those
controls will obviously never do anything. We thought a few times in the
past to provide a way to generate a native keyboard message from e.g.
wxKeyEvent but this has never been done. If you feel like trying to do it,
it would certainly be welcome. Otherwise you will have to handle the keys
yourself manually (i.e. checks for arrow up and select the appropriate item
and so on).

Настроение с утра испортил:)

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

Будем копать дальше, гда наша не пропадала:)

четверг, 20 декабря 2007 г.

wxWindowDestroyEvent

В обработчике wxWindowDestroyEvent окно уже какое-то полудохлое, такое ощушение что еще не совсем умерло, но уже попахивает. При IsMaximized() получаем AV. Так что MFCшники бросайте привычку делать что-то в OnDestroy, дружно юзаем деструктор.

среда, 19 декабря 2007 г.

wxWindowCreateEvent много раз

This event is sent just after the actual window associated with a wxWindow object has been created. Since it is derived from wxCommandEvent, the event propagates up the window hierarchy.

Обратите внимание на выделенное. Если хотите использовать этот событие для дополнительной инициализации диалога, по аналогии с OnInitDialog в MFC, то учтите: обработчик OnCreate для wxWindowCreateEvent вызывается много раз, первый раз после инициализации фрейма, а потом после создания каждого контрола. Так что или выберите другое место для дополнительной инициализации или предохраняйтесь:

if(event.GetEventObject()==this)

{

....

}

wxIconizeEvent и wxMaximizeEvent

Не радует меня система сообщений в wxWidgets, приложение получает wxIconizeEvent и wxMaximizeEvent уже постфактум. Ни запретить действие, ни выполнить свой код перед тем как окно будет свернуто\развернуто - нельзя.

Не смотря на то что в документации написано
An event being sent when the frame is maximized or restored.

и

An event being sent when the frame is iconized (minimized) or restored.

Приходит только после максимизации\минимизации. При возвращении к нормальным размерам - неприходит. Под маком вроде вообще не должно приходить, так что пытатся его использовать наверное не стоит - хоть мне приходится.

вторник, 18 декабря 2007 г.

понедельник, 17 декабря 2007 г.

О чем тут

Приветствую

Это мой микроблог о wxwidgets. Сейчас я пытаюсь перейти под на эту библиотеку и активно с ней разбираюсь, часто хочется крепко высказаться.... да не кому:) Так что буду постить сюда свои впечатления.

Сразу хочу предупредить - я плохой программист и извращенный тормоз:) Поэтому многих очевидных вещей не понимаю, а некоторых обычные - делаю крайне извращенным способом. Таким образом здесь вы найдете список моих жалоб и возмущений, немного кривых решений и советов. Ничего умного и полезного тут не будет, разве что в комментариях:) Пишу просто чтобы копить свой опыт и не забывать про грабли. также для того что бы более детально разобраться в вопросе, так что совсем не уверен что это стоит читать.

Опыт программирования у меня до этого - только MFC на нем написаны почти все мои программы. Пишу пока только под винду, но с прицелом...

Еще у меня есть мой блог шароваршика, а вообще живу я тут, так что велком.