воскресенье, 23 декабря 2007 г.

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

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

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

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

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

Комментариев нет: