Delphi中通过子类化实现全局WINDOWS事件处理

var

  oldWndProc: Pointer = nil;
  SubclassHandles : TList;
  SubclassWndProc: TList;

procedure SaveInstance(instance: Pointer);
type
  Parser = packed record
     funcPtr: Pointer;
     objPtr: Pointer;
  end;
  PObjectInstance = ^TObjectInstance;
  TObjectInstance = packed record
    Code: Byte;
    Offset: Integer;
    case Integer of
      0: (Next: PObjectInstance);
      1: (Method: TWndMethod);
  end;
var
  pObjectInst: PObjectInstance;
  ps: Parser;
  wc: TWinControl;
begin
  pObjectInst:= PObjectInstance(instance);
  ps:= Parser(pObjectInst.Method);
  wc:= TWinControl(ps.objPtr);
  SubclassHandles.Add( Pointer(wc.Handle));

  SubclassWndProc.Add(instance);
end;

function DispatchSubclass(hWin: HWND; uMsg: Cardinal; wPm: WPARAM; lPm: LPARAM): Integer;stdcall;
var
  idx: integer;
begin
  Result:= 0;
  idx:= SubclassHandles.IndexOf(Pointer(hWin));
  if idx >= 0 then
  begin
    Result:= CallWindowProc(SubclassWndProc.Items[ idx ], hWin, uMsg, wPm, lPm);
  end;
end;

function SubclassProc(hWin: HWND; uMsg, wPm, lPm: Longint): Longint;stdcall;
begin
  if uMsg = WM_ERASEBKGND then
  begin
    Result:= 0;
  end
  else begin
    Result:= DispatchSubclass(hWin, uMsg, wPm, lPm);
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
var
  i: integer;
begin

  if not firstShow then
  begin
    try
      SubclassHandles:= TList.Create;
      SubclassWndProc:= TList.Create;
      firstShow:= true;
      for i:= 0 to self.ComponentCount - 1 do
      begin
        if (self.Components[ i ] is TWinControl) then
        begin
          oldWndProc:= Pointer(SetWindowLong(
            TWinControl(self.Components[ i ]).Handle, GWL_WNDPROC,
            Integer(@SubclassProc)));
          SaveInstance(oldWndProc);
        end;
      end;
    except
      SubclassHandles.Free;
      SubclassWndProc.Free;
    end;
  end;
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值