home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Delphi1_And_Delphi2 / EXAMPLES / OTHER / NETSCAPE / NPSUBCLS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  5.4 KB  |  188 lines

  1. unit NPSubCls;
  2.  
  3. interface
  4.  
  5. uses
  6.   Messages, Windows, SysUtils, Classes, Controls, NPPlugin,Forms ;
  7.  
  8. type
  9.   { TSubclassedPlugin }
  10.   { A TPlugin that subclasses Netscape's plugin window's window procedure so
  11.     that it can intercept and handle Windows messages to the plugin window.
  12.     To use this, simply create a subclass and override WndProc to handle
  13.     the Windows messages as appropriate. }
  14.  
  15.   TSubclassedPlugin = class( TPlugin )
  16.   private
  17.     FObjectInstance : pointer ;
  18.     FDefPluginProc  : pointer ;
  19.   protected
  20.     procedure WndProc( var Message : TMessage ) ; virtual ;
  21.     procedure WindowHandleChanging ; override ;
  22.     procedure WindowHandleChanged ; override ;
  23.   public
  24.     constructor Create( AInstance         : PNPP ;
  25.                         AExtraInfo        : TObject ;
  26.                         const APluginType : string ;
  27.                         AMode             : word ;
  28.                         AParamNames       : TStrings ;
  29.                         AParamValues      : TStrings ;
  30.                         const ASaved      : TNPSavedData ) ; override ;
  31.     destructor Destroy ; override ;
  32.   end ;
  33.  
  34. implementation
  35.  
  36. (* When NOT using Forms unit...
  37.  
  38. const
  39.   InstanceCount = 313;
  40.  
  41. { Object instance management }
  42.  
  43. type
  44.   PObjectInstance = ^TObjectInstance;
  45.   TObjectInstance = packed record
  46.     Code: Byte;
  47.     Offset: Integer;
  48.     case Integer of
  49.       0: (Next: PObjectInstance);
  50.       1: (Method: TWndMethod);
  51.   end;
  52.  
  53. type
  54.   PInstanceBlock = ^TInstanceBlock;
  55.   TInstanceBlock = packed record
  56.     Next: PInstanceBlock;
  57.     Code: array[1..2] of Byte;
  58.     WndProcPtr: Pointer;
  59.     Instances: array[0..InstanceCount] of TObjectInstance;
  60.   end;
  61.  
  62. var
  63.   InstBlockList: PInstanceBlock;
  64.   InstFreeList: PObjectInstance;
  65.  
  66. function CalcJmpOffset(Src, Dest: Pointer): Longint;
  67. begin
  68.   Result := Longint(Dest) - (Longint(Src) + 5);
  69. end;
  70.  
  71. { Standard window procedure }
  72. { In    ECX = Address of method pointer }
  73. { Out   EAX = Result }
  74.  
  75. function StdWndProc(Window: HWND; Message, WParam: Longint;
  76.   LParam: Longint): Longint; stdcall; assembler;
  77. asm
  78.         XOR     EAX,EAX
  79.         PUSH    EAX
  80.         PUSH    LParam
  81.         PUSH    WParam
  82.         PUSH    Message
  83.         MOV     EDX,ESP
  84.         MOV     EAX,[ECX].Longint[4]
  85.         CALL    [ECX].Pointer
  86.         ADD     ESP,12
  87.         POP     EAX
  88. end;
  89.  
  90. function MakeObjectInstance(Method: TWndMethod): Pointer;
  91. const
  92.   BlockCode: array[1..2] of Byte = (
  93.     $59,       { POP ECX }
  94.     $E9);      { JMP StdWndProc }
  95.   PageSize = 4096;
  96. var
  97.   Block: PInstanceBlock;
  98.   Instance: PObjectInstance;
  99. begin
  100.   if InstFreeList = nil then
  101.   begin
  102.     Block := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  103.     Block^.Next := InstBlockList;
  104.     Move(BlockCode, Block^.Code, SizeOf(BlockCode));
  105.     Block^.WndProcPtr := Pointer(CalcJmpOffset(@Block^.Code[2], @StdWndProc));
  106.     Instance := @Block^.Instances;
  107.     repeat
  108.       Instance^.Code := $E8;  { CALL NEAR PTR Offset }
  109.       Instance^.Offset := CalcJmpOffset(Instance, @Block^.Code);
  110.       Instance^.Next := InstFreeList;
  111.       InstFreeList := Instance;
  112.       Inc(Longint(Instance), SizeOf(TObjectInstance));
  113.     until Longint(Instance) - Longint(Block) >= SizeOf(TInstanceBlock);
  114.     InstBlockList := Block;
  115.   end;
  116.   Result := InstFreeList;
  117.   Instance := InstFreeList;
  118.   InstFreeList := Instance^.Next;
  119.   Instance^.Method := Method;
  120. end;
  121.  
  122. { Free an object instance }
  123.  
  124. procedure FreeObjectInstance(ObjectInstance: Pointer);
  125. begin
  126.   if ObjectInstance <> nil then
  127.   begin
  128.     PObjectInstance(ObjectInstance)^.Next := InstFreeList;
  129.     InstFreeList := ObjectInstance;
  130.   end;
  131. end;
  132.  
  133. *)
  134.  
  135.  
  136. { TSubclassedPlugin }
  137.  
  138. constructor TSubclassedPlugin.Create( AInstance : PNPP ;
  139.                                       AExtraInfo : TObject ;
  140.                                       const APluginType : string ;
  141.                                       AMode             : word ;
  142.                                       AParamNames       : TStrings ;
  143.                                       AParamValues      : TStrings ;
  144.                                       const ASaved      : TNPSavedData ) ;
  145. begin
  146.   inherited Create( AInstance, AExtraInfo, APluginType, AMode,
  147.                     AParamNames, AParamValues, ASaved ) ;
  148.   FObjectInstance := MakeObjectInstance( WndProc ) ;
  149. end ;
  150.  
  151. destructor TSubclassedPlugin.Destroy ;
  152. begin
  153.   WindowHandleChanging ;
  154.   FreeObjectInstance( FObjectInstance ) ;
  155.   inherited Destroy ;
  156. end ;
  157.  
  158. procedure TSubclassedPlugin.WndProc( var Message : TMessage ) ;
  159. begin
  160.   { call the original plugin window proc }
  161.   with Message do
  162.     Result := CallWindowProc( FDefPluginProc, WindowHandle,
  163.                               Msg, WParam, LParam ) ;
  164. end ;
  165.  
  166. procedure TSubclassedPlugin.WindowHandleChanging ;
  167. begin
  168.   inherited WindowHandleChanging ;
  169.  
  170.   { undo any previous subclassing }
  171.   if ( WindowHandle <> 0 ) and ( FDefPluginProc <> NIL ) then begin
  172.     UpdateWindow( Windows.GetParent( WindowHandle ) ) ;
  173.     SetWindowLong( WindowHandle, GWL_WNDPROC, longint( FDefPluginProc ) ) ;
  174.   end ;
  175.   FDefPluginProc := NIL ;
  176. end ;
  177.  
  178. procedure TSubclassedPlugin.WindowHandleChanged ;
  179. begin
  180.   { Navigator has given us a new window handle - subclass it. }
  181.   if WindowHandle <> 0 then begin
  182.     FDefPluginProc := pointer( GetWindowLong( WindowHandle, GWL_WNDPROC ) ) ;
  183.     SetWindowLong( WindowHandle, GWL_WNDPROC, longint( FObjectInstance ) ) ;
  184.   end ;
  185. end ;
  186.  
  187. end.
  188.