mmhook.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:7k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Tel.: +0351-8012255                   =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 15.02.98 - 03:31:31 $                                        =}
  24. {========================================================================}
  25. unit MMHook;
  26. {$I COMPILER.INC}
  27. interface
  28. uses
  29. {$IFDEF WIN32}
  30.     Windows,
  31. {$ELSE}
  32.     WinTypes,
  33.     WinProcs,
  34. {$ENDIF}
  35.     SysUtils,
  36.     Classes,
  37.     Controls,
  38.     Messages,
  39.     Forms,
  40.     MMObj,
  41. {$IFDEF BUILD_ACTIVEX}
  42.     AxCtrlsUtil,
  43. {$ENDIF}
  44.     MMUtils;
  45. type
  46.     {== TMMWndProcComponent ===================================================}
  47.     TMMWndProcComponent = class(TMMNonVisualComponent)
  48.     private
  49.        FOldWndProc     : TFarProc;
  50.        FNewWndProc     : TFarProc;
  51.        FHookWnd        : HWND;
  52.        FOwnerForm      : TForm;
  53.        FHooked         : Boolean;
  54.     protected
  55.        procedure HookOwner; virtual;
  56.        procedure UnHookOwner; virtual;
  57.        procedure HookWndProc(var Message: TMessage); virtual;
  58.        function  CallPrevWndProc(Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; virtual;
  59. {$IFDEF BUILD_ACTIVEX}
  60.        procedure MMParentWindowChanged(var M: TMessage); message MM_PARENTWINDOWCHANGED;
  61. {$ENDIF}
  62.        property HookWnd    : HWND read FHookWnd;
  63.        property OwnerForm  : TForm read FOwnerForm;
  64.        property FormOK     : Boolean read FHooked write FHooked;
  65.     public
  66.        constructor Create(aOwner: TComponent); override;
  67.        destructor  Destroy; override;
  68.     end;
  69. implementation
  70. const
  71.    HookList: TList = nil;
  72. {------------------------------------------------------------------------------}
  73. procedure AddHook(Comp: TMMWndProcComponent);
  74. begin
  75.    if (HookList = nil) then HookList := TList.Create;
  76.    HookList.Add(Comp);
  77. end;
  78. {------------------------------------------------------------------------------}
  79. function RemoveHook(Comp: TMMWndProcComponent): Boolean;
  80. var
  81.    i: integer;
  82. begin
  83.    Result := False;
  84.    HookList.Remove(Comp);
  85.    for i := 0 to HookList.Count-1 do
  86.    begin
  87.       { !!! remove the current component from the Hook chain !!! }
  88.       if (TMMWndProcComponent(HookList[i]).FOldWndProc = Comp.FNewWndProc) then
  89.       begin
  90.          TMMWndProcComponent(HookList[i]).FOldWndProc := Comp.FOldWndProc;
  91.          Result := True;
  92.       end;
  93.    end;
  94.    if (HookList.Count = 0) then
  95.    begin
  96.       HookList.Free;
  97.       HookList := nil;
  98.    end;
  99. end;
  100. {== TMMWndProcComponent =======================================================}
  101. constructor TMMWndProcComponent.Create(aOwner: TComponent);
  102. begin
  103.    inherited Create(aOwner);
  104.    FHookWnd     := 0;
  105.    FHooked      := False;
  106. {$IFNDEF BUILD_ACTIVEX}
  107.    if not (Owner is TForm) then
  108.       raise Exception.Create('Owner must be a Form');
  109. {$ENDIF}
  110.    if (Owner <> nil) and (Owner is TForm) then
  111.    begin
  112.       FOwnerForm := Owner as TForm;
  113.    end;
  114. end;
  115. {-- TMMWndProcComponent -------------------------------------------------------}
  116. destructor TMMWndProcComponent.Destroy;
  117. begin
  118.    UnHookOwner;
  119.    inherited Destroy;
  120. end;
  121. {-- TMMWndProcComponent -------------------------------------------------------}
  122. procedure TMMWndProcComponent.HookOwner;
  123. begin
  124.    if not FHooked and (FOwnerForm <> nil) then
  125.    begin
  126.       { hook the parents WndProc }
  127.       FHookWnd    := FOwnerForm.Handle;
  128.    end;
  129.    if not FHooked and (FHookWnd <> 0) then
  130.    begin
  131.       FNewWndProc := MakeObjectInstance(HookWndProc);
  132.       FOldWndProc := TFarProc(SetWindowLong(FHookWnd,GWL_WNDPROC,LongInt(FNewWndProc)));
  133.       AddHook(Self);
  134.       FHooked := True;
  135.    end;
  136. end;
  137. {-- TMMWndProcComponent -------------------------------------------------------}
  138. procedure TMMWndProcComponent.UnHookOwner;
  139. begin
  140.    if FHooked then
  141.    begin
  142.       FHooked := False;
  143.       { unhook the parents WndProc }
  144.       if FHookWnd <> 0 then
  145.       begin
  146.          if not RemoveHook(Self) then
  147.             SetWindowLong(FHookWnd, GWL_WNDPROC, LongInt(FOldWndProc));
  148.          FreeObjectInstance(FNewWndProc);
  149.          if (FOwnerForm <> nil) then FHookWnd := 0;
  150.       end;
  151.    end;
  152. end;
  153. {-- TMMWndProcComponent -------------------------------------------------------}
  154. function TMMWndProcComponent.CallPrevWndProc(Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT;
  155. begin
  156.    if FHooked then
  157.    Result := CallWindowProc(FOldWndProc,FHookWnd,Msg,wParam,lParam);
  158. end;
  159. {-- TMMWndProcComponent -------------------------------------------------------}
  160. procedure TMMWndProcComponent.HookWndProc(var Message: TMessage);
  161. begin
  162.    with Message do
  163.    Result := CallPrevWndProc(Msg,wParam,lParam);
  164. end;
  165. {$IFDEF BUILD_ACTIVEX}
  166. {-- TMMWndProcComponent -------------------------------------------------------}
  167. procedure TMMWndProcComponent.MMParentWindowChanged(var M: TMessage);
  168. begin
  169.   if (FOwnerForm <> nil) then
  170.   begin
  171.      if FHookWnd <> M.WParam then
  172.      begin
  173.         UnHookOwner;
  174.         FHookWnd := M.WParam;
  175.         if FHookWnd <> 0 then
  176.            HookOwner;
  177.      end;
  178.   end;
  179. end;
  180. {$ENDIF}
  181. end.