TTimer et Dll [Résolu]

cs_User8 30 Messages postés jeudi 24 juillet 2008Date d'inscription 13 novembre 2012 Dernière intervention - 9 nov. 2009 à 12:13 - Dernière réponse : cs_User8 30 Messages postés jeudi 24 juillet 2008Date d'inscription 13 novembre 2012 Dernière intervention
- 9 nov. 2009 à 17:01
Hello everybody,

Je développe actuellement un bout de code partagé par un exécutable et une dll.
Ce bout de code utilise un TTimer. Avec l'exécutable, tout se passe bien.
Le problème est que dans la dll, l'évènement OnTimer n'est jamais appelé. Aprés quelques recherches, il apparait, sauf erreur de comprehension, que le Timer ait besoin d'etre fenetré. Si il n'est pas fenétré, le message Windows WM_TIMER n'est pas intercepté et l'évènement OnTimer n'est donc jamais exécuté.

Je recherche donc comment utiliser mon bout de code dans ma dll?
Quelqu'un a-t-il déjà rencontré ce problème?
Dois-je créer un forme invisible et l'associer comme parent de mon Timer?
Existe-t-il une autre solution?

Merci.
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
cs_User8 30 Messages postés jeudi 24 juillet 2008Date d'inscription 13 novembre 2012 Dernière intervention - 9 nov. 2009 à 17:01
3
Merci
MEA CULPA...

Je viens de résoudre mon problème et il s'avère qu'il n'est pas du tout lié au Timer ... ce bout de code fonctionne très bien! C'est l'appel de la Dll qui était foireux. OnTimer n'avait pas le temps de s'exécuter, la classe contenant le timer était détruite ... Je suis parti dans une mauvaise direction!

Merci cs_User8 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 118 internautes ce mois-ci

Commenter la réponse de cs_User8
Cirec 4224 Messages postés vendredi 23 juillet 2004Date d'inscription 5 juin 2018 Dernière intervention - 9 nov. 2009 à 13:18
0
Merci
Salut,

trouvé en 2mn sur Google


[hr]@+Cirec
[hr]
Commenter la réponse de Cirec
cs_User8 30 Messages postés jeudi 24 juillet 2008Date d'inscription 13 novembre 2012 Dernière intervention - 9 nov. 2009 à 13:35
0
Merci
Je tiens quand même à dire qu'avant de poster mon problème j'ai bien entendu effectué divers recherches... J'ai donc également parcouru cette page ... que j'ai également trouvé en moins de 2 minutes.

Ce que je vois sur cette page, c'est le source du TTimer et je ne vois pas trop en quoi cela résout mon problème.

Je vois que le TTimer est censé créer une fenêtre non visuel pour gérer les messages. La question est: pourquoi dans le cas d'une dll, le message WM_TIMER est mal géré? Je pense que mon problème est lié à la gestion des messages WM_TIMER ... mais peut-être je me trompe!
Commenter la réponse de cs_User8
Cirec 4224 Messages postés vendredi 23 juillet 2004Date d'inscription 5 juin 2018 Dernière intervention - 9 nov. 2009 à 14:38
0
Merci
Bon alors,

j'ai utilisé la méthode la plus simple ... c'est à dire que je laisse le Timer créer la fenêtre mais on aurait très bien pu utiliser les fonctions SetTimer & KillTimer et créer la fenêtre nous même avec AllocateHwnd afin d'alléger la Dll !!

voilà ... l'exemple est des plus simples il ne fait qu'incrémenter un compteur toutes les secondes ... rien d'autre ... mais on peut tout gérer
DllTimer.zip


[hr]@+Cirec
[hr]
Commenter la réponse de Cirec
cs_User8 30 Messages postés jeudi 24 juillet 2008Date d'inscription 13 novembre 2012 Dernière intervention - 9 nov. 2009 à 16:45
0
Merci
Je confirme que ta solution marche mais je ne comprends pas pourquoi ca marche dans un cas mais pas dans l'autre ...

voici le bout de code qui coince, c'est une classe qui me permet de lancer des processus:

TProcLauncher = class
  private
    { Déclarations privées }
    FOutFileName: String;
    FOnExit     : TProcedure;
    FOnTimer    : TProcedure;

    Timer              : TTimer;
    ReadPipe,WritePipe : THandle;
    Proc_Info          : TProcessInformation;

    procedure Timer_OnTimer(Sender: TObject);
    procedure FreeHandles;
  public
    { Déclarations publiques }
    Constructor Create;
    Destructor  Destroy; override;
    Function    Execute(Cmd             : String;
                        params          : String;
                        title           : String;
                        CheckInterval   : Cardinal;
                        OnTimer         : TProcedure;
                        OnExit          : TProcedure;
                        OutFileName : String): Boolean;
  end;

implementation

{ TProcLauncher }

{-----------------------------------------------------------------------
 -----------------------------------------------------------------------}
constructor TProcLauncher.Create;
begin
  Timer := TTimer.create(nil);
  Timer.enabled:=false;
  Timer.OnTimer:=Timer_OnTimer;
end;
                                     
{-----------------------------------------------------------------------
 -----------------------------------------------------------------------}
destructor TProcLauncher.Destroy;
begin
  Timer.free;
  Inherited Destroy;
end;

{-----------------------------------------------------------------------
 Execute une commande
 Cmd           : La Commande
 Params        : Les parametres
 Title         : Le titre
 CheckInterval : Interval de temps entre chaque verification d'etat
 OnTimer       : Evenement sur chaque interval (Nil si inutile)
 OnExit        : Evenement à la fin de l'execution du process (Nil si inutile)
 OutFileName   : Redirection en sortie du prcess vers un fichier log ('' si inutile)
 -----------------------------------------------------------------------}
Function TProcLauncher.Execute(Cmd, params,title: String; CheckInterval: Cardinal;
  OnTimer,OnExit: Tprocedure; OutFileName: String): Boolean;
var
 Security           : TSecurityAttributes;
 startinfo          : TStartUpInfo;
begin
  result:=false;
  if busy then exit; // un process est deja en cours
  {Initialisation}
  if checkinterval>0 then Timer.Interval:=CheckInterval
  else Timer.Interval:=3000;
  FoutFilename  :=OutFileName;
  FOnExit       :=OnExit;
  FOnTimer      :=Ontimer;

  With Security do begin
    nlength := SizeOf(TSecurityAttributes) ;
    binherithandle := true;
    lpsecuritydescriptor := nil;
  end;


  if Createpipe (ReadPipe, WritePipe,@Security, 0) then
  begin
   FillChar(proc_info, sizeof(TProcessInformation), #0);
   FillChar(startinfo, sizeof(TStartupInfo), #0);
   startinfo.cb := sizeof(TStartupInfo);
   startinfo.hStdOutput := WritePipe;
   startinfo.hStdInput := ReadPipe;
   startinfo.dwFlags := STARTF_USESTDHANDLES+StartF_USESHOWWINDOW;
   startinfo.wShowWindow := SW_HIDE;
   startinfo.lpTitle:= PANSICHAR(Title);

   if CreateProcess(nil,PANSICHAR(cmd+params),@Security,@Security,
                    true,CREATE_DEFAULT_ERROR_MODE
                    + NORMAL_PRIORITY_CLASS, nil, nil,
                    startinfo,proc_info) then
   Begin
     Timer.enabled:=true;  //Timer attend la fin de process
     result:=true;
   End;
 End;

 if Result=false then FreeHandles;
end;

{-----------------------------------------------------------------------
 A chaque top du timer, on met à jour le log et on regarde l'etat du process
 -----------------------------------------------------------------------}
procedure TProcLauncher.Timer_OnTimer(Sender: TObject);
var
 ExitCode: LongWord;
begin
  Timer.Enabled := False;

  {Action suivant etat}
  if GetExitCodeProcess(proc_info.hProcess, ExitCode) then
  Begin
    if ExitCode = STILL_ACTIVE
    then
    begin
      if assigned(FOnTimer) then FOntimer;
      application.ProcessMessages;
      Timer.Enabled := True;
    end
    else
    begin
      FreeHandles; 
      if assigned(FOnExit) then FOnExit;
    end;
  end
  else
  begin
      FreeHandles;   
      if assigned(FOnExit) then FOnExit;
  end;
end;

Commenter la réponse de cs_User8
cs_User8 30 Messages postés jeudi 24 juillet 2008Date d'inscription 13 novembre 2012 Dernière intervention - 9 nov. 2009 à 16:47
0
Merci
Dans le code ci-dessus, Timer_OnTimer n'est jamais exécuté lorsque on passe par une dll...
Commenter la réponse de cs_User8

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.