Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

Глюки в глобальном хуке (p.s. FAQи смотрел, не помогает)

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
Const69



Зарегистрирован: 27.10.2005
Сообщения: 3

СообщениеДобавлено: Чт Ноя 10 2005 19:31    Заголовок сообщения: Глюки в глобальном хуке (p.s. FAQи смотрел, не помогает) Ответить с цитатой

Сделал всё по-писаному -- написал DLL с хуками от клавы и мыши, с общей областью, посылкой сообщений главному окну и пр.

Работает замечательно. Всё перехватывает. Выключаю хуки, включаю, хоть сто раз, сбоев нет.

Глюки начинаются, когда я, при включенном хуке, раскрываю папку, которая лежит на desktop'е. Потом закрываю. Ничего больше.
Так вот, когда с первого раза, когда со второго. но глючить начинает обязательно.
Внешне это выглядит так: не активируется ни одна иконка на десктопе, не вызывается меню СТАРТ, десктоп не перерисовывается, а потом и вообще всё с десктопа исчезает, кроме фоновой картинки.
Те проги, что были запущены, работают. Единственно, что можно сделать -- нажать ctrl+alt+del и перегрузиться.

Что за нафиг? Кто-нибудь с таким сталкивался?





Кроме того. В callback-функциях хука (обработка событий в DLL), я должен возвращать результат.
Допустим, я ничего не хочу блокировать. Т.е. не должен возвращать 1. Как должна выглядеть моя обработка?

В разных источниках я видел разные варианты:

function KeybdHookProc (aCode, aWParam, aLParam: longint): longint; stdcall;

1) if ( aCode < 0 ) then begin
CallNextHookEx (...);
Result := 0;
end else begin
PostMessage (...); // моя обработка
Result := CallNextHookEx (...);
end;

2) if ( aCode < 0 ) then begin
Result := CallNextHookEx (...);
end else begin
PostMessage (...); // моя обработка
CallNextHookEx (...);
Result := 0;
end;

3) if ( aCode >= 0 ) then
PostMessage (...); // моя обработка
Result := CallNextHookEx (...);

Глючит при любом варианте.





И ещё. При создании хука, нужно задавать тип хука. По справке всё просто -- WH_KEYBOARD и WH_MOUSE.
Но в одном из примеров был такой вариант:

if ( integer(GetVersion) > 0 ) then begin // NT, 2000 ..
whK := 13; // WH_KEYBOARD_LL
whM := 14; //
end else begin // 95, 3.1 ...
whK := WH_KEYBOARD;
whM := WH_MOUSE;
end;
hKeybdHook := SetWindowsHookEx (whK, KeybdHookProc, hInstance, 0);
hMouseHook := SetWindowsHookEx (whM, MouseHookProc, hInstance, 0);

И как это понимать? У меня в XP всё прекрасно работает и с WH_KEYBOARD / WH_MOUSE.






Буду благодарен за любую помощь.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
tinimi



Зарегистрирован: 27.03.2005
Сообщения: 90
Откуда: Win32

СообщениеДобавлено: Вс Ноя 13 2005 11:57    Заголовок сообщения: Ответить с цитатой

WH_KEYBOARD_LL, WH_MOUSE_LL - ето низкоуровневый хук, он тебе не нужен.

Ты не кричи "глючит", а кинь свой кусок кода, ВЕСЬ!

Я в свое время такое делал и все работало.

А еще почитай чего нить по Win32API. Не просто справочник, а учебник.
_________________
[ TiNiMi ]
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Const69



Зарегистрирован: 27.10.2005
Сообщения: 3

СообщениеДобавлено: Пн Ноя 14 2005 12:03    Заголовок сообщения: Ответить с цитатой

вот DLL (оставил только клаву):

Код:

library hook_KM;


uses
  Windows, Messages;



type
  PHookData = ^THookData;
  THookData =
    record
      hKeybdHook{,            // хэндлы ловушек
      hMouseHook}: HHook;     //
      hTargetWnd: HWnd;       // хэндл окна-приёмника событий
    end;

var
  Mapped: boolean;        //
  EntryErr: longint;
  DataP: PHookData;
  hMMF: THandle;          // хэндл мап-файла
  WM_KeybdHook{,          // сообщения о событиях
  WM_MouseHook}: DWord;   //



function KeybdHookProc (aCode, aWParam, aLParam: longint): longint;  stdcall;
begin
  if ( DataP = nil ) then begin
    Result := CallNextHookEx (0, aCode, aWParam, aLParam);
  end else begin
    if ( aCode = HC_ACTION ) then
      PostMessage (DataP^.hTargetWnd, WM_KeybdHook, aWParam, aLParam);
    Result := CallNextHookEx (DataP^.hKeybdHook, aCode, aWParam, aLParam);
  end;
end;

{
function MouseHookProc (aCode, aWParam, aLParam: longint): longint;  stdcall;
begin
  if ( DataP = nil ) then begin
    Result := CallNextHookEx (0, aCode, aWParam, aLParam);
  end else begin
    if ( aCode = HC_ACTION ) then
      PostMessage (DataP^.hTargetWnd, WM_MouseHook, aWParam, aLParam);
    Result := CallNextHookEx (DataP^.hMouseHook, aCode, aWParam, aLParam);
  end;
end;
}



// возврат 0 - всё нормально
function SetHook (anOn: boolean;  aTargetWnd: HWnd): longint;  export;  stdcall;
begin
  Result := EntryErr;  if ( DataP = nil ) then Exit;
  Result := 0;
  with DataP^ do
    if anOn then begin
      hTargetWnd := aTargetWnd;
      hKeybdHook := SetWindowsHookEx (WH_KEYBOARD, KeybdHookProc, hInstance, 0);
        if (hKeybdHook = 0) then Result := GetLastError;
//      hMouseHook := SetWindowsHookEx (WH_MOUSE,    MouseHookProc, hInstance, 0);
//        if (hMouseHook = 0) then Result := GetLastError;
    end else begin
      hTargetWnd := INVALID_HANDLE_VALUE;
      if not UnHookWindowsHookEx (hKeybdHook) then  Result := GetLastError;  hKeybdHook := 0;
//      if not UnHookWindowsHookEx (hMouseHook) then  Result := GetLastError;  hMouseHook := 0;
    end;
end;





procedure DLLEntryPoint (aCode: DWord);  stdcall;
begin
  case aCode of
    DLL_PROCESS_ATTACH:
      begin
        if Mapped then Exit;  Mapped := True;
        EntryErr := 0;
        WM_KeybdHook := WM_NULL;
//        WM_MouseHook := WM_NULL;
        hMMF  := 0;
        DataP := nil;
          //---------------
        WM_KeybdHook := RegisterWindowMessage ('WM_KEYBD_HOOK');
          EntryErr := GetLastError;
          if ( WM_KeybdHook = 0 ) then Exit;
//        WM_MouseHook := RegisterWindowMessage ('WM_MOUSE_HOOK');
//          EntryErr := GetLastError;
//          if ( WM_MouseHook = 0 ) then Exit;
        hMMF := CreateFileMapping (INVALID_HANDLE_VALUE,
                                   nil,
                                   PAGE_READWRITE,
                                   0,
                                   SizeOf(THookData),
                                   'hook_KM_Area');
          EntryErr := GetLastError;
          if ( hMMF = 0 ) then Exit;
        DataP := MapViewOfFile (hMMF,
                                FILE_MAP_ALL_ACCESS,
                                0,
                                0,
                                SizeOf(THookData));
          EntryErr := GetLastError;
          if ( DataP = nil ) then Exit;
        EntryErr := 0;
      end;
    DLL_PROCESS_DETACH:
      begin
        Mapped := False;
        UnmapViewOfFile (DataP);  DataP := nil;
        CloseHandle (hMMF);       hMMF  := 0;
        EntryErr := -1;
      end;
  end;
end;


exports
  SetHook;

begin
  Mapped := False;
  DLLProc    := @DLLEntryPoint;
  DLLEntryPoint (DLL_PROCESS_ATTACH);
end.






и форма:

Код:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;


type
  TSetHookProc = function (anOn: boolean;  aTargetWnd: HWnd): longint;  stdcall;

  THook = class (TWinControl)
  private
    _FName: string;
    _WM_KeybdHook,
    _WM_MouseHook: DWord;
    _DLL: THandle;
    _SetProc: TSetHookProc;
    _OnHook: TNotifyEvent;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WndProc (var aMsg: TMessage);  override;
  public
    LastErr: longint;
    constructor Create (anOwner: TComponent);  override;
    function Init: boolean;     // чруЁєчър DLL
    function UnInit: boolean;   // т√уЁєчър DLL
    property OnHook: TNotifyEvent  read _OnHook  write _OnHook;
  end;





type
  TForm1 = class(TForm)
    btStart: TButton;
    btStop: TButton;
    laCnt: TLabel;
    me: TMemo;
    tm: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure btStartClick(Sender: TObject);
    procedure btStopClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure tmTimer(Sender: TObject);
  private
    _Cnt: longint;
  public
    Hook: THook;
    procedure OnHook (aSender: TObject);
  end;

var
  Form1: TForm1;










implementation

{$R *.dfm}


function SystemErrorStr (ErrCode: longint = -1): string;
var
  ErrStr: string[255];
begin
  if (ErrCode = -1) then ErrCode := GetLastError;
  byte(ErrStr[0]) := FormatMessage (Format_Message_From_System, nil,
                                    ErrCode, 0, @ErrStr[1], 253, nil);
  Result := Trim(ErrStr);
end;



procedure THook.CreateParams (var Params: TCreateParams);
begin
  inherited;
  with Params do
    Style := Style and (not ws_Child);
end;




constructor THook.Create (anOwner: TComponent);
begin
  inherited;
  LastErr := 0;
  _FName := ExtractFilePath(ParamStr(0)) + 'hook_KM.dll';
  _WM_KeybdHook := RegisterWindowMessage ('WM_KEYBD_HOOK');
  _WM_MouseHook := RegisterWindowMessage ('WM_MOUSE_HOOK');
  _DLL := 0;
  _SetProc := nil;
end;





function THook.Init: boolean;
begin
  UnInit;
  Result := False;  LastErr := 0;
  try
    repeat
      _DLL := LoadLibrary (PChar(_FName));           if ( _DLL = 0 ) then break;
      _SetProc := GetProcAddress (_DLL, 'SetHook');  if not Assigned(_SetProc) then break;
      Result := ( _SetProc (True, Handle) = 0 );
    until True;
    if not Result then LastErr := GetLastError;
  except
    UnInit;
    raise;
  end;
end;

function THook.UnInit: boolean;
begin
  Result := True;  LastErr := 0;
  if (_DLL <> 0) then begin
    if Assigned(_SetProc) then LastErr := _SetProc (False, 0);
    Result := ( LastErr = 0 );
    FreeLibrary (_DLL);
  end;
  _DLL := 0;
  _SetProc := nil;
end;



procedure THook.WndProc (var aMsg: TMessage);
begin
  inherited;
  with aMsg do begin
    if ( Msg = _WM_KeybdHook ) or
       ( Msg = _WM_MouseHook )
    then begin
      if Assigned (_OnHook) then  _OnHook (Self);
    end;
  end;
end;




////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////




procedure TForm1.FormCreate(Sender: TObject);
begin
  _Cnt := 0;
  Hook := THook.Create (Self);
  Hook.OnHook := OnHook;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Hook.UnInit;
end;

procedure TForm1.btStartClick(Sender: TObject);
begin
  if not Hook.Init then
    me.Lines.Add (SystemErrorStr (Hook.LastErr));
end;

procedure TForm1.btStopClick(Sender: TObject);
begin
  if not Hook.UnInit then
    me.Lines.Add (SystemErrorStr (Hook.LastErr));
end;

procedure TForm1.OnHook(aSender: TObject);
begin
  Inc (_Cnt);
end;

procedure TForm1.tmTimer(Sender: TObject);
begin
  laCnt.Caption := IntToStr (_Cnt);
end;

end.

Вернуться к началу
Посмотреть профиль Отправить личное сообщение
tinimi



Зарегистрирован: 27.03.2005
Сообщения: 90
Откуда: Win32

СообщениеДобавлено: Пн Ноя 14 2005 22:04    Заголовок сообщения: Ответить с цитатой

Ну лекарство я тебе не дам, но:

Код:

 repeat
      _DLL := LoadLibrary (PChar(_FName));           if ( _DLL = 0 ) then break;
      _SetProc := GetProcAddress (_DLL, 'SetHook');  if not Assigned(_SetProc) then break;
      Result := ( _SetProc (True, Handle) = 0 );
    until True;

- а не легче было написать что-то типа:
Код:
procedure SetHook; external 'KBDHook.dll';


и зачем тебе ето:

Код:
 _WM_KeybdHook := RegisterWindowMessage ('WM_KEYBD_HOOK');
  _WM_MouseHook := RegisterWindowMessage ('WM_MOUSE_HOOK');


И еще - я не нашел где ты ставиш хуки. Есть SetWindowsHookEx в процеде SetHook.
Короче, почитай WinAPI и Delphi еще че нить. И пиши по проще!
WinApi придумали что бы упростить все, а по твоему коду етого не видно.

Как оказалось атачи сдесь выложить низя, по етому напиши мне на tinimi<at>gmail<dot>com
_________________
[ TiNiMi ]
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...