参考一下Timer控件,里面创建了一个没有窗口的句柄。为此,新建一个单元Unit2
LL中主动将句柄发送给B.EXE.unit Unit2;interfaceuses Classes, Windows, Messages, Forms, Consts,Dialogs,Sysutils;type TReadResult = record FileName: string[255]; MS: TmemoryStream; end; PReadResult = ^TReadResult; TTimerEx = class(TComponent) private FInterval: Cardinal; FWindowHandle: HWND; FOnTimer: TNotifyEvent; FEnabled: Boolean; procedure UpdateTimer; procedure SetEnabled(Value: Boolean); procedure SetInterval(Value: Cardinal); procedure SetOnTimer(Value: TNotifyEvent); procedure WndProc(var Msg: TMessage); protected procedure Timer; dynamic; procedure DoCopyMsg(Var Msg:TWMCopyData); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Enabled: Boolean read FEnabled write SetEnabled default True; property Interval: Cardinal read FInterval write SetInterval default 1000; property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer; property WinHandle: HWND read FWindowHandle; //新增加的,用于接收消息的句柄 end;implementation{ TTimerEx }constructor TTimerEx.Create(AOwner: TComponent);begin inherited Create(AOwner); FEnabled := True; FInterval := 1000;{$IFDEF MSWINDOWS} FWindowHandle := Classes.AllocateHWnd(WndProc);{$ENDIF}{$IFDEF LINUX} FWindowHandle := WinUtils.AllocateHWnd(WndProc);{$ENDIF}end;destructor TTimerEx.Destroy;begin FEnabled := False; UpdateTimer;{$IFDEF MSWINDOWS} Classes.DeallocateHWnd(FWindowHandle);{$ENDIF}{$IFDEF LINUX} WinUtils.DeallocateHWnd(FWindowHandle);{$ENDIF} inherited Destroy;end;procedure TTimerEx.WndProc(var Msg: TMessage);begin case Msg.Msg of WM_TIMER: try Timer; except Application.HandleException(Self); end; WM_COPYDATA: DoCopyMsg( TWMCopyData(Msg)); else Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam); end;end;procedure TTimerEx.UpdateTimer;begin KillTimer(FWindowHandle, 1); if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then if SeTTimer(FWindowHandle, 1, FInterval, nil) = 0 then raise EOutOfResources.Create(SNoTimers);end;procedure TTimerEx.SetEnabled(Value: Boolean);begin if Value <> FEnabled then begin FEnabled := Value; UpdateTimer; end;end;procedure TTimerEx.SetInterval(Value: Cardinal);begin if Value <> FInterval then begin FInterval := Value; UpdateTimer; end;end;procedure TTimerEx.SetOnTimer(Value: TNotifyEvent);begin FOnTimer := Value; UpdateTimer;end;procedure TTimerEx.Timer;var H: THandle;begin if Assigned(FOnTimer) then FOnTimer(Self); H := Windows.FindWindow(nil, 'B.exe的Caption'); if H<>nil then 发送消息给B程序,告知DLL中的Handle(Self.FWindowHandle)是多少。建议用 TCopyDataStruct.dwData参数表示类别(如1表示发送的是Handle,2表示发送的是TMyFileInfo)end;procedure TTimerEx.DoCopyMsg(var Msg: TWMCopyData);var t:TmemoryStream;begin if Msg.CopyDataStruct.dwData=2 then begin t:=PReadResult(Msg.CopyDataStruct.lpData).MS;// showmessage(inttostr(t.Size)); t.SaveToFile('D:/a.txt'); end;end;end.=========================主程序调用:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ExtCtrls, StdCtrls;type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementationuses Unit2;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);var Timer1: TTimerEx; t: PReadResult; DS: TCopyDataStruct;begin Timer1 := TTimerEx.Create(Self); new(t); t.MS := TmemoryStream.Create; t.MS.WriteComponent(Self); Ds.dwData := 2; Ds.cbData := Sizeof(t) + 1; Ds.lpData := t; SendMessage(Timer1.WinHandle, WM_COPYDATA, Application.Handle, Cardinal(@ds)); FreeMem(Ds.lpData);end;end.不过,接收到流后,对流进行的操作,不会反应到原始流上去。