Getting error id: 0 from Windows method: FindWindow
-
27-09-2019 - |
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;
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;