Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   TTimer in DLL (https://www.delphipraxis.net/214050-ttimer-dll.html)

himitsu 9. Nov 2023 15:57

TTimer in DLL
 
n'Abend,

so richtig befriedigen mich gefundene Antworten nicht.

https://stackoverflow.com/questions/...er-not-working
http://www.delphigroups.info/2/be/406364.html
https://www.delphipraxis.net/69322-t...e-comctrl.html
und Vieles mehr, auch in anderen Sprachen
Bei Google suchenTTimer DLL

Bei einem TTimer innerhalb einer DLL wird das OnTimer nicht ausgelöst, warum?

* Ja, TTimer nutzt ein eigenes Form (AllocHWnd) und darin einen Timer mit ID 1.
* SetTimer kann man mit einem Callback nutzen, und man kann sich eine freie ID geben lassen, aber im Callcack fehlt mir dann die Beziehung zu meinen Daten/Objekt.
* * also müsste ich auch noch eine Liste mit IDs führen, zusammen mit dem eigentlich gemeinten

ABER, mein Timer, bzw. das interne CreateWindow, wird im Hauptthread der EXE ausgegührt, also sollte somit eigentlich in dessen Thread laufen und demnach auch von dessen MessageLoop verarbeitet werden. :gruebel:

Da die "virtuellen" WM_TIMER (die nicht wirklich in die Message-Queue geschrieben werden) innerhalb des GetMessage/PeekMessage generiert und sofort verarbeitet werden, ist der VCL-Code drumrum eigentlich egal.



Ja ja, vermutlich muß ich meinen Code eh auf Threads umbauen, weil es bei Verwendung dieser API eventuell zu Deadlocks kommen könnte, in seltenen Fällen,
aber zum Debuggen und um erstmal zu schauen, ob ich den anderen Rest zum Laufen bringen kann (und nicht eh alles umsonst wäre) ..................

Neutral General 9. Nov 2023 16:11

AW: TTimer in DLL
 
Ich hab leider keine Antwort auf die Frage, aber wie du schon gesagt hast:
Ich würde TTimer nicht in einer DLL nutzen, auch wenn dus irgendwie hinkriegst.
Benutz lieber einfach nen Thread.

himitsu 9. Nov 2023 16:42

AW: TTimer in DLL
 
Beim Thread weiß ich noch nicht, ob ich auch das Schreiben in einen/diesen Thread legen muß, oder ob das Lesen ausreicht,
und wenn, ob Lesen und Schreiben der beiden I/O-Pipes im selben Thread sein müssen
und
und
und


Weiß also noch garnicht was wie in den Thread muß,
drumm dachte ich das erstmal so "lassen" zu können.

Dachte bisher, dass noch keine Daten rein kommen, weil der externe Aufruf noch nicht klappte und nicht weil das ReadFile nie aufgerufen wurde. :stupid:

KodeZwerg 9. Nov 2023 17:43

AW: TTimer in DLL
 
Nutz doch die Windows Api CreateTimerQueueTimer()

jaenicke 9. Nov 2023 18:04

AW: TTimer in DLL
 
Wenn es eine eigene DLL und eine eigene Hostanwendung ist, ist die Sache doch sehr einfach:
Schreibe einfach ein ITimer Interface und hole dir das aus der Hostanwendung (z.B. mit meinem AppCentral Projekt). Dann hast du keinerlei Probleme.

himitsu 9. Nov 2023 18:28

AW: TTimer in DLL
 
Aktuell eine eigene DLL und eigene Anwendung,
aber per se ist es so vorgesehen, dass sie auch von anderen Anwendungen verwendet werden kann.

jaenicke 9. Nov 2023 18:40

AW: TTimer in DLL
 
Also ich habe es gerade ausprobiert (Delphi 11.3)...
Formular in DLL erstellt, TTimer drauf, Formular zwischen begin und end des Projektquelltextes (beim Laden der DLL) erzeugt (Visible nicht auf True gesetzt, kein Show aufgerufen), es funktioniert.

himitsu 10. Nov 2023 08:42

AW: TTimer in DLL
 
Ahhhhhhh, du willst es nich wissen.

Die alte CMD-Console war synchron, aber die neue Pseudo-Console ist asynchron,
da ich die Steuerbefehle noch nicht alle kenne, weiß ich noch nicht, wie ich auf's Ende des SubProzesses warten muß (weil da nichts in der Doku gefunden), also ist nach dem WriteFile noch keine Wartefunktion

leider ist das Prozessdesign für Einzelbefehle (ohne explizites Open) so, dass sofort das Close kam und der Timer und Handle freigegeben wurden. :wall:


Da es Vieles zu "Timer in DLL geht nicht" zu finden gab, hatte ich erstmal dort gesucht. :duck:


Delphi-Quellcode:
procedure TConsoleScript.ConsoleOutputTimer(Sender: TObject);
var
  Count: DWORD;
  Buffer: UTF8String;
begin
  if PeekNamedPipe(FOutputRead, nil, 0, nil, @Count, nil) and (Count > 0) then begin
    SetLength(Buffer, Count);
    ReadFile(FOutputRead, PAnsiChar(Buffer)^, Count, Count, nil);
    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), PAnsiChar(Buffer)^, Count, Count, nil);
  end;
end;
Jetzt wird das aufgerufen :firejump:

Mußte aber noch das
Delphi-Quellcode:
and (Count > 0)
anhängen, da selbst ein ReadFile mit Count=0 blockierend wartet, bis neue Daten rein kommen (von denen man aber "nichts" haben will)




PS: Im Prinzip ist die neue Console jetzt wieder fast so, wie früher unter DOS, also mit Escape-Befehlen im Stream, anstatt parallel mit zusätzlichen APIs (es gibt nur noch einen dritten Befehl, um die Größe des Fensters/Ausgabebereichs zu ändern).
Sowie es gibt "eigentlich" keinen StdErr, der ist farblich im StdOut mit drin.
Delphi-Quellcode:
function CreatePseudoConsole(size: COORD; hInput, hOutput: THandle; dwFlags: DWORD; out phPC: HPCON): HRESULT; stdcall;
function ResizePseudoConsole(hPC: HPCON; size: COORD): HRESULT; stdcall;
procedure ClosePseudoConsole(hPC: HPCON); stdcall;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:42 Uhr.

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