Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.07.2010, 23:01   #1
Impuls1989
Форумчанин
 
Аватар для Impuls1989
 
Регистрация: 16.08.2008
Сообщений: 276
По умолчанию Узнать нажата ли стрелка на клавиатуре

Доброго времени суток уважаемые эксперты. Суть вопроса такова:
Моя идея
Пишу компонент, который будет по нажатию функциональных клавиш переключаться на выбранный мной компонент (что-то типа модифицированного TAB-a). Пример такой: есть форма, на которой установлено куча Button-ов, Edit-ов, CheckBox-ов и т.д. Все это чудо выставлено по рядам и по столбцам (в произвольном порядке разумеется). Далее ставим мой компонент, вбиваем нужный порядок переключения и вуаля... по нажатии на (ну допустим CTRL+'в право') фокус получает следующий элемент в данном ряду. По нажатии CTRL+'в низ' фокус получает первый элемент в следующем ряду. Ну и т.д.
Мой вопрос
Компонент выставляет свойство формы KeyPreview в true
Далее я переопределяю свойство формы OnKeyDown на свое, в котором и должен располагаться код перехода между элементами. И тут-то начинается самое интересное. Для примера написал такой код:
Код:
  if (Key = 37) then ShowMessage('LEFT');
  if (Key = 38) then ShowMessage('UP');
  if (Key = 39) then ShowMessage('RIGHT');
  if (Key = 40) then ShowMessage('DOWN');
  if (Key = 81) then ShowMessage('Q');  
  if (Shift = [ssCtrl]) then ShowMessage('CTRL');
С CTRL проблем нету: его нажатие отлавливается нормально
С буквой Q - тоже все хорошо
А вот со стрелками возникли проблемы: их нажатие отлавливается только тогда, когда на форме нет ни одного компонента, на который можно установить фокус. Точно такая же ситуация, когда я прописываю вышеприведенный код в свойство OnKeyDown формы (без моего компонента). Ну вопрос я думаю понятен: как исправить или обойти данную проблему?
Заранее спасибо.
Искусственный интеллект - фигня по сравнению с естественной глупостью
Impuls1989 вне форума Ответить с цитированием
Старый 19.07.2010, 23:26   #2
ZaRDaK
Форумчанин
 
Регистрация: 01.09.2009
Сообщений: 197
По умолчанию

Попробуй локальные хуки
SetupLocalHook вызовешь при создании формы
RemoveLocalHook при унчтожении
в KeyBoardHook напишешь обработчик событий
Код:
unit Local;

interface

uses windows,sysutils;

function SetupLocalHook: boolean;
function RemoveLocalHook: boolean;
function KeyBoardHook(code: integer; wParam: word; lParam: longword): longword; stdcall;

var CurrentHook: HHook;
    HookInstalled: boolean;
    
implementation

function SetupLocalHook: boolean;
begin
    CurrentHook:=setwindowshookex(WH_KEYBOARD,@KeyBoardHook,0,GetCurrentThreadID());
    if CurrentHook<>0  then SetupLocalHook:=true else SetupLocalHook:=false;
end;

function RemoveLocalHook: boolean;
begin
    RemoveLocalHook:=UnhookWindowsHookEx(CurrentHook);
    RemoveLocalHook := True;
end;


function KeyBoardHook(code: integer; wParam: word; lParam: longword): longword; stdcall;
begin
    if code<0 then begin
       KeyBoardHook:=CallNextHookEx(CurrentHook,code,wParam,lparam);
       Exit;
    end;
    if (lParam and KF_UP)=0 then begin
    //код обработки нажатой стрелки вверх
    end;
    if (lParam and KF_DOWN)=0 then begin
    //код обработки нажатой стрелки вниз
    end;   
    CallNextHookEx(CurrentHook,code,wParam,lparam);
    KeyBoardHook:=0;
    Exit;
end;

end.
ZaRDaK вне форума Ответить с цитированием
Старый 19.07.2010, 23:51   #3
Impuls1989
Форумчанин
 
Аватар для Impuls1989
 
Регистрация: 16.08.2008
Сообщений: 276
По умолчанию

Хук ставится, но срабатывает постоянно. (lParam and KF_UP)=0 AND в любом случае выдает 0. И насчет KF_UP и иже с ним: может надо VK_UP?
И еще. Функция вызывается дважды: при нажатии на кнопку, и при отпускании((
___________________________________ ___________________________________ _
В общем частично проблему я решил. Объясните что лежит в wParam и в lParam? Я так понимаю что в lParam лежат некие флаги нажатия/отжатия клавиш и флаги функциональных клавиш. Расскажите как это все достать?
Искусственный интеллект - фигня по сравнению с естественной глупостью

Последний раз редактировалось Impuls1989; 20.07.2010 в 00:40.
Impuls1989 вне форума Ответить с цитированием
Старый 20.07.2010, 01:26   #4
ZaRDaK
Форумчанин
 
Регистрация: 01.09.2009
Сообщений: 197
По умолчанию

Да, действительно, не KF_, a VK_
Описание сообщений, которые хукаются (там же и параметры)
http://msdn.microsoft.com/en-us/libr...80(VS.85).aspx
http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx
Вкратце:
wParam = VK_код нажатой\отпущеной кнопки
lParam:
Биты 0-15: Кличество автоматических повторёний нажатия кнопки (если её держать)
Биты 16-23: Скан-код
Бит 24: Является ли нажатая кнопка extended (правый альт например)
Биты 25-28: Зарезервировано вендой
Бит 29: Код контекста. Всегда ноль при сообщении об WM_KEYUP (отпускание кнопки)
Бит 30: Предидущее состояние кнопки. Всегда 1 при сообщении WM_KEYUP
Бит 31: Состояние перехода. Всегда 1 при сообщении WM_KEYUP
ZaRDaK вне форума Ответить с цитированием
Старый 20.07.2010, 20:04   #5
Impuls1989
Форумчанин
 
Аватар для Impuls1989
 
Регистрация: 16.08.2008
Сообщений: 276
По умолчанию

Ну спасибо огромное за помощь. Сейчас буду сидеть разбираться...
Искусственный интеллект - фигня по сравнению с естественной глупостью
Impuls1989 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
И снова хуки... Как узнать нажата ли CTRL? TwiX Общие вопросы Delphi 1 20.05.2010 23:29
как узнать, нажата ли кнопка мыши? Juffin Общие вопросы Delphi 1 20.05.2010 20:16
Как узнать была ли нажата кнопка? SanSanblch Win Api 3 20.12.2009 01:15
Как с помощье ReadKey определить что нажата клавиша "Стрелка" Викдон Паскаль, Turbo Pascal, PascalABC.NET 5 05.02.2009 00:47