这是一个SHELL型钩子的DLL文件,用来显示用户打开和关闭的窗口。其中为了保存从调用此DLL的程序传递过来的数据比如调用此DLL的程序的窗口句柄,用一般的方法好像不行,如果从DLL中按数据(句柄)向窗口发送消息,但窗口收不到。我目前是用内存映射文件来保存的,好麻烦,不知有什么更好的办法?另外钩子函数起作用时,所打开的窗口均不能在任务栏上显示出任务按钮,但我用MASM32按同样的思路写却没有同样的问题。请大虾指点更简单的方法。 源程序如下://以下是DLL文件 
unit dll; interface uses 
  Windows, SysUtils, StdCtrls, Messages; function WinProc(nCode: integer; wParam: WPARAM; lParam: LPARAM):LRESULT; stdcall; export; 
function InstallHook(hHostWin: HWND): boolean; stdcall; export;//加载钩子 
function UninstallHook: boolean; stdcall; export;//卸载钩子 
procedure WinHookExit;far;export; 
//Procedure DLLMain(hInst: Longint; dwReason: DWord; reserved1: DWord); far; 
Procedure DLLMain(dwReason: DWord);far; 
Procedure MapMem; 
Procedure UnMapMem; var 
  hhk: hhook; 
  ProcSaveExit: Pointer; 
  hObject : THandle; 
  hwndHost: HWND; 
  pMem : Pointer; 
implementation function WinProc(ncode:integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;export; 
const 
  conWinCreate = 1; 
  conWinClose  = 2; 
  WM_WININFO = WM_USER + 6; begin 
  result := 0; 
  CallNextHookEx(hhk,ncode,wParam,lParam); 
  case ncode of 
     HSHELL_WINDOWCREATED: 
     begin 
       //messagebeep($FFFFFFFF); 
       //PostMessage(hwndHost, WM_WININFO, wParam, conWinCreate); 
       PostMessage(HWND(pMem^), WM_WININFO, wParam, conWinCreate); 
     end; 
     HSHELL_WINDOWDESTROYED: 
     begin 
       //messagebeep($FFFFFFFF); 
       //postMessage(hwndHost, WM_WININFO, wParam, conWinClose); 
       postMessage(HWND(pMem^), WM_WININFO, wParam, conWinClose); 
     end; 
  end; 
end; function InstallHook(hHostWin:HWND): boolean; 
begin 
  if hhk = 0 then 
  begin 
     hhk:=SetWindowsHookEx(WH_SHELL, WinProc, hinstance, 0); 
     //HWND(pMem)hwndHost := hHostWin; 
     HWND(pMem^) := hHostWin; 
  end; 
  result:= hhk <> 0; 
end; function UninstallHook: boolean; 
begin 
  if hhk <> 0 then 
  begin 
    if UnHookWindowsHookEx(hhk) then  hhk := 0; 
  end; 
  result:=hhk=0; 
end; procedure WinHookExit;far; 
begin 
  UninstallHook; 
  ExitProc:=ProcSaveExit; 
end; 
//Procedure DLLMain(hInst: Longint; dwReason: DWord; reserved1:DWord); 
Procedure DLLMain(dwReason: DWord); 
begin 
  Case dwReason of 
    DLL_PROCESS_ATTACH: 
    begin 
        pMem := nil; 
        hObject := hInstance;//0; 
        MapMem;//以下的公有数据,如tHWND,tMessageID将直接使用本Buf. 
    end; 
    DLL_PROCESS_DETACH: UnMapMem; 
    DLL_THREAD_ATTACH, DLL_THREAD_DETACH://缺省 
  end; 
  //result := TRUE; 
end; Procedure UnMapMem; 
begin 
  if Assigned(pMem) then 
  begin 
    UnMapViewOfFile(pMem); 
    pMem := Nil ; 
  end; 
end; Procedure MapMem; 
begin 
  hObject := CreateFileMapping($FFFFFFFF,Nil,Page_ReadWrite,0,$FFFF, 
     pChar('_IOBuffer')); 
  if hObject = 0 then 
    Raise Exception.Create('创建公用数据的Buffer不成功!'); 
  pMem :=MapViewOfFile(hObject,FILE_MAP_WRITE,0,0,SizeOf(hwndHost)); 
  // ;1 ;or ;SizeOf(DataBuf) ;???? ;// 创建SizeOf(DataBuf)的数据区 
  if not Assigned(pMem) then 
  begin 
    UnMapMem; 
    Raise Exception.Create('创建公用数据的映射关系不成功!')    ; 
  end; 
end; end. 
//以下调用上面的DLL的应用程序 
unit testform; interface uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  StdCtrls,TLHelp32; const 
  WM_WININFO = WM_USER + 6; 
  conCreateWin  = 1; 
  conDestroyWin = 2; type 
  TForm1 = class(TForm) 
    btnInstallHook: TButton; 
    lblMessage: TLabel; 
    procedure btnInstallHookClick(Sender: TObject); 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
  private 
    { Private declarations } 
    procedure WinMessage(var WinMsg:Tmessage); message WM_WININFO; 
  public 
    { Public declarations } 
 end; var 
  Form1: TForm1; 
  bIntalledHook: boolean = false; 
implementation {$R *.DFM} function InstallHook(hClientWin:HWND): boolean; stdcall; external 'shellhook.dll'; function UninstallHook:boolean;stdcall;external 'shellhook.dll'; procedure TForm1.btnInstallHookClick(Sender: TObject); 
begin 
  if bIntalledHook then      if UninstallHook then 
     begin 
        bIntalledHook := false; 
        lblMessage.Caption := ''; 
        btnInstallHook.Caption:= 'InstallHook' 
     end 
     else 
        MessageBox(Form1.Handle, 'ErrUNinstallHook','', Mb_OK + MB_ICONERROR)   else      if InstallHook(Form1.Handle) then 
     begin 
        bIntalledHook := true; 
        btnInstallHook.Caption := 'UninstallHook' 
     end 
     else 
        MessageBox(Form1.Handle, 'ErrInstallHook','', Mb_OK + MB_ICONERROR) end; procedure Tform1.WinMessage(var WinMsg:Tmessage); 
var 
  pWinTitle:Pchar; 
  TitleLen:Integer; 
  clp:bool; 
  WinProcID:DWORD; 
  fp32:tprocessentry32; 
  fshandle:thandle; 
begin 
  with lblMessage do 
  begin 
    if WinMsg.lParam=1 then 
    begin 
      Caption:=' Open '; 
      sleep(5); 
    end 
    else Caption:=' Close '; 
    GetWindowThreadProcessId(WinMsg.wParam,@WinProcID); 
    fshandle:=CreateToolhelp32Snapshot(th32cs_snapprocess,0); 
    fp32.dwsize:=sizeof(fp32); 
    clp:=process32first(fshandle,fp32); 
    while (integer(clp)<>0) and (fp32.th32processid<>WinProcId) do 
    begin 
      clp:=process32next(fshandle,fp32); 
    end; 
    closehandle(fshandle); 
    TitleLen:=GetWindowTextLength(WinMsg.wParam)+2; 
    GetMem(pWinTitle,TitleLen); 
    GetWindowText(WinMsg.wParam,pWinTitle,TitleLen); 
    Caption:=DateTimeToStr(Now)+Caption+fp32.szexefile+' '+pWinTitle; 
    if TitleLen > 0 then FreeMem(pWinTitle); 
  end; 
  { 
  ShowWindow(WinMsg.wParam,SW_HIDE); 
  ShowWindow(WinMsg.wParam,SW_SHOWNORMAL); 
  SetForegroundWindow(WinMsg.wParam); 
  } 
end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
  if bIntalledHook then UninstallHook; 
end; end.