2013-02-25 70 views
0

我嘗試從Indy TCP服務器線程連接到(Uni)DDE服務器。 從正常的應用程序我可以連接,並可以獲取/設置任何PLC變量。德爾福:來自Indy TCPServer的DDE調用線程

但是,當我從Indy線程(從Execute(AThread:TIdPeerThread)事件)使用相同的命令時,SetLink命令失敗。

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; 

也許DDE正在使用Windows消息,或者其他東西不是線程安全的,或者在線程級別上不可捕獲?

感謝這方面有任何信息: DD

+0

你爲什麼要使用DDE? DDE是Win16的迴歸?! – Lloyd 2013-02-25 12:14:58

+0

我只有這個接口... :-((Unitronics) – durumdara 2013-02-25 12:18:11

回答

1

DDE是建立在Windows消息的頂部。您需要確保消息在具有DDE連接的線程上分派。

0

我知道這太晚了,但可能有人需要這條指令。我在這方面做了太多的工作。我有同樣的問題(但openlink方法,而不是設置鏈接方法。我用連接模式ddeManual不自動)。最後我發現了一些東西。 Delphi ddeMgr位於VCL單元中,需要像Synchronize(yourProcedure)一樣調用它。當我編寫另一個過程(該過程包括我所有的dde交互)和線程Execute方法時,我使用Synchronize調用了我的過程。 我的代碼看起來像這樣。

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; 

我希望這個信息幫助其他人:)