Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

есть ли разница между onKeyUp и onKeyPress? [D7, WinXP]


Страницы:   1 2

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо