Autor Beitrag
UweK
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 54
Erhaltene Danke: 1

Win 11
Delphi Enterprise XE6
BeitragVerfasst: Di 13.01.26 17:56 
Hallo allerseits,

Ich habe eine Frage zu einem Problem mit DDE. Ich weiß, dass das Verfahren veraltet ist, aber ich möchte ein ansonsten gutes altes Programm an dieser einen Problemstelle mit möglichst wenig Aufwand verbessern. Bitte schickt mir darum keine Vorschläge zu anderen Methoden der Kommunikation.

Mein Client verbindet sich mit dem Server so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
with MainDDEClientConv do

{Aktion nur ausführen, wenn das betreffende Serverprogramm läuft. Sonst käme Fehlermeldungsfenster: "D:\Verzeichnis\ControlDDEServerConv": File not found", das ich von Hand wegklicken muss.}
  if ProcessExists('MyControlProgram.exe'then
  begin
    SetLink('MyControlProgram''ControlDDEServerConv');
    OpenLink
    PokeDataLines('ControlDDEServerItem', TempStringList); // TempStringList: TStringList ist irgend ein Text
    CloseLink;
  end{if ProcessExists(}


Das funktioniert fast immer, außer wenn der Server gerade durch eine aufwendige Operation beschäftigt ist, z.B. eine 30 Sekunden lange Berechnung. Dieser seltene, aber mögliche Fall ist mein Problem. Denn wenn der Server beschäftigt ist, und dann offensichtlich nicht auf die Anfrage des Client sofort reagieren kann, erhalte ich vom Client genau dasselbe Fehlermeldungsfenster wie oben "File not found", obwohl der Prozess natürlich auch jetzt noch in Windows zu sehen ist.

Ich habe es mit einer Exception-Behandlung versucht:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
with MainDDEClientConv do

{Aktion nur ausführen, wenn das betreffende Serverprogramm läuft. Sonst käme Fehlermeldungsfenster: "D:\Verzeichnis\ControlDDEServerConv": File not found", das ich von Hand wegklicken muss.}
  if ProcessExists('MyControlProgram.exe'then
  begin
    try
      SetLink('MyControlProgram''ControlDDEServerConv');
      OpenLink
      PokeDataLines('ControlDDEServerItem', TempStringList); // TempStringList: TStringList ist irgend ein Text
      CloseLink;
    except
      on E: Exception do
// Nichts tun. Der Timer im Client wird diese Anfrage in ein paar Sekunden einfach wiederholen.
    end;
  end{if ProcessExists(}


Diese Exception-Behandlung bringt aber nichts. In der Delphi-Hilfe habe ich auch keinen Hinweis gefunden, ob diese DDE-Funktionen überhaupt Exceptions auslösen.

Mein Problem ist eigentlich nur das Fehlermeldungsfenster, denn das muss ich erst von Hand wegklicken, bevor der Client weitermacht und dann in ein paar Sekunden die Anfrage wiederholt. Ich bräuchte also vermutlich nichts weiter ändern, wenn ich eine Möglichkeit finde, dieses Fehlermeldungsfenster automatisch verschwinden, oder gar nicht erst entstehen zu lassen.

Über Tipps würde ich mich sehr freuen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19336
Erhaltene Danke: 1751

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 13.01.26 18:35 
Dein größtes Problem ist, dass du den Rückgabewert von OpenLink komplett ignorierst. Dadurch bekommst du gar nicht mit, wenn dieses aus den genannten Gründen fehlschlägt.

Die Dialoge kannst du mit aktuellen Delphiversionen wohl nicht direkt unterdrücken. Du kannst aber versuchen, ob du WM_DDE_ACK in der WndProc abfangen kannst. Aber ich bin nicht sicher, ob das bei dem Fehlerdialog kommt. Oder du setzt Hook auf WH_CALLWNDPROC und fängst dort WM_INITDIALOG ab. Dann kannst du dort prüfen, ob das ein solcher Fehlerdialog ist. Den Hook brauchst du, weil die Nachricht nicht an deine Anwendung geht, sondern an den fremden Dialog.

Leider wirst du bei DDE nicht um solche Workarounds herumkommen.

Die eigentliche Frage ist aber, warum dein Hauptthread so lange blockiert ist. Lange laufende Aufgaben gehören in Threads...