Пару воскресных грабликов

October 26th, 2009 Begemot

Если вы используете проверку на запуск второго экземпляра и переходите на wxWidgets 3, то имейте ввиду что в wxConnection::OnExecute второй и третий параметр надо заменить на с wxChar * data, int size  на  const void * data, size_t size. Иначе не работает и выдает ошибку. Я заметил только спустя месяц использования\разработки двух своих  прог скомпиленных в тройке:)

И еще раньше битмап для картинки в меню можно было получить из главной иконки как wxIcon(wxT("main"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16), с тройкой под вистой\семеркой это код приводит к кривому отображению иконки, проблемы с прозрачностью, тоже стоит иметь ввиду.

Posted in Использование | Tags: ,
Comments Off on Пару воскресных грабликов


GetViewStart() vs GetScrollPos()

September 9th, 2009 Begemot

Столкнулся только что с багом – есть наследник от wxScrolledControl’a, контента мало – линеек прокрутки нет, то есть client size = virtual size. Крутим над ним колесиком мыши – прокручивая “вверх”, после этого GetViewStart() говорит нам что у нас позиция по вертикали минус сколько-то…, GetScrollPos() возвращает правильный ноль. Точно грешить на wxWidgets не могу – так как и приложение там сложное, у окна есть еще 1 или даже два базовых класса, которые возможно обрабатывают скролл мышкой (Скорее всего конечно нет, но совсем не удивлюсь если так:)), да и версия либы там весьма древняя. Но тем не менее следует иметь ввиду, что что возможно есть такая особенность, beware 🙂

Posted in Программирование | Tags:
Comments Off on GetViewStart() vs GetScrollPos()


wxListCtrl selection under MAC OS

August 14th, 2009 Begemot

Наткнулся на разное поведение wxListCtrl’a под виндой и маком. Надо при смене выделения в другом контроле устанавливать правильное выделение в wxListCtrl. Под виндой все просто

        int t = нужная строка;
    list->SetItemState(t, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
    list->EnsureVisible(t);

Под маком надо обязательно сбрасывать старое выделение и только потом ставить новое.

    int cursel = list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
    if (cursel != wxNOT_FOUND)
               list->SetItemState(cursel, !wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
 ......
      int t = нужная строка;
      list->SetItemState(t, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
      list->EnsureVisible(t);

Салянка из wxWidgets, wxCombobox и MAC OS

June 25th, 2009 Begemot

Сборная.

Кажется на маке с комбобоксами плохо, весьма плохо. Как то уж очень странно они выглядят (такое впечетление что родных нет, и вх эмулирует их сам, причем весьма посредственно)

Picture 6

Picture 8

Правда страшненько?

А вот это такое стремненькое белоей с каемочкой это стандартные color picker(!).

Причем тут комбобокс еще немного прилизанный, так как по умолчанию у него размер раза в 2 – 2.5 шире реально необходимо – почему ? хз. Пришлось руками уменьшать размер после создания

#ifdef __WXMAC__
{  // default combobox size under macos is too big
int w = 0, h = 0;
m_OverlayFontSize->GetSize(&w, &h);
m_OverlayFontSize->SetMinSize(wxSize(w / 2, h));
}
// combobox does not receive wxEVT_KILL_FOCUS event under MAC OS – http://trac.wxwidgets.org/ticket/9862
// so we use text update event, inseted of text_enter + kill_focus
#else

#ifdef __WXMAC__
{  // default combobox size under macos is too big
int w = 0, h = 0;
m_OverlayFontSize->GetSize(&w, &h);
m_OverlayFontSize->SetMinSize(wxSize(w / 2, h));
}

А еще они не получает события установки\потери фокуса. Пришлось жертвовать красотой работы и делать отдельную ветку логики под мак:(

Вот такой вот винегрет.


Scroll wxTreeCtrl – как скроллить ручками

May 21st, 2009 Begemot

Появилась задача, есть wxTreeCtrl с горизонтальной линейкой прокрутки, необходимо переодически скроллить ее в начало начал. В wxWidgets есть SetScrollPos(wxHORIZONTAL, 0); , но она делает только то что сдвигает скроллер у окна, но никак не его содержимое, в принципе об этом честно написано в документации

This function does not directly affect the contents of the window: it is up to the application to take note of scrollbar attributes and redraw contents accordingly.

Хотя есть люди которые утверждают, что у них работает именно так как хочется, а не так как в документации говорится:) Я даже обновился до 2.8.10, но не помогло. Зато помог самый просто способ,

::SendMessage((HWND)m_Tree->GetHWND(), WM_HSCROLL, SB_LEFT, 0);

Дойдем до альтернативных OS, будем думать.

А посмотрел код для скроллинга в самой бибилиотеке… толи что я чего-то не понимаю, то ли там хрень какая-то 🙁


delay loaded dll – не всегда полезна

April 30th, 2009 Begemot

Дополнение к посту про то как вылечить проблему с OpenCV и wxWidgets путем использования отложенной загрузки библиотек,  сегодня нарвался на странную багу падает код загрузки каскада, для face detection

m_nested_cascade = (CvHaarClassifierCascade*)cvLoad( (const char*)path_nested_cascade.ToUTF8(), 0, 0, 0);

Оказалось падает из за использования delay loaded для OpenCV библиотек – вот такие странные бывают ситуации, все вылечилось путем добавления в лист отложенной загрузки только /delayload:highgui110d.dll  – а вот остальные пришлось оттуда убрать.

Странными иногда способами удается найти причину ошибку

Posted in Программирование | Tags:
Comments Off on delay loaded dll – не всегда полезна


Иногда вещи не такие как кажутся, про SetFocus()

April 29th, 2009 Begemot

Как оказывается SetFocus(),  не всегда делает то что можно от него ожидать не читая для докумментацию:) Для wxWindow все ок:

This sets the window to receive keyboard input.

А вот для wxPanel ситуация совсем другая:

Overrides wxWindow::SetFocus. This method uses the (undocumented) mix-in class wxControlContainer which manages the focus and TAB logic for controls which usually have child controls. In practice, if you call this method and the control has at least one child window, the focus will be given to the child window.

А то что надо,  делает  SetFocusIgnoringChildren()

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


Грабли с временными переменными

December 15th, 2008 Begemot

Я уже как-то писал про "мистику" . Вот сегодня еще наткнулся на интересные грабли. Задача такая есть юникодная строка надо конвертить ее в UTF8, получить указатель на то что получилось и дальше обработать. Если писать так

void foo(const char * data)

{

   int len=strlen(data);

   //работаем с указателем data

}

wxString str(wxT("sometext"));

foo(str.ToUTF8().data());

Все работает отлично. Если попытатся это реализовать прямо в коде

wxString str(wxT("sometext"));

const char *  cp=str.ToUTF8().data();

int len=strlen(cp);

//работаем с указателем data

То начинает бардак. Оно не работает, cp указывает на мусор, но если поставить брейкпоинт на 3 строчку и посмотреть в watch окне значение str.ToUTF8(), то после этого все хорошо, и cp указывает куда надо и длина правильно считается. Мистика:)

Если я правильно понимаю то дело во временности буфера возвращяемого ToUTF8(). В первом случаем он видимо уничтожается после выхода из функции, поэтому в теле функции указательно возвразщаемый data() валиден. Во втором wxCharBuffer уничтожается сразу же (?) и указатель кривой, но дебагер его как-то возвращяет в жизни…. – кто силен в теории с++ подскажите в чем дело грамотно:)

Вообщем что бы обойти это приходится писать вот такой код:

wxString str(wxT("sometext"));

const wxCharBuffer tcb=str.ToUTF8();

const char *  cp=tcb.data();

int len=strlen(cp);

//работаем с указателем data

Это работает!