AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Init, Timer läuft nicht an

Ein Thema von schwa226 · begonnen am 12. Apr 2010 · letzter Beitrag vom 27. Apr 2010
Antwort Antwort
Seite 1 von 3  1 23      
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#1

DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 19:08
Hi,

ich habe eine DLL gemacht, die beim Init eine Form erzeugt und einen Timer startet:
Delphi-Quellcode:
function InitDLL(Callback : TCallback):Boolean; stdcall;
begin
      try
        //plugin gets loaded, create Form
        if Not Assigned(frMain) then
          frMain := TfrMain.Create(NIL);

        frMain.AddLog('plugin got init');

        //start startupdelay
        frMain.StartStartUpDelay(StartDelay);

      finally
        Result := Assigned(frMain);
      end;
    end;
end;

procedure TfrMain.StartStartUpDelay(Interval:Integer);
begin
  //start startup delay
  StartUpDelay.Interval := Interval;
  StartUpDelay.Enabled := True;
end;
Wenn die DLL nun von eine Test-VCL Form von Delphi geladen wird und das Init aufgerufen wird, wird das Timer Event von StartUpDelay ausgelöst.

Wenn die DLL aber von einer C-Console-App (VS2008) geladen wird, wird das Timer Event nicht ausgelöst!?
Erst wenn ich die Form anzeige wird das Event ausgelöst:
Delphi-Quellcode:
procedure ShowForm();
begin
  if Assigned(frMain) then
  begin
    frMain.ShowModal;
  end;
end;
Sobald Showmodal aufgerufen wird spingt der Code in die StartUpDelay Timer Routine.

Woran kann das liegen?
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.116 Beiträge
 
Delphi 12 Athens
 
#2

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 19:28
Darum nutzt man keine VCL in einer DLL.

- der Timer wird über die VCL gesteuert
- in deiner DLL hast du keine Nachrichtenbehandlung (Windows-Messages) eingebaut
- die Nachrichtenschleife der EXE behandelt alle Nachichten und leitet sie an die DLL weiter
- eine C-EXE hat zwar (vermutlich) eine Nachrichtenschleife, aber diese behandelt garantiert keine Delphi-Ereignisse

Wenn unbedingt VCL in DLL,
- dann erstelle und behandle diese in einem eigenem Thread und arbeite in diesem Thread die Nachrichten ab
- und es darf keine Interation zwischen den beiden VCLs (EXE und DLL) geben, denn die VCL ist nicht threadsicher
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 19:50
Zitat von himitsu:
Darum nutzt man keine VCL in einer DLL.

- der Timer wird über die VCL gesteuert
- in deiner DLL hast du keine Nachrichtenbehandlung (Windows-Messages) eingebaut
- die Nachrichtenschleife der EXE behandelt alle Nachichten und leitet sie an die DLL weiter
- eine C-EXE hat zwar (vermutlich) eine Nachrichtenschleife, aber diese behandelt garantiert keine Delphi-Ereignisse
Dann kläre ich mal auf.
- Es gibt in diesem Fall absolut nichts verwerfliches daran in diesem Fall die VCL in der DLL zu verwenden.
- Das der Timer über die VCL gesteuert wird ist nur bedingt richtig. Der Timer ist wohl Teil der VCL (je nach dem wie man VCL definiert) aber letztendlich wird er über das Windows-Nachrichtensystem gesteuert.
- Das die Nachrichtenschleife der Exe alle Nachrichten behandelt und diese an die DLL weiter leitet ist nur bedingt richtig. Eine Nachrichtenschleife behandelt alle Nachrichten des Threads in der die Schleife läuft. Da der Timer im Kontext des Hauptthreads der Exe erstellt wurde, werden die Nachrichten aller Fenster (und nichts anderes empfängt die Timernachrichten in der Timerklasse) dieses Threads, inklusive derer aus der DLL verarbeitet. Ebenso würde aber auch eine Nachrichtenschleife innerhalb der DLL die Nachrichten für die Fenster in der EXE verarbeiten sofern diese im gleichen Threadkontext laufen.
- Eine Nachrichtenschleife in einem C-Programm verarbeitet garantiert auch die Nachrichten welche für Fenster sind die aus Programmen/Programmteilen anderer programmiersprachlicher Herkunft sind.
Die Begründung warum es nicht funktioniert liegt hierin:
Zitat von schwa226:
Wenn die DLL aber von einer C-Console-App (VS2008) geladen wird
Es handelt sich also um eine Konsolenanwendung wie sie auch mit Delphi erstellt werden kann. Und in einer Konsolenanwendung wird in der Regel keine Nachrichtenschleife verwendet weswegen die Nachrichten für den Timer nicht verarbeitet werden. Die verwendete Programmiersprache ist da völlig egal da das Nachrichtensystem auf Windows beruht und nichts spezifisches einer bestimmten Programmiersprache ist.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.116 Beiträge
 
Delphi 12 Athens
 
#4

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 19:55
Es gibt aber auch eine Menge delphieigener Messages, welche direkt in Delphis Nachrichtenschleife behandelt werden
und Solche werden nicht von einer "fremden" Nachrichtenschleife behandelt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#5

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 19:58
Hast du dich mal mit Nachrichtenschleifen beschäftigt? Zumindest alle Punkt die ich von dir zitiert habe trafen in diesem konkreten Beispiel nicht zu. Und dem Fragesteller ging es nicht darum was allgemein irgendwann mal sein kann sondern er wollte wissen warum im konkreten Fall der Timer seinen Dienst nicht verrichtet. Und da waren die von dir genannten Punkte schlichtweg falsch.

Aber auch die letzte Aussage würde ich so nicht stehen lassen. Ich bin der Meinung (bin mir hier aber nicht zu 100% sicher) das nicht die Nachrichtenschleife spezielle Messages verarbeitet. Vielmehr holt die Nachrichtenschleife nur die Nachrichten aus der Nachrichtenwarteschlange ab und leitet diese durch den Aufruf von Windowsfunktionen an die entsprechende registrierten Nachrichtenfunktionen weiter.

So sieht übrigens eine Nachrichtenschleife in C aus:
Code:
while (GetMessage(&Message, NULL, 0,0))
{
    TranslateMessage(&Message);
    DispatchMessage(&Message);
}
In Delphi sieht sie übrigens nicht groß anders aus. Es werden die gleichen Funktionen aufgerufen. Rein der Syntax der Programmiersprache unterscheidet sich.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#6

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 20:07
Danke euch beiden erst einmal!

Gibt es zu dem Thread/Message abarbeiten ein Beispiel.

Werde warscheinlich im Thread mit GetMessage ein Polling machen müssen und die WM_TIMER dann per PostMessage an mein HWND weiterleiten!?
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.116 Beiträge
 
Delphi 12 Athens
 
#7

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 20:07
Zitat von SirThornberry:
In Delphi sieht sie übrigens nicht groß anders aus.
Bei NonVCL-Programmen schon, aber für die VCL ....

Delphi-Quellcode:
var
  Msg: TMsg;
begin
  while ProcessMessage(Msg) do {loop};



function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
  Handled: Boolean;
  Unicode: Boolean;
  MsgExists: Boolean;
begin
  Result := False;

  MsgExists := PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);

  if MsgExists or PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
  begin
    Unicode := (Msg.hwnd = 0) or IsWindowUnicode(Msg.hwnd);

    if not MsgExists then
    begin
      if Unicode then
        MsgExists := PeekMessageW(Msg, 0, 0, 0, PM_REMOVE)
      else
        MsgExists := PeekMessageA(Msg, 0, 0, 0, PM_REMOVE);
    end;

    if MsgExists then
    begin
      Result := True;
      if Msg.Message <> WM_QUIT then
      begin
        Handled := False;
        if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
        if not IsPreProcessMessage(Msg) and not IsHintMsg(Msg) and
          not Handled and not IsMDIMsg(Msg) and
          not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
        begin
          TranslateMessage(Msg);
          if Unicode then
            DispatchMessageW(Msg)
          else
            DispatchMessageA(Msg);
        end;
      end
      else
      begin
  {$IF DEFINED(CLR)}
        if Assigned(FOnShutDown) then FOnShutDown(self);
        DoneApplication;
  {$IFEND}
        FTerminate := True;
      end;
    end;
  end;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 20:15
Sorry, aber auch da sehe ich keine wirkliche Sonderbehandlung. Es wird die Message lediglich für das Application-Object etc. bereit gestellt. Aber eine besondere Behandlung einzelner Messages sehe ich hier nicht. Aber das ist auch egal. Mir ging es nur darum einige Aussagen richtig zu stellen damit der Fragestellende nicht den Eindruck bekommt wirklich alles falsch gemacht zu haben wenn im konkreten Fall der einzige "Fehler" ist keine Nachrichtenschleife zu haben.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.116 Beiträge
 
Delphi 12 Athens
 
#9

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 20:33
Für den Timer selber könnten diese Befehle entscheidend sein ... man weiß ja nicht was da intern noch alles passiert.
Delphi-Quellcode:
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsPreProcessMessage(Msg) and ...
  and not Handled
Und dann wird der Timer nicht einzeln verwaltet.
Ein Timer ohne Form/Owner muß nicht das Selbe sein, wie Einer mit Form/Owner ... hier kann es auch sein, daß schon bei dessen Erstellung etwas schief läuft, also z.B. wärend die Form erstellt/verwaltet wird.

Der Code vom TTimer selber ist noch relativ primitiv und dürfte so vermutlich auch in der C-Nachrichtenschleife behandelt werden, aber das TComponent hinter dem TTimer verbirgt 'ne Menge unberechenbaren VCL-Code.


Wie gesagt, der einfachste und sicherste Weg die VCL innerhalb einer "autonomen" DLL zu verwalten,
wäre diese VCL in einem separaten Thread und mit eigener Nachrichtenschleife laufen zu lassen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#10

Re: DLL Init, Timer läuft nicht an

  Alt 12. Apr 2010, 21:27
Zitat:
Wie gesagt, der einfachste und sicherste Weg die VCL innerhalb einer "autonomen" DLL zu verwalten,
wäre diese VCL in einem separaten Thread und mit eigener Nachrichtenschleife laufen zu lassen.
Also beim laden der DLL einen Thread erzeugen, der dann die Form erzeugt?
Im Execute vom Thread dann wie am besten die Nachrichten abarbeiten?

Tut leid, aber ich steh momentan voll auf dem Schlauch...

Danke!
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:32 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