1

我试图向我的 Delphi 应用程序发送一条 Windows 消息,但我的FindWindow方法有问题:我从方法中获取错误 id 为 0 GetLastError。我正在运行 Vista,据我所知,此错误在 XP 或更早版本中很常见,但在 Vista 或 Win 7 中应该可以正常工作(也许我误解了?)。

这是我使用的代码及其在 Delphi DLL 文件中,用 Delphi 5 编写:

procedure SendData(const copyDataStruct: TCopyDataStruct) ;
var
   receiverHandle : THandle;
   res : integer;
begin
   receiverHandle := FindWindow(PChar('TMainForm'),PChar('MainForm')) ;
   if receiverHandle = 0 then
   begin
   ShowMessage(format('Error %x finding MainForm',
    [GetLastError()]));
     Exit;
   end;

   res := SendMessage(receiverHandle, WM_COPYDATA, Integer(receiverHandle), Integer(@copyDataStruct)) ;
end;
4

2 回答 2

1

根据系统错误代码列表,error 0 表示“ ERROR_SUCCESS ”。

可能是您的 Window 属于 class TMainWindow,但有一个空的 Caption 吗?

请参阅当 lpWindowName 参数为非空时FindWindow内部使用的GetWindowText的备注(这种情况:您通过那里)。MainWindow

——杰伦

于 2010-10-05T10:23:02.010 回答
0

向所有窗口广播自定义消息。只有您的窗口知道如何对它做出反应。然后它可以在另一条消息中回复其当前的 HWND,因此广播公司不必手动寻找它。使用 RegisterWindowMessage() 注册其他应用程序将忽略的唯一消息 ID。例如:

应用 1:

var
  WM_WHERE_ARE_YOU: UINT = 0;
  WM_HERE_I_AM: UINT = 0;
  App2Wnd: HWND = 0;

procedure TApp1Form.FromCreate(Sender: TObject);
begin
  // use whatever string names you want, as long as they match App 2...
  WM_WHERE_ARE_YOU := RegisterWindowMessage("WhereAreYou");
  WM_HERE_I_AM := RegisterWindowMessage("HereIAm");
end;

procedure TApp1Form.WndProc(var Message: TMessage);
begin
  if (Message.Msg = WM_HERE_I_AM) and (WM_HERE_I_AM <> 0) then
    App2Wnd := HWND(Message.LParam)
  else
    inherited;
end;

procedure TApp1Form.SendData(const copyDataStruct: TCopyDataStruct);
var 
  res : integer; 

  procedure FindApp2Window;
  var
    Ignore: DWORD;
  begin
    App2Wnd := 0;
    if WM_WHERE_ARE_YOU = 0 then Exit;
    SendMessageTimeout(HWND_BROADCAST, WM_WHERE_ARE_YOU, 0, Longint(Self.Handle), SMTO_NORMAL, 500, Ignore);
    if App2Wnd = 0 then Application.ProcessMessages;
  end;

begin 
   FindApp2Window; 
   if App2Wnd = 0 then 
   begin 
     ShowMessage(Format('Unable to find MainForm');
     Exit; 
   end; 
   res := SendMessage(App2Wnd, WM_COPYDATA, Longint(Self.Handle), Longint(@copyDataStruct));
   ...
end;

应用 2:

var
  WM_WHERE_ARE_YOU: UINT = 0;
  WM_HERE_I_AM: UINT = 0;

procedure TApp2Form.FromCreate(Sender: TObject);
begin
  // use whatever string names you want, as long as they match App 1...
  WM_WHERE_ARE_YOU := RegisterWindowMessage("WhereAreYou");
  WM_HERE_I_AM := RegisterWindowMessage("HereIAm");
end;

procedure TApp2Form.WndProc(var Message: TMessage);
begin
  case Message.Msg of
    WM_COPYDATA:
    begin
      if PCopyDataStruct(Message.LParam)^.dwData = ... then
      begin
        ...
        Message.Result := 1;
        Exit;
      end;
    end;
    ...
  else
    if (Message.Msg = WM_WHERE_ARE_YOU) and (WM_WHERE_ARE_YOU <> 0) then
    begin
      if WM_HERE_I_AM <> 0 then
        PostMessage(HWND(Message.LParam), WM_HERE_I_AM, 0, Longint(Self.Handle));
      Exit;
    end;
  end;

  inherited;
end;
于 2010-10-06T20:59:37.820 回答