{{notification.text}}

MirGames

Прохожий
18.12.06 17:54
0
Вопрос: как заставить приложение обрпботать две зажатые клавиши?

Код, относящийся к обработке клавиш (чего не хватает?)


var keys : Array[0..255] of Boolean;

---------------------
TCWnd = class
public
OnKeyDown: procedure;

---------------------

function WndProc(hwnd, message: DWORD; wParam, lParam: Integer): Integer; stdcall;
var
WndCoreInstance: TCWnd;
begin
result:=0;
WndCoreInstance := TCWnd(GetWindowLong(hWnd, GWL_USERDATA));
case message of
WM_NCCREATE:
begin
WndCoreInstance := TCWnd(PCreateStruct(LParam)^.lpCreateParams);
SetWindowLong(hwnd, GWL_USERDATA, Integer(WndCoreInstance));
Result := DefWindowProc(hwnd, message, wParam, lParam);
end;
WM_KEYDOWN:
begin
keys[wParam] := True;
Result := 0;
if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyDown) then
WndCoreInstance.OnKeyDown;
end;
WM_KEYUP:
begin
keys[wParam] := False;
Result := 0;
end;
end;

--------------------

Основной код:

procedure KeyDown;
begin
if Keys[VK_F2] then MessageBox(0,'F2','F2',MB_OK or MB_ICONEXCLAMATION);
if (Keys[VK_SHIFT]) and (Keys[VK_F3]) then MessageBox(0,'Shift+F3','Shift+F3',MB_OK or MB_ICONEXCLAMATION);
end;

begin
Wnd:= TCWnd.Create(640,480);
Wnd.OnKeyDown:= KeyDown;
Wnd.MessageOperations(hinstance, 0, NIL, 0);
end.



#1
MirGames Dev
18.12.06 18:17
0
Массив keys Больше нигде не изменяется?
#2
Прохожий
18.12.06 19:06
0
Цитата(MeF Dei Corvi @ 18.12.2006 - 14:17) [snapback]44939[/snapback]

Массив keys Больше нигде не изменяется?



нет, нигде
#3
DGDever
18.12.06 21:41
0
Так, а что, собственно, не работает? Что требуется-то от программы?
#4
Прохожий
18.12.06 22:00
0
Цитата(DGDever @ 18.12.2006 - 17:41) [snapback]44970[/snapback]

Так, а что, собственно, не работает? Что требуется-то от программы?



Требуется, чтобы по нажатию VK_ARROW выполнялась процедура А, а по нажатию VK_SHIFT+VK_ARROW - процедура В. Только и всего.
#5
Mirage
18.12.06 22:07
0
Не работает именно VK_SHIFT? Попробуй VK_LSHIFT/VK_RSHIFT. А может они и вовсе не передаются в WM_KEYDOWN, может они в WM_SYSKEYDOWN, не помню.
Можно использовать GetAsyncKeyState - точно работает.
#6
MirGames Dev
18.12.06 22:24
0
Цитата
может они и вовсе не передаются
Передаются :) Во всяком случае, у меня.
#7
DGDever
19.12.06 02:13
0
Может, не работает из-за условия
Код
if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyDown) then
?
А то у меня в программе написано
Код
    WM_KEYDOWN:     Keys[wParam] := True;
    WM_KEYUP:       Keys[wParam] := False;
и все прекрасно работает...

P.S.: У Shift'а код клавиши 16... Попробуй отдельно проверить условие
Код
if Keys[16] then
P.S.S.: Другой выход - попробовать писать обработчик клавы через 60й порт (асм-вставка)... :P там всего-то 15-20 строк...
Отредактировано: 19.12.06 02:18
#8
Прохожий
19.12.06 14:46
0
Цитата(DGDever @ 18.12.2006 - 22:13) [snapback]45027[/snapback]

Может, не работает из-за условия
Код
if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyDown) then
?
А то у меня в программе написано
Код
    
WM_KEYDOWN:     Keys[wParam] := True;
WM_KEYUP:       Keys[wParam] := False;

и все прекрасно работает...


А у меня без этого совсем не работает :-(
#9
Прохожий
19.12.06 14:50
0
Цитата(Mirage @ 18.12.2006 - 18:07) [snapback]44976[/snapback]

Не работает именно VK_SHIFT? Попробуй VK_LSHIFT/VK_RSHIFT. А может они и вовсе не передаются в WM_KEYDOWN, может они в WM_SYSKEYDOWN, не помню.
Можно использовать GetAsyncKeyState - точно работает.


Нет, речь идет о любых произвольных двух зажатых клавишах. Сам по себе шифт работает, и шифт + мышь работает. Но если я хочу обработать две клавиши, зажатые одновременно - начинается бред. В лучшем случае обрабатывается одна из них.
#10
Mirage
19.12.06 16:42
0
Без тега "код" глаза сломать можно...
Вообще-то DefWindowProc надо вызывать, по крайней мере для необработанных тобой сообщений.
Если не будет работать, введи протоколирование на WM_KEYDOWN и WM_KEYUP и смотри что там получается.
Не совсем понятно в чем заключается "бред" и когда он возникает. Перестает работать при зажатии двух клавиш, или когда проверку на зажатие двух клавиш вставляешь?
#11
Прохожий
19.12.06 17:37
0
Все заработало
#12
Mirage
19.12.06 18:56
0
А че было-то? После чего заработало?
#13
Прохожий
19.12.06 19:37
0
Цитата(Mirage @ 19.12.2006 - 14:56) [snapback]45072[/snapback]

А че было-то? После чего заработало?



Я пыталась понять, честное слово. Не знаю. Не могу же я ЭТИМ голову всем морочить. :-(

Убрала условие

Код
if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyDown) then


и в основном цикле дописала

Код
if Assigned(OnKeyDown) then OnKeyDown;


Все, заработало
Отредактировано: 19.12.06 20:38
#{{post.Index}}
{{post.Author.Login}}
{{post.CreatedDate | date:'dd.MM.yy HH:mm'}}
{{post.VotesRating}}
Отредактировано: {{post.UpdatedDate | date:'dd.MM.yy HH:mm'}}