SarusSystems
asked on
Delphi 7, DDE Client problem
I have a Delphi7 DDE client that talks do a 16 bit DDE server application.
This ran beautifully until recently. The 16 bit server is not mine so I have no
control over it.
When I try the openlink ( with the 16 bit server not running ( or modally busy ),
the D7 client freezes and I get an "application not responding" type message in
the Windows task manager.
(a timer running in the client application don't trigger ontimer events when this
happens)
If the 16 bit server IS running, everything works as expected.
Tried the code below but 16 bit server not seen with DDE.WaitStat (understandably)
procedure TForm1.mIRCDDE(Service, Topic, Cmd: string);
var
DDE: TDDEClientConv;
begin
try
DDE := TDDEClientConv.Create(nil) ;
DDE.ConnectMode := ddeManual;
DDE.SetLink(Service, Topic);
Timer1.Enabled := true; // for freeze test to see if ontimer event
works
If DDE.WaitStat then // If DDE server available //won't work with 16
bit server
begin
DDE.OpenLink
DDE.PokeData(Topic, PChar(Cmd));
end;
finally
DDE.Free;
end;
end;
I changed the code to
if DDE.OpenLink then
DDE.PokeData(Topic, PChar(Cmd));
finally
DDE.Free;
end;
Basically the application freezes on the openlink and stays frozen until terminated
with a three fingered salute. I tried wrapping the Openlink in a Try/except but it
stayed frozen. Eureka doesn't work either.
I need a timeout on the DDEOpenlink I guess. Any help greatly appreciated.
Thanks
This ran beautifully until recently. The 16 bit server is not mine so I have no
control over it.
When I try the openlink ( with the 16 bit server not running ( or modally busy ),
the D7 client freezes and I get an "application not responding" type message in
the Windows task manager.
(a timer running in the client application don't trigger ontimer events when this
happens)
If the 16 bit server IS running, everything works as expected.
Tried the code below but 16 bit server not seen with DDE.WaitStat (understandably)
procedure TForm1.mIRCDDE(Service, Topic, Cmd: string);
var
DDE: TDDEClientConv;
begin
try
DDE := TDDEClientConv.Create(nil)
DDE.ConnectMode := ddeManual;
DDE.SetLink(Service, Topic);
Timer1.Enabled := true; // for freeze test to see if ontimer event
works
If DDE.WaitStat then // If DDE server available //won't work with 16
bit server
begin
DDE.OpenLink
DDE.PokeData(Topic, PChar(Cmd));
end;
finally
DDE.Free;
end;
end;
I changed the code to
if DDE.OpenLink then
DDE.PokeData(Topic, PChar(Cmd));
finally
DDE.Free;
end;
Basically the application freezes on the openlink and stays frozen until terminated
with a three fingered salute. I tried wrapping the Openlink in a Try/except but it
stayed frozen. Eureka doesn't work either.
I need a timeout on the DDEOpenlink I guess. Any help greatly appreciated.
Thanks
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks.
>>I guess I'll have a big job finding the window handle of the 16 bit application
not sure about 16bit but:
procedure TForm1.Button1Click(Sender : TObject);
var tmpHWND: THandle;
pid: Cardinal;
wndtxt: array[0..MAX_PATH] of Char;
begin
pid := GetCurrentProcessId;
tmpHWND := FindWindow(nil, nil);
while tmpHWND <> 0 do begin
if GetParent(tmpHWND) = 0 then begin
if pid = GetHandlesPID(tmpHWND) then begin
GetWindowText(tmpHWND, wndtxt, MAX_PATH);
ShowMessage('found: ' + Trim(wndtxt));
end;
end;
tmpHWND := GetWindow(tmpHWND, GW_HWNDNEXT);
end;
end;
function TForm1.GetHandlesPID(AHand le: THandle): Cardinal;
begin
GetWindowThreadProcessId(A Handle, Result);
end;
just change pid := GetCurrentProcessId; to PID obtained by OpenProcess() on DDE server
ziolko.
not sure about 16bit but:
procedure TForm1.Button1Click(Sender
var tmpHWND: THandle;
pid: Cardinal;
wndtxt: array[0..MAX_PATH] of Char;
begin
pid := GetCurrentProcessId;
tmpHWND := FindWindow(nil, nil);
while tmpHWND <> 0 do begin
if GetParent(tmpHWND) = 0 then begin
if pid = GetHandlesPID(tmpHWND) then begin
GetWindowText(tmpHWND, wndtxt, MAX_PATH);
ShowMessage('found: ' + Trim(wndtxt));
end;
end;
tmpHWND := GetWindow(tmpHWND, GW_HWNDNEXT);
end;
end;
function TForm1.GetHandlesPID(AHand
begin
GetWindowThreadProcessId(A
end;
just change pid := GetCurrentProcessId; to PID obtained by OpenProcess() on DDE server
ziolko.
ASKER
It sounds very possible and a logical way forward. I'll look into it. Thanks