Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi In Konsolenanw. auf Firebird-Events reagieren? (https://www.delphipraxis.net/171974-konsolenanw-auf-firebird-events-reagieren.html)

RSE 5. Dez 2012 08:30

In Konsolenanw. auf Firebird-Events reagieren?
 
Hallo,

ich möchte eine kleine Konsolenanwendung schreiben, die auf Firebird-Events wartet und ein Script ausführt, wenn der Event eintritt. Als DB-Kompos verwende ich TIBCConnection und TIBCAlerter der IBDAC Komponentensammlung. In meiner GUI-Anwendung kann ich damit problemlos die Events empfangen, in der Konsolenanwendung nicht. Durch einen Blick in meine magische Glaskugel bin ich darauf gekommen, dass das daran liegen könnte, dass Konsolenanwendungen keine Messages empfangen.
  1. Könnte das der Grund sein?
  2. Wie könnte man das Problem lösen/umgehen (Ansatz reicht mir)
Natürlich könnte ich das einfach in eine GUI-App packen, aber ist das wirklich notwendig?

DeddyH 5. Dez 2012 08:54

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Ohne jetzt groß nachgedacht zu haben: kannst Du Dir nicht mit Delphi-Referenz durchsuchenAllocateHWnd einfach ein Botschaftsfenster erzeugen?

RSE 5. Dez 2012 11:05

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Könnt ich schon, aber wie soll mein Window dafür sorgen, dass der TIBCAlerter Messages empfängt? Ich weiß ja nicht mal was der als "Antwortadresse" angibt. Der Alerter registriert sich ja für Messages beim Firebird-Server, das heißt, dass der seine Antworten an irgendwen schicken muss. Ich halte es für unwahrscheinlich, dass der Alerter mein Fenster als "Antwortadresse" angibt.

Wenn man davon ausgeht, dass der Alerter sich die Messages an den aktuellen Thread kommen lässt, dann könnte ich eine Message-Queue für den Thread einrichten, indem ich einmal PeekMessage aufrufe. Aber wie bekomme ich dann die Message(s) an den Alerter? Da muss ich sicherlich irgendwas mit Dispatch aufrufen. Aber so konkret kenn ich mich damit nicht aus. Ich werde mal nach dem Mittag in den Quellen von TApplication stöbern und etwas experimentieren.

RSE 5. Dez 2012 12:28

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Also mit folgendem Konstrukt empfange ich schon mal den Event:
Delphi-Quellcode:
  repeat
    if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
    begin
      DispatchMessage(Msg);
    end
    else
      Sleep(0); // Rest der Zeitscheibe verwerfen
  until False;
Jetzt muss nur noch ein Abbruchkriterium her, damit ich nicht nur die Möglichkeit habe die Konsole zu schließen... Dazu werde ich mir jetzt http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx ansehen.

RSE 5. Dez 2012 13:02

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Wenn ich die Schleife folgendermaßen erweitere, dann kann ich das Programm zwar sauber beenden, aber dann bekomme ich die Events nicht mehr:
Delphi-Quellcode:
  repeat
    if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
      DispatchMessage(Msg)
    else
      if ReadConsole(GetStdHandle(STD_INPUT_HANDLE), @Key, 1, NumRead, nil) and
         (NumRead > 0) then
        Exit
      else
        Sleep(0); // Rest der Zeitscheibe verwerfen
  until False;
Kommentiere ich die Erweiterung wieder aus, dann bekomme ich die Events wieder. Was hat das eine mit dem anderen zu tun? :shock:

RSE 5. Dez 2012 14:49

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
ReadConsole hat tatsächlich gewartet, bis eine Eingabe erfolgt, bevor es zurückkehrt. Damit hat es natürlich den restlichen Programmablauf blockiert...
Die funktionierende Lösung ist die folgende:
Delphi-Quellcode:
procedure ProcessMessages;
var
  SIN: Cardinal;
  Num: Cardinal;
  IR: TInputRecord;
begin
  SIN := GetStdHandle(STD_INPUT_HANDLE);
  repeat
    if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
      DispatchMessage(Msg)
    else
    begin
      while PeekConsoleInput(SIN, IR, 1, Num) and (Num > 0) do
        if (IR.EventType = KEY_EVENT) and (IR.Event.KeyEvent.bKeyDown) then
          Exit
        else
          FlushConsoleInputBuffer(SIN); // sonst wird immer wieder der gleiche Puffer getestet und nie geleert;
      Sleep(0); // Rest der Zeitscheibe verwerfen
    end;
  until False;
end;

Medium 5. Dez 2012 15:46

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Manchmal hilft es einem schon, wenn man seine Ideen nur schriftlich dokumentiert :)

Danke, dass du dies hier getan hast! Sicherlich interessant für einige, und verallgemeinert könnte man daraus ggf. sogar einen schönen Code-Lib Eintrag machen: "Windows Messages in Konsolenanwendungen verarbeiten" o.ä.

RSE 5. Dez 2012 16:46

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Zitat:

Zitat von Medium (Beitrag 1194468)
Manchmal hilft es einem schon, wenn man seine Ideen nur schriftlich dokumentiert :)

Sehr richtig. Ich hatte schon Angst, dass jemand etwa sagen würde, weil ich mir ständig selbst geantwortet habe... :roll: Ich danke dir deshalb sehr für deinen Post! :-D

tsteinmaurer 5. Dez 2012 16:55

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
Ich mach das in einer Konsolenanwendung mit IBObjects einfach durch Attachen eines eigenes Event-Handlers für das entsprechende OnEventAlert Event der EventAlerter Komponente. Kann nicht sagen, ob das auch mit IBDAC funktionieren würde.

RSE 5. Dez 2012 17:43

AW: In Konsolenanw. auf Firebird-Events reagieren?
 
@tsteinmaurer: Wenn du meinen ersten Beitrag aufmerksam gelesen hättest, wüsstest du, dass ich genau das gleiche mit den IBDACs mache. Nur kommt der Event eben durch eine Windows-Message in dein Programm, und wenn die nie bei der Komponente ankommt, kann die den Event nicht auslösen. Und da eine Konsolenanwendung nicht von Haus aus eine Message-Schleife hat, musste ich die selbst bauen. Das wird bei dir mit den IBOs nicht anders laufen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz