Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Отмена обработки сообщения Windows (API)


Автор: sani79 15.1.2006, 10:34
Как перехватить сообщение windows до начала его обработки системой и в определенном случае отменить его обработку. Например сообщение WM_SYSKEYDOWN, в зависимости от того какая клавиша нажата либо пропустить сообщение, либо блокировать его так как будто его не было. ?

Автор: mes 15.1.2006, 18:54
Код

Type Form1 =
    ....
  procedure SysKeyDown(var Message: TWMChar); [color=green]message WM_SysKeydown[/color];
    ....
  end;

implements
   .....
  procedure Form1.SysKeyDown(var Message: TWMChar); message WM_SysKeydown;
  begin

//     Проверяешь нузно ли тебе это сообщение 
//     например так:

    [color=green]   if ......   then ....[/color]

//    Если не нужно, отдаешь дальше системе (точнее перекрытому методу )  

      [color=green] else  inherited[/color]

 end;

Автор: sani79 15.1.2006, 19:01
Спасибо за ответ. Но вопрос далее - а как быть если сообщение нужно отменить, не передавать его дальше вообще, либо передать какое то другое вместо него?

Автор: mes 15.1.2006, 19:26
smile напишу более подробно:



1) Чтоб передать сообщение системе нужно вызвать перекрытый метод: inherited

begin
..... // Обработка сообщения до системы
inherited // Вызов системной ф-ции обработки
.... // Обработка сообщения после системы
end;


2) Если не хочешь передовать не вызывай этот метод.

3) Если хочешь передать при условии, поставь условие: if ... then .... else inherited
case ... of .... else inherited
4) Если хочешь послать другое сообщение, пошли другое сообщение с помощью
Sendmessage (Handle, Msg, WParam, LParam)



Автор: FRAGNATIC 15.1.2006, 19:54
hook поставить =)

Автор: sani79 16.1.2006, 09:19
Спасибо за советы. В общем у меня все получилось, единственно сейчас пробую ршение через хук и есть проблемка... написал dll:
Код

library hd;

uses
  SysUtils, Classes, Windows, Messages, Dialogs;
var
 SysHook : HHook = 0;
 Wnd : Hwnd = 0;  

function SysMsgProc(code : integer; wParam : word;
 lParam : longint) : longint; stdcall;
begin
   if TMsg(Pointer(lParam)^).message = WM_SysKeydown then
     if TMsg(Pointer(lParam)^).wParam = ... then ShowMessage('TEST');
    CallNextHookEx(SysHook, Code, wParam, lParam);
end;

procedure RunStopHook(State : Boolean) export; stdcall;
begin

 if State=true then SysHook := SetWindowsHookEx(WH_GETMESSAGE, @SysMsgProc, HInstance, 0);
 else  
 begin
   UnhookWindowsHookEx(SysHook);
   SysHook := 0;
 end;
end;

exports RunStopHook index 1;

begin
end.


Ловушка срабатывает, но следом возникает ошибка и далее вплоть до зависания винды...
сейчас разбираюсь... длл писал на основе нескольких разных примеров, возможно что-то недопонял. Если кто видит ошибку, буду признателен если укажите... насколько я понимаю проблема в передачи сообщения после срабатывания ловушки....

Автор: bems 17.1.2006, 14:49
Процедура хука работает в контексте процесса который послал сообщение. Перед вызовом длл подключается к этому процессу и работает с собственной копией данных. Поэтому переменная HHook в теле процедуры хука у тебя равна нулю (присваивание касается копии переменной для процессы установившего хук, все будет работать только если ты установишь хук не для всех потоков, а только своих). Поэтому в CallNextHookEx ты передаешь нуль - так не надо.

Параметр wParam не смотря на название имеет тот же тип что и lParam (тоже 4 байта).

Есть еще одна не критическая ошибка, но лучше бы тебе в этом разобраться. Ты устанавливаешь хук типа WH_GETMESSAGE, а процедуру хука пишешь как для WH_SYSMSGFILTER. Тебе повезло что для обоих типов lParam ссылается на одинаковою запись. Но не для всех типов это так, и если ты изменишь тип на какой-нибудь еще, то надо переписать и процедуру хука. Еще эти типы отличаются значением параметра code, но ты его не анализируешь (Почему?) - в общем это тебе еще повезло. Кстати, CallNextHookEx нужно вызывать или не вызывать в зависимости от этого самого code

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)