![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
есть ли разница между onKeyUp и onKeyPress? [D7, WinXP]
Creative © (2006-11-27 17:06:00)Пытаюсь описать собственный класс окна. Все работает, но удивляет одна вещь. У меня обрабабывается событие onKeyPress, пишу аналогичную обработку событие onKeyUp. Результат - тот же самый. Все событие, которе должны происходить, происходят, пока клавише нажата. Разве они не должны происходить только при ее отпускании? Почему так происходит?
type TWndCore = class
private
......//все нужные поля
OnKeyPress : procedure;
OnKeyUp : procedure;
constructor CreateWnd(Width, Height : integer; FullScreen, VSync : boolean; ColorDepth, Freq : integer);
destructor Destroy(); override;
function MessageOperations(hInstance : HINST; hPrevInstance : HINST; lpCmdLine : PChar; nCmdShow : Integer) : Integer; stdcall;
===============
function TWndCore.MessageOperations(hInstance, hPrevInstance: HINST;
lpCmdLine: PChar; nCmdShow: Integer): Integer;
var Msg : TMsg;
begin
.........
if @OnKeyPress <> nil then OnKeyPress;
if @OnKeyUp <> nil then OnKeyUp;
end;
Основной код
procedure KeyUp;
begin
if Keys[VK_UP] then DoSmth1;
end;
procedure KeyPress;
begin
if Keys[VK_UP] then DoSmth2;
end;
begin
Wnd := TWndCore.CreateWnd(640, 480, false, true, 32, 60);
Wnd.OnKeyPress := KeyPress;
Wnd.OnKeyUp := KeyUp;
Wnd.MessageOperations(hinstance, hprevinst, cmdline, cmdshow)
end.
Игорь Шевченко (2006-11-28 14:08:00) [1]Creative (28.11.06 14:01) [33]
> Скажите, а я могу аналогичным образом
> (if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.
> OnKeyDown) then
> WndCoreInstance.OnKeyDown;)
> обрабатывать и другие сообщения?
Безусловно
Creative (2006-11-28 14:04:00) [2]Извиняюсь, выяснила, что кажется могу :-)
Creative (2006-11-28 14:01:00) [3]Скажите, а я могу аналогичным образом
(if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyDown) then
WndCoreInstance.OnKeyDown;)
обрабатывать и другие сообщения?
Игорь Шевченко (2006-11-28 13:55:00) [4]Creative (28.11.06 13:49) [31]
В обработчике сообщения NCCREATE происходит установка соответствия между окном и экземпляром класса TWndCore, для того, чтобы потом, зная HWND окна, можно было легко и просто узнать экземпляр класса WndCore, создавший это окно.
Creative (2006-11-28 13:49:00) [5]Вы знаете, я посмотрела и решила, что действительно - KeyDown вполне достаточно. Спасибо вам большое.
У меня только один вопрос еще: не могли бы вы объяснить, что сейчас происходит в обработке сообщения WM_NCCREATE?
Игорь Шевченко (2006-11-28 13:43:00) [6]Creative (28.11.06 13:29) [29]
Если тебе надо по нажатию на кнопку делать какие-то действия, то и делай. Зачем делать что-то по ее (кнопки) отпусканию ?
Creative (2006-11-28 13:29:00) [7]
> А зачем ее (процедуру OnKeyUp) вообще вызывать ?
Если я правильно понимаю, то все равно придется вернуться к тому, что собственно в WM_KEYUP писать обработку нажатий всех клавиш, которые мне нужны. Или нет? Извините, пожалуйста, но я не совсем ясно вас понимаю.
Игорь Шевченко (2006-11-28 13:17:00) [8]Creative (28.11.06 13:05) [27]
В MessageOperations наверное вообще ничего не надо писать ? Какой смысл вызывать процедуру, реагирующую на нажатие кнопок, при обработке каждого сообщения ?
А зачем ее (процедуру OnKeyUp) вообще вызывать ?
Creative (2006-11-28 13:05:00) [9]Отчет.
Все запускается, но работает следующим образом:
1. KeyDown работает точно, при этом очень хорошо заметно, насколько он отличается от KeyPress.
2. KeyUp - не работает вовсе. Она начинает работать, если в MessageOperations написать строку if @OnKeyUp <> nil then OnKeyUp; (аналогично if @OnKeyPress <> nil then OnKeyPress, которая стояла там раньше), но при этом она и работает как KeyPress. по-моему это неправильно.
Как заставить работать KeyUp?
Игорь Шевченко (2006-11-28 12:53:00) [10]В обработку сообщения WM_NCCREATE добавь перед end строку:
Result := DefWindowProc(hWnd, Msg, wParam, lParam);
Creative (2006-11-28 12:41:00) [11]И начинается эта кривизна, как только в коде появляется обработка сообщения WM_NCCREATE
Creative (2006-11-28 12:39:00) [12]...и выдает он ее в соответствии вот с этим кодом:
if FHandle = 0 then begin
MessageBox(FHandle, 'Failed to get a FB render port context.', 'Fatal error', MB_OK or MB_ICONERROR);
Destroy();
exit;
Насколько я поняла, это потому что
FHandle := CreateWindowEx(dwexstyle, ApplicationName, ApplicationName, dwstyle, 0, 0, Width, Height, 0, 0, h_Inst, self);
либо вообще не происходит, либо происходит как-то криво
Creative (2006-11-28 12:36:00) [13]Откомпилиться-то он откомпилился, но при запуске выдает ошибку:
Failed to get a FB render port context.
Creative (2006-11-28 12:34:00) [14]а с избыточностью параметров как быть?
Игорь Шевченко (2006-11-28 12:28:00) [15]
> 2. WndCoreInstance.OnKeyDown(WndCoreInstance) - too many
> actual parameters
Тогда просто WndCoreInstance.OnKeyDown; и WndCoreInstance.OnKeyUp;
Игорь Шевченко (2006-11-28 12:27:00) [16]Creative (28.11.06 12:08) [17]
> > WM_NCCREATE:
>
>
> а что это такое?
Это сообщение Windows
> 1. GWL_USER - undeclared identifier
Виноват, GWL_USERDATA
Creative (2006-11-28 12:22:00) [17]Есть два затруднения:
1. GWL_USER - undeclared identifier
2. WndCoreInstance.OnKeyDown(WndCoreInstance) - too many actual parameters
Creative (2006-11-28 12:16:00) [18]
> WM_NCCREATE:
а что это такое?
Creative (2006-11-28 12:08:00) [19]
> Из приведенного кода я не вижу, что действие (хоть какое-
> то) происходит в момент нажатия клавиши. По приведенному
> коду (в посте[0]) мне непонятно, в какой момент производится
> вызов твоих обработчиков OnKeyUp и OnKeyPress.
>
> Может, тебе подойдет такой способ:
Если честно, из кода мне тоже это непонятно, поэтому я здесь. Я просто вижу, что оно происходит, но не могу объяснить почему.
А ваш способ обязательно сейчас попробую.
Игорь Шевченко (2006-11-28 11:57:00) [20]Creative (28.11.06 11:08) [15]
> Да, но в действие то происходит момент нажатия клавиши.
> Как же так?
Из приведенного кода я не вижу, что действие (хоть какое-то) происходит в момент нажатия клавиши. По приведенному коду (в посте[0]) мне непонятно, в какой момент производится вызов твоих обработчиков OnKeyUp и OnKeyPress.
Может, тебе подойдет такой способ:
function MainAction(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
WndCoreInstance: TWndCore;
begin
Result := 0;
WndCoreInstance := TWndCore(GetWindowLong(hWnd, GWL_USER));
case (Msg) of
WM_NCCREATE:
begin
WndCoreInstance := TWndCore(
PCreateStruct(LParam)^.lpCreateParams);
SetWindowLong(hWnd, GWL_USER, Integer(WndCoreInstance));
end;
WM_CREATE:
begin
//
end;
WM_CLOSE:
begin
PostQuitMessage(0);
Result := 0
end;
WM_KEYDOWN:
begin
keys[wParam] := True;
Result := 0;
if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyDown) then
WndCoreInstance.OnKeyDown(WndCoreInstance);
end;
WM_KEYUP:
begin
keys[wParam] := False;
Result := 0;
if Assigned(WndCoreInstance) and Assigned(WndCoreInstance.OnKeyUp) then
WndCoreInstance.OnKeyUp(WndCoreInstance);
end;
...........
end;
И в том месте, где в WndCore создается окно, в CreateWindow или в CreateWindowEx последним параметром вставить Self