Как reference counting чуть было не заставил поверить меня в мистику

January 15th, 2008 Begemot

Вчера вечером была написанна функция. Сегодня утром DialogBloks похерил мне весь файл, файл был восстановлен с архива, функция востановленна с аськи\почты. Но одно но - она не работала!, не работал не первый, ни второй вариант, всего было написанно три, третий работал но я проверил его только в конце. Функция простая как две копейки, берем строку, получаем ее внутренний буфер и отдаем винапи для изменения.

Обьявление функции:

void BegUtils::StrMakeLowerUniversal(wxString & data)

Первый

CharLower( data.GetWriteBuf(data.Length()) );

data.UngetWriteBuf();

и второй нерабочий вариант тела

wxStringBuffer buf(data, data.length()+1);

CharLower(buf);

Вчера работало - сегодня нет, классика :)

 

Оказалось все дело в контексте вызова - вот так работает

wxString data=_("NTnt НТнт öffnen вікно привет Donnée rápido test");

BegUtils::StrMakeLowerUniversal(data);

wxMessageBox(data);

А вот так уже нет

wxString data1=_("NTnt НТнт öffnen вікно привет Donnée rápido test");

wxString data(data1);

BegUtils::StrMakeLowerUniversal(data);

wxMessageBox(data);

Все оказалось прозаично, оптимизация строк, reference counting и разделямый внутренний буфер. Подробности обьяснять не буду - сам толком не понимаю, а ляпнуть что-нибудь и выглядеть дураком не хочется:) Зато дам вариант функции который работает и который я юзаю.

 

void

BegUtils::StrMakeLowerUniversal(wxString & data)

{

  #ifdef __WIN32__

      int len=data.length()+1;

      wxChar * buf = new wxChar[len];

      wxStrcpy(buf, data.c_str());

      CharLower(buf);

      data=buf;

      delete [] buf;

#else

      data.MakeLower();

#endif

}

 

Кстати это функция преобразования строки к нижнему регистру, которая работает со сторой на любом языке, а не только с латинскими сиволами как стандартная MakeLower. Но только под MSW.


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


Юмористы

January 14th, 2008 Begemot

Авторы не лишены чуства юмора, из доков

    wxString theAnswer;
    GetMeaningOfLifeAsString(wxStringBuffer(theAnswer, 1024));
    if ( theAnswer != "42" )
    {
        wxLogError("Something is very wrong!");
    }

хотя было бы наверное лучше если бы они wxCharBuffer в документации описали.


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


Почти герой:)

January 13th, 2008 Begemot

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


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


wxRichTextCtrl не фонтан

January 12th, 2008 Begemot

Как я и боялся wxRichTextCtrl не всегда адекватен. За час тестов я нашел кучу “странного поведения”, и раза 4 он херил мне стиль всего документа. В результате несложных манипуляций- то весь текст стает жирным, то центрированным, самый тяжелый случай - при ресайзе окна весь текст превратился в сплошной список, каждый пункт которого начинался с ‘1′ и всеб было bold & italik. Ну и как я могу дать подобное юзерам? Ответил Julian Smart’y на его предложение юзать wxRichTextCtrl, описанием багов и методикой воспроизведения одной из ситуаций, посмотрим что ответит - как никак он автор.

Уточню, речь шла о использовании wxRichTextCtrl  как РТФ редактора. Мысль о том, что можно попробывать эмулировать им простой эдит с расширенной функциональностью все еще не покидает меня - буду пробывать.


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


Мягкая часть тела с Edit’ами

January 10th, 2008 Begemot

Просто какая-то отвратительная ситуация с эдитами в мире, причем не  в wxWidgets а в целом. Не могу подобрать идеальный Edit Control для своей задачи, хотя требования у меня довольно простые, без особых наворотов.

Чего хочется:

  1. Функциональность обычного простого эдита (notepad)
  2. _Обязательно_ множественное undo\redo.
  3. _Желательно_ подсветка и клик на ссылках.
  4. Корректная работа с точки зрения пользователя.
  5. Хотелось бы иметь возможность в будущем (опционально) перейти на RTF если стукнет в голову.

Собственно если говорить про MSW и wxWidgets, есть 4 варианта:

  1. Обычный edit control (CEdit, wxTextCtrl, Notepad) - (2) обязательное условие не выполняется.
  2. RTF контрол (CRichTextCtrl, wxTextCtrl+wxTE_RICH, WordPad) - все пункты кроме (4) выполняются. На скорость работы и совместимость версией под линукс можно забить пока, но (4) условие не выполняется. Для пользователя контрол должен выглядеть простым (не ртф) - соответвенно вставять и копировать _только_ plain text, этого добиться не получается.
  3. wxWidgets версию RTF контрола wxRichTextCtrl (generic, ground-up implementation of a text control capable of showing multiple styles and images.) - Как-то она вообще не внушает доверия в плане работы, к тому же пункт (5) вызывает определенные проблемы.
  4. Scintilla - там что-то непонятное с RTF, с одной стороны он умеет с ним работать - сохранять файлы как RTF, копировать в буфер - но полноценной работы я не нашел.

Наверное забью я в итоге на пользователей (и на себя самого, потому что от отсутствия ундо я сам страдаю) и возьму для начала обычный edit.


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


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

December 25th, 2007 Begemot

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


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.

Posted in Uncategorized | Tags:
No Comments, Be First! »


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

December 24th, 2007 Begemot

Потребовалось мне значит добавить стандартные процедуры -  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);
}


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


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

December 23rd, 2007 Begemot

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

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

Решение  - для навигации используется 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__

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


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


wxLaunchDefaultBrowser and FireFox

December 22nd, 2007 Begemot

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

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


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.


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

December 21st, 2007 Begemot

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

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

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

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


Если пост полезен для вас вы можете подписаться на RSS или мы можем доставлять вам новые посты прямо в ваш почтовый ящик.




Page 6 of 7«1234567»