Delphi-PRAXiS

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)

schwa226 12. Apr 2010 19:08


DLL Init, Timer läuft nicht an
 
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?

himitsu 12. Apr 2010 19:28

Re: DLL Init, Timer läuft nicht an
 
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

SirThornberry 12. Apr 2010 19:50

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

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:

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.

himitsu 12. Apr 2010 19:55

Re: DLL Init, Timer läuft nicht an
 
Es gibt aber auch eine Menge delphieigener Messages, welche direkt in Delphis Nachrichtenschleife behandelt werden
und Solche werden nicht von einer "fremden" Nachrichtenschleife behandelt.

SirThornberry 12. Apr 2010 19:58

Re: DLL Init, Timer läuft nicht an
 
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.

schwa226 12. Apr 2010 20:07

Re: DLL Init, Timer läuft nicht an
 
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!?

himitsu 12. Apr 2010 20:07

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

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;

SirThornberry 12. Apr 2010 20:15

Re: DLL Init, Timer läuft nicht an
 
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.

himitsu 12. Apr 2010 20:33

Re: DLL Init, Timer läuft nicht an
 
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.

schwa226 12. Apr 2010 21:27

Re: DLL Init, Timer läuft nicht an
 
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... :roll:

Danke!

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.

schwa226 14. Apr 2010 15:27

Re: DLL Init, Timer läuft nicht an
 
Werd's mir nocheinmal genauer ansehen!

Aber zuerst habe ich noch eine Frage zu dem ShowModal:

Ich sende ja nun den Thread, dass er die Form anzeigen soll. somit wird der DLL aufruf ja sofort wieder beendet, da ja nur PostThreadMessage gemacht wird.

Somit ist es nicht Modal. Wie kann man das noch am besten machen, dass die DLL im ShowSettings stehen bleibt?

himitsu 14. Apr 2010 15:33

Re: DLL Init, Timer läuft nicht an
 
Du könntest TThread.Syncronize in der DLL nutzen, um mit dem Thread zu synchronisieren.

schwa226 15. Apr 2010 15:55

Re: DLL Init, Timer läuft nicht an
 
Hab's mit Synchronize versucht, da kommt wieder der Zugriff-Verweigert Fehler:

Delphi-Quellcode:
MyMainThread : TMyMainThread;

procedure ShowSettings(Handle: Integer);
begin
  if Assigned(MyMainThread) then
    MyMainThread.Synchronize(MyMainThread, MyMainThread.ShowDLLForm);
 
//  PostThreadMessage(MyMainThread.ThreadID, WM_SHOWFORM, Handle, 0);
end;

procedure TMyMainThread.ShowDLLForm;
begin
  if Assigned(frMain) then
    frMain.ShowModal;
end;
EDIT:
Auch habe ich noch eine anderes Problem:
Ich starte ja nun einen Thread, dieser macht mir die frMain Form.
Nun arbeite ich mit einem HID-Deivce.
Wenn nun das Gerät abgesteckt wird bleibt mir die DLL bei Checkin stehen:
Delphi-Quellcode:
// method CheckIn hands a checked out HidDevice back in

procedure TJvHidDeviceController.CheckIn(var HidDev: TJvHidDevice);
begin
  if HidDev <> nil then
  begin
    HidDev.StopThread;       //<----- hier bleibt es stehen
    HidDev.CloseFile;
    HidDev.CloseFileEx(omhRead);
    HidDev.CloseFileEx(omhWrite);

    if HidDev.IsPluggedIn then
    begin
      HidDev.FIsCheckedOut := False;
      Dec(FNumCheckedOutDevices);
      Inc(FNumCheckedInDevices);
    end
    else
      HidDev.Free;
    HidDev := nil;
  end;
end;
Delphi-Quellcode:
procedure TJvHidDevice.StopThread;
begin
  if Assigned(FDataThread) then
  begin
    FDataThread.Terminate;
    FDataThread.WaitFor;          <<----schätze also hier das es stehen bleibt
    FDataThread.Free;
    FDataThread := nil;
  end;
end;
Wenn ich die EXE beende, die die DLL geladen hatte läuft es erst weiter.
Wiso wird das jetzt blockiert?

schwa226 15. Apr 2010 19:24

Re: DLL Init, Timer läuft nicht an
 
Will ja nicht pushen, aber ich werde noch Wahnsinnig! :wall:

Das SetTimer geht nicht, auch nicht per Callback.
Dies wird erst ausgelöst wenn die Form angezeigt wird!

Der Ablauf ist nun so:
Die DLL wird geladen,
INIT-Funktion wird aufgerufen -> Thread wird erstellt -> Execute -> frMain (Form wird erzeugt):

Delphi-Quellcode:
procedure TMyMainThread.Execute;
var
  msg:Tmsg;
begin
  try
    InitFinished := False;

    if Not Assigned(frMain) then
      frMain := TfrMain.Create(NIL);

    frMain.AddLog('plugin got init');

    InitFinished := True;

    while not Terminated do
    begin
      Sleep(1);

      if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then //warten auf Message then
      begin
        case msg.message of
          WM_SHOWFORM:
            begin
              if IsWindow(msg.wParam) then
                if Application.Handle <> msg.wParam then
                  Application.Handle := msg.wParam;
              if NOT frMain.Showing then
                frMain.Show;
            end;
          WM_STARTUP:
            begin
              if Assigned(frMain) then
                frMain.Start_StartUp(StartDelay);
            end;
          WM_STOP:
            begin
              if Assigned(frMain) then
              begin
                frMain.AddLog('stopped plugin');
                if ((Assigned(frMain.HIDDevice)) and (not frMain.HIDDevice.IsPluggedIn)) then
                  frMain.JvHidDeviceController.CheckIn(frMain.HIDDevice);

                if Assigned(frMain.JvHidDeviceController) then
                  FreeAndNil(frMain.JvHidDeviceController);
              end;
            end;
          WM_QUIT: Terminate;
          else begin
            //TranslateMessage(msg);
            DispatchMessage(msg);
          end;
        end;
      end;
    end;

  finally
    if Assigned(frMain) then
    begin
      if frMain.Showing then
        frMain.Close;
      FreeAndNil(frMain);
    end;
  end;
end;
//funktion was ausgelöst wird wenn das Device entfernt wird:
Delphi-Quellcode:
procedure TfrMain.JvHidDeviceRemoval(HidDev: TJvHidDevice);
begin
  AddLog('Device got removed: ' + HIDDevice.ProductName);
  if ((Assigned(HIDDevice)) and (NOT HIDDevice.IsPluggedIn)) then
  begin
    if ((HidDev.Attributes.VendorID = VendorID) AND
      (HidDev.Attributes.ProductID = ProductID) AND
      (HidDev.ProductName = ProductName )) then
    begin
      try
        PostThreadMessage(MyMainThread.ThreadID, WM_STOP, 0, 0);

        OutputDebugString(PWideChar('Device got disconnected'));
      finally
//todo
      end;
    end;
  end;
end;
Nun bleibt meine DLL in frMain.JvHidDeviceController.CheckIn(frMain.HIDDev ice); stehen!

Wenn das Device geöffnet wird, wird für HIDDevice ein "WorkerThread" erzeugt.
Dieser will bei CheckIn gestoppt werden.

Und bei Thread Waitfor wartet man für immer, ausser die EXE wird beendet, dann kommt der Debugger sofort aus dem TThread.Waitfor zurück.

Irgendwie kommen immer wieder neue Probleme mit DLL + Form auf...

Medium 15. Apr 2010 20:53

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

Zitat von schwa226
Das SetTimer geht nicht, auch nicht per Callback.
Dies wird erst ausgelöst wenn die Form angezeigt wird!

Ahhh Mist, da hab ich nicht weit genug gelesen :(
Zitat:

Zitat von MSDN
When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.

Sorry :?
Ich bin mir aber irgendwie sicher, schon mal Timer in einem non-Form Projekt genutzt zu haben :gruebel:

Vielleicht wäre es noch ein Weg, das Fenster ganz von Hand via WinAPI, also Hier im Forum suchennon-VCL, zu erstellen. Damit umgeht man zumindest das dumme Gehampel mit den VCL-Interna, sprich Threads und das ganze Gelöt. Oder aber du nimmst MSDN-Library durchsuchenCreateTimerQueue + MSDN-Library durchsuchenCreateTimerQueueTimer (das neue Gegenstück zum mittlerweile obsoleten MMTimer setTimerEvent()). Da spricht zumindest kein Parameter von irgendwelchen Fensterhandles, und statt "Messages" les ich da ausschließlich "Callback" :). Ist zwar erstmal mit Reindenken verbunden, aber man spart sich den ganzen Krampf den du bisher veranstalten musstest - NUR um einen Timer zu haben.

schwa226 16. Apr 2010 10:19

Re: DLL Init, Timer läuft nicht an
 
Ja, hatte ich auch schon mal in einer DLL.

So eine Class mit Start(Interval), Stop usw.
Gibt hier irgendwo ein Beispiel dafür.

Da hatte es auch funktioniert, aber nun durch die Verwendung der DLL mit der Console bin ich auf diese Probleme gestoßen.

schwa226 27. Apr 2010 16:28

Re: DLL Init, Timer läuft nicht an
 
Zu diesem leidigen Thema nochmal:

Mit der D6DLLSynchronizer.pas kann ich nun den SubThread beenden! :)

Jedoch habe ich noch Probleme mit dem Anzeigen der Form mit ShowModal.

Delphi-Quellcode:
procedure ShowSettings(Handle: Integer);
begin
  if Assigned(MyMainThread) then
  begin
    if Handle = 0 then
      Handle := GetActiveWindow;

    Application.Handle := Handle;

    TThread.Synchronize(MyMainThread, MyMainThread.FormShowModal);

    Application.Handle := 0;
  end;
end;
Wenn ich das nun ausführe wir mein Fenster angezeigt.
Wenn ich nun aber FreeAndNil(frMain) beim beenden durchführe bekomme ich den Error:
EOSError Code 5 (Zugriff verweigert).
Habe leider keine Ahnung warum dieser kommt und wo dieser Auftritt.

Wie kann man das noch lösen? :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:24 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