问题
I try to connect to (Uni)DDE server from an Indy TCP Server thread. From normal application I can connect, and can get/set any PLC variables.
But when I use same command from Indy thread (from Execute(AThread: TIdPeerThread) event), the SetLink command failed.
procedure ReadDDE(AppPath, Service, Topic, Cmd: string; out Eredmeny : string; out HibaSzint : string);
var
DDE: TDDEClientConv;
pc : PChar;
begin
Eredmeny := '';
HibaSzint := '';
DDE := TDDEClientConv.Create(nil);
try
DDE.ConnectMode := ddeAutomatic;
DDE.ServiceApplication := AppPath;
DDE.FormatChars := False;
HibaSzint := 'SetLink';
if DDE.SetLink(Service, Topic) then begin
HibaSzint := '';
pc := DDE.RequestData(PChar(Cmd));
Eredmeny := StrPas(pc);
StrDispose(pc);
end;
finally
DDE.Free;
end;
end;
Maybe the DDE is using Windows messages, or other things are not threadsafe, or not catchable in the thread's level?
Thanks for any info about this: dd
回答1:
DDE is built on top of windows messages. You need to make sure that messages are dispatched on the thread that has the DDE connection.
回答2:
I know it is too late but may be someone need this instruction. I have worked too many works on it. I have the same problem (but openlink method, not on Set Link method. I used connection mode ddeManual not automatic).At last I found something. Delphi ddeMgr is in the VCL Unit and it needs to be called in like Synchronize(yourProcedure). When I write another procedure (that procedure include my all dde interactions) and in the threads Execute method, I called my procedure with Synchronize. My code look like this.
procedure TAskYTSThread.MakeDDEConv;
begin
with TDDEClientConv.Create(Form1) do
begin
ConnectMode:=ddeManual;
ServiceApplication:='explorer.exe';
SetLink('Folders', 'AppProperties') ;
Form1.Memo1.Lines.Add('Openlink çağrılacak Gönderilecek.');
if OpenLink then
begin
Form1.Memo1.Lines.Add('Link Open Edildi.');
ExecuteMacro('[FindFolder(, C:\)]', False) ;
CloseLink;
end
else
begin
Form1.Memo1.Lines.Add('OLMADIIIIIII');
end;
Free;
end;
end;
procedure TAskYTSThread.Execute;
var
blnRunning : boolean ;
FYtsTopicName, strMacro : string ;
begin
inherited;
FDDE_BUSY.Enter ;
try
blnRunning := IsYTSRunning;
Synchronize(MakeDDEConv); // this is key point
finally
FDDE_BUSY.Leave ;
end;
end;
I wish this information help other people :)
来源:https://stackoverflow.com/questions/15066705/delphi-dde-call-from-indy-tcpserver-thread