Напишите кто-нибудь нормальное меню

October 15th, 2008 Begemot

+С грустью приходится отметить что в нормальное меню  в wx не завозили:(

А хотелось бы иметь нормальное красивое owner-draw меню, и даже не надо кучи наворотов типа стилей офиса 2003, офиса xp и тд. Просто приятный градиентик сбоку, нормальная прорисовка чекбоксов, возможность задать дисейбленный рисунок… и конечно обязательно нормальное поведение, не хуже системного.

Вот для MFC такое есть.

Напишите кто-нибудь, а ?:)


С думами про MACOS

October 13th, 2008 Begemot

Если пишите на wxWidgets, то наверняка думаете\собираетесь\хотите воспользоватся радостями кроссплатформенности, другими словами портировать приложения на другие платформы. Если среди них есть MAC OS, то можете глянуть на блог посвященный программированию на Python и Objective-C в Mac OS.

Блог про ipod, python и  Objective-C,  не про wxWidgets, но можно найти  и полезную теоретическую информацию. Например про хранение и доступ к настройкам приложения или про Локализация приложений в Mac OS.

Я пока под мак не пишу, но собираюсь, так что закинул в закладки.

Posted in Oбщее | Tags: ,
Comments Off on С думами про MACOS


Еще пару видео туториалов

October 9th, 2008 Begemot

 

Встретилось пару видео про установку wxWidgets и написание hello word.

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


Как выборочно отключить шоткаты в меню. Часть вторая – фигвам.

October 1st, 2008 Begemot

В прошлом посте писал о том как как выборочно отключить шоткаты в меню, всего пару дней мне понадобилось что бы заметить что все это не работает.

Подход основывался на изменении tilte для wxMenu – удаления шотката при закрытии меню и добавления при открытии. Я еще тогда пытался изменить код на Enable\Disable – чтобы оставить текст тайтла в одном месте (легче менять если понадобится). Но это не сработало, разбиратся почему я не стал. Теперь знаю.

При нажатии горячей клавиши ассоциированной с пунктом меню, фрейм получает сообщение об открытии меню и соответвенно отрабатывает OnOpenMenu. Поэтому не работала идея дисейблить пункты, так как при нажатии хоткея  сначала вызывался OnOpenMenu, который делает Enable(), после чего разумеется шоткат срабатывал.

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

Вызывается OnOpenMenu, добавляет сокращения ко всем пунктам, которые мы вручную отключаем, а вот OnCloseMenu, в данном случае не вызывается.

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

Posted in Программирование | Tags: ,
Comments Off on Как выборочно отключить шоткаты в меню. Часть вторая – фигвам.


Как выборочно отключить шоткаты в меню

September 26th, 2008 Begemot

При создании меню в wxWidgets, в названии пункта меню можно указать шоткат, который будет использоватся для выбора этого пункта. Автоматическую обработку шоткатов wxWidgets берет на себя, что с одной стороны, конечно, удобно и приятно. Но с другой – иногда, подобная услужливость, явна лишняя.

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

Решение нашлось на форуме, собственно ответ тут. Добавляем обработчики для открытия\закрытия меню.

 
[sourcecode language=”cpp”]
EVT_MENU_OPEN(MainFrame::OnOpenMenu)
EVT_MENU_CLOSE(MainFrame::OnCloseMenu)

void MainFrame::OnOpenMenu(wxMenuEvent & event)
{
GetMenuBar()->FindItem(ID_COPYITEMTOCLIPBOARD)->SetItemLabel(_(“&Copy to Clipboard\tCtrl+C”));
event.Skip();
}

void MainFrame::OnCloseMenu(wxMenuEvent & event)
{
GetMenuBar()->FindItem(ID_COPYITEMTOCLIPBOARD)->SetItemLabel(_(“&Copy to Clipboard”));
GetMenuBar()->FindItem(ID_COPYITEMTOCLIPBOARD)->SetBitmaps(wxBitmap(copy_clipboard_xpm), wxNullBitmap);
event.Skip();
}
[/sourcecode]

Выглядит грязным хаком, но работает. Особое удивление у меня вызывает необходимость устанавливать каждый раз иконку для меню, причем именно в обработчике закрытия, а не открытия (!), но это волшебство я уже объяснить не могу.


Перевод главы 11: Буфер обмена и поддержка перетаскивания (Drag and Drop)

September 19th, 2008 Begemot

Лирическое отступление

Я уже говорил что решил поучаствовать в переводе на русский книги “Cross-Platform GUI Programming with wxWidgets”. Теперь пришло время публиковать первую переведенную мной главу.

Выбор главы не случаен, я как раз сейчас работаю над написанием на wxWidgets программы для ведения истории буфера обмена.

Можете высказывать свои замечания, пожелания, поправки… они вполне могут войти в финальный вариант перевода.

Спасибо Алексею, за редактирование и оформление текста.

Читать под катом.

 

Read the rest of this entry »

Posted in Учебники | Tags:
Comments Off on Перевод главы 11: Буфер обмена и поддержка перетаскивания (Drag and Drop)


wxSearchCtrl или может я чего-то не понимаю?

September 11th, 2008 Begemot

Писец какой-то, нужно реализовать фильтрацию\поиск в приложении, вспомнаю что в wxWidgets есть специальный компонент для поиска – красивенький такой.

image

Ура думаю, сейчас быстро заюзаю, и напишу в блог в категорию ‘+1’. Как же заюзал, вообщем сегодня будем пороть  wxSearchCtrl.

  1. Логику человека который догадался разместить кнопку начала поиска слева (!), а очистки – справа мне наверное никогда не понять.
  2. Enter по умолчанию не забинден на кнопку начала поиска, а просто служит для навигации в диалоге, переход на следующий контрол
  3. Что бы иметь возможность отлавливать Enter, надо поставить флаг wxTE_PROCESS_ENTER. Но если создать контрол с этим флагом, то вдруг перестает работать tab(?)…
  4. Connect(wxID_ANY, xEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)NULL,

    this); для этого контрола не работает. А мне обязательно надо…

Если кто разбирался\работал\знает – я ничего не пропустил, может можно добится того чего я хочу?

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

p.s. Кто знает как отловить факт прихода\ухода фокуса для любого контрола в окне?


Учимся вводить только цифры в wxTextCtrl

September 8th, 2008 Begemot

Поразительная фигня, казалось бы простая задача  и должно быть готовое решение. И правда есть, только поразительно кривое:(

Итак, задача – необходимо дать возможность пользователю указать число, например в настройках, количество записей  для отображения где-нибудь… Первое что приходит в голову – wxSlider, ну знаете такой контрол со стрелочками. Так как у меня диапазон от нуля до 10 000, а возможность задать шаг инкрементации для стрелочек я не нашел, и равен он 1 – то этот вариант, оказывается издевательством над юзером.

Думаем дальше и вспоминаем, про wxTextCtrl и валидаторы. Радуемся и пишем код, что-то типа

m_Count = new wxTextCtrl( this, ID_MAXCLIPTEXT, _T(""), wxDefaultPosition, wxSize(50, -1), 0, wxTextValidator(wxFILTER_NUMERIC, &count));

Я ожидал что контрол будет давать вводить в себя только цифры. Я ошибся, он также пропускал точку и запятую, что еще хоть как-то можно понять, хотя его и не просили. Но еще оказались разрешенными: ‘+’ и ‘–’. Также он спокойно пропускал все буквы кирилицы. Похоже что контрол отфильтровывал только пробел, спецсимволы и латиницу. Хотя даже это можно ввести туда пользуясь драг анд дропом или простой вставкой. Вообщем я разочаровался.

Попробывал задать более конкретно wxFILTER_INCLUDE_CHAR_LIST и разрешил только цифры. “голосуй, не голосуй, все равно … “ (с). Теже траблы со вставкой текста из буфера и …. с кирилицей. Прямо наваждение какое-то.

Решил писать сам, вот что получилось

[sourcecode language=”cpp”]
h:
void OnMaxClipTextUpdated( wxCommandEvent& event );

wxTextCtrl* m_Count;

unsigned long maxCount;
long maxInsertionPoint;
wxString maxCountStr;
bool maxSetManually;

cpp:
EVT_TEXT( ID_MAXCLIPTEXT, COPDatabase::OnMaxClipTextUpdated )

m_Count = new wxTextCtrl( this, ID_MAXCLIPTEXT, _T(“”), wxDefaultPosition, wxSize(50, -1), 0);
m_Count->SetMaxLength(4);

void COPDatabase::OnMaxClipTextUpdated( wxCommandEvent& event )
{
if (maxSetManually) return;
wxString str=m_Count->GetValue();

if (str.empty() || (str==wxT(” “))) // вторая проверка нужна для случая когда юзер выделяет все в контроле и жмет пробел
{
maxCount=0;
str=wxT(“0”);
maxInsertionPoint=1;
// or if you want to let empty string – replace last 2 string to these – maxCountStr=wxEmptyString; maxInsertionPoint=0;
}

if (str.ToULong(&maxCount))
{ // successfully converted to ulong, check range now
if (maxCount>10000) maxCount=10000;
else if (maxCount<0) maxCount=0; maxInsertionPoint=m_Count->GetInsertionPoint();
maxCountStr=wxString::Format(wxT(“%i”), maxCount); // we should do like this! иначе траблы с пробелами, нулями..
}

maxSetManually=true;
m_Count->SetValue(maxCountStr);
maxSetManually=false;
m_Count->SetInsertionPoint(maxInsertionPoint);
}
[/sourcecode]

Код выглядит извратом, но именно в такой он превратился после нескольких итераций, и такой заработал лучше всего.

Поведение (юзабилити) не идеально, но твердую 4-ку я бы поставил. Хотя в случае если диапазон снизу ограничен не нулем, тогда поведение хреново будет, но у меня такого случая пока не было. Как выход можно исключить динамическую проверку диапазона, и перенести ее в код сохраняющий значение.

Еще совет, лучше поставить ограничение на длину вводимых символов, типа m_Count->SetMaxLength(4); для верхней границы 10000 и т.д.

Пользуйтесь. Высказывайтесь.


Не показывается tooltips под Windows 2000

September 3rd, 2008 Begemot

Баги + плохая память = даром потраченное время  и нервы. Не совсем про wxWidgets, но может кому полезно будет.

Собираю вчера альфу для своих, типа наконец дожил – радуюсь. Ставлю жене на машину и тут облом, не работают тултипсы. Код на винапи, перетащил со старой программы на мфц и вставил с минимальными правками.  Под ХП все работает, под Windows 2000 не показывается tooltips.

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

Исправил проблемное место в этом коде – не помогло, исправил попутно еще два бага в программе никак не связанных с этим. Самое обидное что в старой версии программы (mfc) этот код работает, в новой(wxwidgets) уже нет.

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

Вот строчка которую я нашел:

[sourcecode language=”cpp”]
ZeroMemory(&ti, sizeof(TOOLINFO));
//ti.cbSize = sizeof(TOOLINFO);
// Я знаю что тут должно быть sizeof(TOOLINFO) =48, но при числах более 44 оно не показывает подсказку – под win2K, похоже только в юникоде
ti.cbSize = 44;
[/sourcecode]

Глюк этот похоже появлятся только в юникодных версиях программ под Windows 2000 – tooltip создается, но не появляется на экране. Решается вот таким грязным хаком.

Шаманство.

Posted in Oбщее
Comments Off on Не показывается tooltips под Windows 2000


Первые траблы с Chome и wxWidgets.

September 3rd, 2008 Begemot

Вот щеет, поставил Chome как дефолтный броузер, теперь мои wx-проги при попытке выполнить код перехода на веб страницу типа

wxLaunchDefaultBrowser(dHomeLink, wxBROWSER_NEW_WINDOW); 

запускают броузер и открывают страницу, но выдают ошибку

12:39:20: Can’t open registry key ‘HKCR\http\shell\open\DDEExec\topic’ (error 2: the system cannot find the file specified.)
12:39:20: Can’t read value of ‘HKCR\http\shell\open\DDEExec\topic’ (error 2: the system cannot find the file specified.)

Че за  новая напасть:(