Question

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;
Was it helpful?

Solution

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

OTHER TIPS

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top