从 Windows 方法获取错误 ID:0:FindWindow

发布于 2024-09-26 03:03:09 字数 708 浏览 0 评论 0原文

我正在尝试向我的 Delphi 应用程序发送 Windows 消息,但我在使用 FindWindow 方法时遇到问题: 我从 GetLastError 方法获取错误 ID 0。 我正在运行 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;

im trying to send a Windows message to my Delphi application, but im having problems with the FindWindow method:
im getting error id of 0 from the GetLastError method.
Im running Vista and from what ive read this error is common in XP or earlier versions, but should work fine in Vista or Win 7 (maybe i misunderstood ?).

This is the code im using and its in a Delphi DLL file, written in 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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黄昏下泛黄的笔记 2024-10-03 03:03:09

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

是否您的窗口属于 TMainWindow 类,但有一个空的标题?

请参阅 GetWindowText 的备注,即当 lpWindowName 参数为非空(就是这种情况:您将 MainWindow 传递到那里)。

——杰罗恩

According to the system error codes list, error 0 means "ERROR_SUCCESS".

Could it be that your Window is of class TMainWindow, but has an empty Caption?

See the remarks for GetWindowText that is internally used by FindWindow when the lpWindowName parameter is non-null (which is the case: you pass MainWindow there).

--jeroen

初见终念 2024-10-03 03:03:09

向所有窗口广播自定义消息。只有您的窗口知道如何对此做出反应。然后,它可以在另一条消息中回复其当前的 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;

Broadcast a custom message to all windows. Only your window will know how to react to it. It can then reply with its current HWND in another message so the broadcaster does not have to hunt for it manually. Use RegisterWindowMessage() to register unique message IDs that other apps will ignore. For example:

App 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;

App 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文