Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DLL Init, Timer läuft nicht an (https://www.delphipraxis.net/150287-dll-init-timer-laeuft-nicht.html)

SirThornberry 12. Apr 2010 21:36

Re: DLL Init, Timer läuft nicht an
 
Der Timer funktioniert nur mit Nachrichtenschleife. Diese wird unter anderem ausgeführt bei einem YourForm.ShowModal. Damit der Timer wie gewünscht funktioniert brauchst du also eine Nachrichtenschleife.
Himitsus Vorschlag verstehe ich wie folgt. Erstelle im C-Programm einen Thread. Dieser Thread startet/lädt die Dll und innerhalb der DLL lässt du dann auch die Nachrichtenschleife laufen.

himitsu 12. Apr 2010 21:43

Re: DLL Init, Timer läuft nicht an
 
Zitat:

Zitat von schwa226
Also beim laden der DLL einen Thread erzeugen, der dann die Form erzeugt?

jupp


Wenn die DLL geladen/initialisiert wird, innerhalb der DLL einen Thread erzeugen,
darin die Form erstellen und dann einfach ein

(im Thread.Execute)
Delphi-Quellcode:
MyForm := TMyForm.Create(nil);
try
  while not Terminated do //while aktiv{oder "not Beenden"} do
  begin
    Application.ProcessMessages;
    Sleep(10);
  end;
finally
  MyForm.Free;
end;
Und nicht vergessen Zugriffe auf diese VCL unbedingt mit diesem Thread zu syncronisieren.

SirThornberry 12. Apr 2010 21:52

Re: DLL Init, Timer läuft nicht an
 
Ich glaube so wird das nicht funktionieren. Wie du bereits angemerkt hast ist die VCL nicht Threadsave. Und das heißt konkret das die VCL (Application.ProcessMessage etc.) nur ordentlich arbeitet wenn es in dem Thread arbeitet in dem das Modul geladen wurde. Der Thread muss also außerhalb der DLL erstellt werden so dass, das Application-Object und die Initialization-Abschnitte innerhalb der DLL bereits in diesem Thread ausgeführt werden (oder mit anderen Worten: Die DLL darf muss "denken" das sie im einzigen Thread läuft)

schwa226 12. Apr 2010 22:18

Re: DLL Init, Timer läuft nicht an
 
Es geht!

Delphi-Quellcode:
procedure TMainThread.Execute;
begin
  try
    //plugin gets loaded, create Form
    if Not Assigned(frMain) then
      frMain := TfrMain.Create(NIL);

    //start startupdelay
    frMain.StartStartUpDelay(StartDelay);

  while not Terminated do //while aktiv{oder "not Beenden"} do
  begin
    if frMain.StartUpDelay.Enabled then
      Application.ProcessMessages;
    Sleep(1); //fix 100% cpu bug
  end;
  finally
    if Assigned(frMain) then
      FreeAndNil(frMain);
  end;
end;
Das ProcessMessages lasse ich aber nach dem Startup Delay wieder aus.

Danke!

Medium 12. Apr 2010 22:19

Re: DLL Init, Timer läuft nicht an
 
Das ganze Gekrampfe spart man sich, wenn man einfach per Hand einen Timer anfordert, und darin die Option eines Callbacks nutzt.

schwa226 13. Apr 2010 18:24

Re: DLL Init, Timer läuft nicht an
 
SetTimer geht bei mir nicht, da ich ja die WM_TIMER nicht bekomme....

Habe jetzt noch ein Problem!
Der Timer wird nun ausgelöst, aber wenn ich die Form einmal gezeigt hatte mit ShowModal dann gibt es den Error: 5 ' Zugriff verweigert' wenn ich ein FreeAndNil(frMain) mache:

Delphi-Quellcode:
procedure TmyThread.Terminate;
begin
  inherited Terminate;
  PostMessage(FHWND, WM_QUIT , 0,0);
end;

procedure TmyThread.Execute;
var msg:Tmsg;
begin

try
  //plugin gets loaded, create Form
  if Not Assigned(frMain) then
    frMain := TfrMain.Create(NIL);

  frMain.AddLog('plugin got init');

finally
//todo
end;

  FHWND:=allocatehwnd(WndProc); //hier ist jetzt dein Windowhandle für MMAudio
  try
    //[weitere Initialisierungen]
    while getMessage(msg,0,0,0) do //warten auf Message
      DispatchMessage(msg); //verteilen auf das entsprechende Fenster (gibt hier allerdings eh nur eins)
  finally
    if Assigned(frMain) then
      FreeAndNil(frMain);
   Deallocatehwnd(FHWND);
  end;
end;

procedure TmyThread.wndProc(var Msg:TMessage);
begin
  Dispatch(msg); //verteilen auf die Methoden mit der entsprechenden Message -->MMInDone
end;
Callstack:
Zitat:

:75e69617 KERNELBASE.RaiseException + 0x54
:0046a4ed RaiseLastOSError + $75
:0046a476 RaiseLastOSError + $A
:004ec618 TCustomForm.DestroyWindowHandle + $38
:00454fc3 TObject.Free + $B
:00454fc3 TObject.Free + $B
:0048fb85 ThreadProc + $45
:0045626e ThreadWrapper + $2A
:772a1174 kernel32.BaseThreadInitThunk + 0x12
:77bcb3f5 ntdll.RtlInitializeExceptionChain + 0x63
:77bcb3c8 ntdll.RtlInitializeExceptionChain + 0x36

himitsu 13. Apr 2010 18:27

Re: DLL Init, Timer läuft nicht an
 
Zitat:

Zitat von schwa226
SetTimer geht bei mir nicht, da ich ja die WM_TIMER nicht bekomme....

Und jetzt rate mal, was der TTimer intern kapselt?

Genau: SetTimer+WM_TIMER :zwinker:

schwa226 13. Apr 2010 18:46

Re: DLL Init, Timer läuft nicht an
 
Das habe ich schon kapiert,

jedoch behebt das mir leider nicht den Fehler wenn ich die Form anzeige. :(

schwa226 13. Apr 2010 21:34

Re: DLL Init, Timer läuft nicht an
 
Zitat:

Und nicht vergessen Zugriffe auf diese VCL unbedingt mit diesem Thread zu syncronisieren.
Danke himitsu :idea:

Habe im DLL Aufruf direkt auf die Form zugegriffen und das Showmodal ausgeführt.

Sende nun mit PostThreadMessage eine Nachricht und der Thread führt dann das Showmodal aus.
Dann gibt es keine Fehlermeldung mehr!

:angel:

Medium 13. Apr 2010 22:46

Re: DLL Init, Timer läuft nicht an
 
Zitat:

Zitat von schwa226
SetTimer geht bei mir nicht, da ich ja die WM_TIMER nicht bekomme....

Das Message-Problem ist mir schon bewusst gewesen. Lies dir die Doku noch mal ganz genau durch ;) Evtl. unter Zuhilfenahme dessen, was ich in meinem Posting geschrieben hab.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:03 Uhr.
Seite 2 von 3     12 3      

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