Копайте и выкопаете
December 23rd, 2007 Begemot Posted in Программирование
Я уже писал про проблему навигации по дереву из другого контрола. Все таки я ее решил.
Задача – в окне есть дерево и другие контролы (у меня только редактор, но думаю что решение масшабируется), необходимо дать юзеру возможность перемешаться по ветвям дерева не заставляя его сначала переключить туда фокус а потом вернутся назад.
Решение – для навигации используется 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__
Разумеется это обработчик события отпускания клавиши для эдита.