В связи с тем что мне надоел блоггер как платформа, может он неудобный, а может я просто не умею его готовить, но вообщем я рещил перебратся на нормальный движок.
Вообщем встречайте новый адрес блога про программирование с wxWidgets
Мысли новичка в процессе попытки использования: открытия, мысли, удивления, ссылки, решения, советы, куски кода.
В связи с тем что мне надоел блоггер как платформа, может он неудобный, а может я просто не умею его готовить, но вообщем я рещил перебратся на нормальный движок.
Вообщем встречайте новый адрес блога про программирование с wxWidgets
Как же меня достал механизм восстанавления лайота в AUI, который не может отследить ситуацию что реальный лайот у нас поменялся (добавился новый элемент), и все косячит:(
Пара маленьких функий, может кому пригодится.
Был удивлен что у wxMenu::Append нету для добавления меню с картинками. Пришлось писать самому
wxMenuItem * MainFrame::AppendMenuItemWithImage(wxMenu* parentMenu,
int id, const wxString& text, const wxString& helpString, const wxBitmap& checked, const wxBitmap& unchecked, wxItemKind kind, wxMenu* subMenu){
wxMenuItem* menuItem =
new wxMenuItem(parentMenu, id, text, helpString, kind, subMenu);menuItem->SetBitmaps(checked, unchecked);
parentMenu->Append(menuItem);
return menuItem;}
Использование:
wxMenu* itemMenu = new wxMenu;
AppendMenuItemWithImage(itemMenu, ID_HIDE, _("&Hide In Tray\tEsc"), _T(""), wxBitmap(hide_xpm));
AppendMenuItemWithImage(itemMenu, wxID_EXIT, _("E&xit\tAlt-x"), _T(""), wxBitmap(exit_xpm));
menuBar->Append(itemMenu, _("&File"));
И еще один маленький хелпер для удобной работы с выделенными айтемами в wxListCtrl:
vector<
long> MainFrame::GetListCtrlItems(const wxListCtrl * lcont, int state /*= wxLIST_STATE_DONTCARE*/, int geometry /*= wxLIST_NEXT_ALL*/, long item/*=-1*/){
vector<
long> items;items.resize(lcont->GetSelectedItemCount());
// надеюсь так быстрее чем push_back long ind=0; do{
item= lcont->GetNextItem(item, geometry, state);
if (item!=-1) items[ind++]=item; //items.push_back(item);}
while( item != -1 ); return items;}
Использование:
vector<
long> items=GetListCtrlItems(m_listFormat, wxLIST_STATE_SELECTED);BOOST_FOREACH(
long item, items){
str+=m_listFormat->GetItemText(item)+wxT(
"\n");…
}
Иногда удобнее работать с вектором, хотя это я просто сейчас с STL знакомлюсь, вот и выпендриваюсь:)
Так я думал когда увидел в wx-mail-list упоминание EVT_CHAR_HOOK. В доке про этот эвент ничего нет, но порывшись в гугле и поэкспеременитровал - я понял что его обработчик получает все нажатия клавиш для окна перед тем как они будут обработанны дочерними контролами. И возрадовался. Дело в том что я люблю так хоткее делать, под мфц это было PreTranslateMessage, под wxWidgets найденный вариант был - вся работа в обработчике EVT_KEY_DOWN и connect для (почти) каждого контрола на форме
m_Note->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)NULL, this);
А поскольку коннкетить каждый контрол для сложного окна не самое приятно времепрепровождение, то я легко возбудился увидив EVT_CHAR_HOOK. И действительно коннекты уже не нужно, обработчик вызывается автоматом. Проблемы вылезли через пару дней:(. Первое по esc приложение "прячется" в трей - в новом варианте, если при открытом меню нажать еск, приложение спрячется а меню останется висеть:) Те хоткеи обработка которых зависила от выбранного в данный момент окна - то же в пролете.
Вообщем не получилось, хотя возможно стоит использовать EVT_CHAR_HOOK для ряда глобальных хоткеев (хотя с этим и меню справляется), а EVT_KEY_DOWN оставить для более специфических вещей.
Обнаружил что Винда не любит точки в конце папок, поэтому доработал функциию ReplaceForbiddenCharsInFileName, теперь будет так
/********************** 22/03/08 19:41 *************************
deleteDotsAtEnd - удалять ли точки в конце, винда неразрешает такие имена, хотя и дает их создать програмно:)
******************************************************************/
/*static*/
wxString & BegUtils::ReplaceForbiddenCharsInFileName(wxString & name, const wxString ch/*=wxT("_")*/, bool deleteDotsAtEnd/*=true*/){
wxString forbidden = wxFileName::GetForbiddenChars();
int size=forbidden.Length(); for (int i=0; i<size; ++i)name.Replace( wxString(forbidden[i]), ch,
true); if (deleteDotsAtEnd){
int count=0, len=name.Len()-1; while( name.GetChar(len-count)==_T('.')) count++; if (count) name=name.Left(name.Length()-count);}
return name;}
(пока я пишу только под винду)
Что-то последнее время были преимущественно негативные топики. Но не все так плохо, просто готовил программу к релизу, осваивал кучу новых тем, разумеется много чего не получалось вот и расстраивался:)
А вообще:
Вообщем к эксплуатации пригодно.
Наконец более-менее дописал, хотя с иконками конечно еще плохо, но если кому интересно - бету, а фактически релиз, можно посмотреть тут.
Полюбуйтесь на это - http://sourceforge.net/tracker/index.php?func=detail&aid=1428691&group_id=9863&atid=109863 . Багу больше 2x(!) лет, тянется еще с прошлого стабильного релиза. До сих пор не пофиксен. Status: Open. А ведь есть специальные события даже EVT_QUERY_END_SESSION и EVT_END_SESSION
Потратил полдня включая\выключая комп что бы найти приемлимый порядок команд для того что бы заставить его корректно выходить при выключении компа и сохранять настройки. И вчера уже собираясь выложить первую бету народу, обнаружил что под win2K не работает все равно. Мало того что не работает, так еще и подвисает при выходе. Сейчас опять буду е****я что бы работало везде.
Изолью душу:) Решил добавить сабж, думал все просто: копи\пайст с книжки, разобраться, подправить под себя, потестить - на час работы, максимум два. Растянулось на целый день:)
Скопировал, разобрался, подправил, тестю - все ок. Обрадовался, собрал себе релиз для внутреннего пользования - и тут засада. В релизе, при запуске второй копии, падает сервер. Дебаг, понятное дело затруднен... В итоге нашел падает на строчке.
return m_connection;
В wxConnectionBase *stServer::OnAcceptConnection(const wxString& topic). Вернее конечно не на ней, а после нее в дебрях библиотеки. Начал ковырятся, дошел до того что поведение программы, в смысле место падения, меняется в зависимости от того где определен конструктор в заголовочном файле или в cpp :). В итоге решил вообще отказатся от использования соединений для общения, просто если приходит от клиента попытка установить соединение, ему отказывать и серверу появлятся на экране. Так работало.
Но тут осенило, что трабла в то что, где-то что-то портило память - поэтому такое, более чем странное поведение программы. Решил рыть до конца. В итоге заметил, что в декларациях классов скопированных с книжки, после определения функций в пределах h файла ';' то есть, то нет. Насколько я знаю это не критично, можно ставить можно нет. Решил поставить везде ';' и чудо свершилось... с надеждой в душе, убрал их назад в небытие, но не помогло - программа все равно не падала. Вот и как это объяснить?
Добавление к программе wxmsw28u_html.lib для поддержки wxHtmlWindow и about- диалога основанного на хтмл утяжеляет екзешник на 170 кб, для меня это 10%.