Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2006 Feb : application wide keyboard hook problem

www.cryer.info
Managed Newsgroup Archive

application wide keyboard hook problem

Subject:application wide keyboard hook problem
Posted by:"Dan" (no_spam@no_spam.com)
Date:17 Feb 2006 19:35:25 -0700

Hi,
For a long time I have been using the component below to implement application wide keyboard hook in an application that consists of several delphi dlls and exe (built without runtime packages) and a few VC++ dlls. In most of the cases it works like a champ however in Windows server 2003 with AWE enabled, as soon as a key is pressed in the application, an acccess violation occurs and the whole application simply dies - not even the global application onerror method is called. Can someone please help? I simply haven't been able to figure out what's going on here.
---code for the component ------------------
unit KeyboardHook;

interface

uses
  Windows, Classes;

type
  TCallbackThunk = packed record
    POPEDX: Byte;
    MOVEAX: Byte;
    SelfPtr: Pointer;
    PUSHEAX: Byte;
    PUSHEDX: Byte;
    JMP: Byte;
    JmpOffset: Integer;
  end;

  TKeyboardCallback =
      procedure(code: Integer; wparam: WPARAM; lparam: LPARAM) of object;

  TKeyboardHook = class(TComponent)
  private
    { Private declarations }
    FHook: HHook;
    FThunk: TCallbackThunk;
    FOnCallback: TKeyboardCallBack;
    function CallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT
        stdcall;
    procedure SetOnCallback(const Value: TKeyboardCallBack);
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property OnCallback: TKeyboardCallBack read FOnCallback write SetOnCallback;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Microbanker', [TKeyboardHook]);
end;

{ TKeyboardHook }

function TKeyboardHook.CallBack(code: Integer; wparam: WPARAM;
  lparam: LPARAM): LRESULT;
begin
  if Code <0 then
    Result:= CallNextHookEx(FHook, Code, wparam, lparam)
  else
  begin
    if Assigned(FOnCallback) then
      FOnCallback(Code, wParam, lParam);
    Result:= 0;
  end;
end;

constructor TKeyboardHook.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FThunk.POPEDX:= $5A;
  FThunk.MOVEAX:= $B8;
  FThunk.SelfPtr:= Self;
  FThunk.PUSHEAX:= $50;
  FThunk.PUSHEDX:= $52;
  FThunk.JMP:= $E9;
  FThunk.JmpOffset:= Integer(@TKeyboardHook.Callback)-Integer(@FThunk.JMP)-5; //set the offset to the address of the callback
  FHook:= SetWindowsHookEx(WH_KEYBOARD, TFNHookProc(@FThunk), 0, MainThreadID);
end;

destructor TKeyboardHook.Destroy;
begin
  UnhookWindowsHookEx(FHook);
  inherited;
end;

procedure TKeyboardHook.SetOnCallback(const Value: TKeyboardCallBack);
begin
  FOnCallback := Value;
end;

end.

Info

Glossary

Replies:

www.cryer.info
Managed Newsgroup Archive