IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

Timer MFC erreur de LNK


Sujet :

MFC

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut Timer MFC erreur de LNK
    Bonjour à tous!

    voila j'ai un problème au niveau d'un timer que j'ai créé de la manière suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
     
    #include<windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "Timer.h"
     
    // Timer dialog
     
    /*static*/void Timer::OnStartTimer() 
    {
     
       UINT_PTR m_nTimer;
       m_nTimer = SetTimer(1, 10, 0);
    }
     
    /*static*/void Timer::OnStopTimer() 
    {
       UINT_PTR m_nTimer;
       KillTimer(m_nTimer);   
    }
     
     
    /*static*/ void Timer::OnTimer(UINT IdTimer) 
    {
     
    	int PedalState;
    	PedalState=0;
     
    	unsigned char Authmov[1]={140}; // get etat command
    	unsigned char NoAuthmov[1]={141}; // get etat command
     
    	CCom::ClosePortCom();
    	CCom::InitPortCom();
     
     
    	if(PedalState = 0)
    	{
    		WriteFile(hcom,Authmov, 1, &m, NULL);
    		CCom::ReadBuffer();
     
    		if ((data[1]=1)&&(data[0]=140))
    		{
    			OnStopTimer();
    			OnStartTimer(); 
     
    		}
    		else
    		{
     
    			OnStopTimer();
    			OnStartTimer(); 
    		}
     
    	}
    	else
    	{
    		WriteFile(hcom,NoAuthmov, 1, &m, NULL);
     
    		if ((data[1] = 1) && (data[0]=141))
    		{
    			OnStopTimer();
    			OnStartTimer(); 
     
    		}
    		else
    		{
     
     
    			OnStopTimer();
    			OnStartTimer(); 
    		}
    	}
     
    }
    J'ai essayé de suivre les indications du faq de farscape mais j'ai les erreurs suivantes:
    error LNK 2019:unresolved external symbol "public:static unisgned int_cdecl Timer::SetTimer...
    error LNK 2019:unresolved external symbol "public:static unisgned int_cdecl Timer::killTimer...

    J'ai cherché dans les forums mais je ne comprends pas vraiment ...
    Pouvez vous me donner un coup de main?

    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    normal la méthode SetTimer de la faq fait partie de la classe CWnd...
    sinon il faut passer par l'api Win32 mais bon je ne te le conseil pas trop...

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Merci pour ta réponse !

    Il suffit donc je déclare les fonctions dans mon .h de la manière suivante?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    CWnd::SetTimer
    UINT SetTimer( 
    UINT nIDEvent,  // numéro du timer à partir de 1 
    UINT nElapse,    // temps ecoulé entre 2 appels en ms.
    void (CALLBACK EXPORT* lpfnTimer)( 
    HWND, UINT, UINT, DWORD) ); // fonction callback.
     
     
    CWnd::KillTimer
    BOOL KillTimer( 
    int nIDEvent ); // numéro du Timer
    cependant je suis débutante en C++ et ma fonction OnTimer est static il faut donc que SetTimer et KillTimer le soient aussi ... comment puis je faire?

  4. #4
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Si je met static devant SetTimer et KillTimer dans le .h ca ne marche pas...

    Aidez moi s'il vous plait !! je suis perdue ...

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    C'est bon j'ai réglé le problème de static. J'ai créé un objet CWnd timer et j'ai appelé ma fonction de la manière suivante : timer.SetTimer(1, 10, 0);
    J'ai fait de même avec KillTimer.

    Par contre maintenant j'ai l'erreur suivante à l'éxecution:
    J'ai les lignes relatives à SetTimer et Killtimer de surligner dans le fichier afxwin2.h et le message suivant : .exe has triggered a breakpoint!

    Que dois je faire?

  6. #6
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    salut,

    as tu lu entierement la MSDN sur la fonction SetTimer() ???

    il ne suffit pas de faire dériver une classe de CWnd pour utiliser SetTimer ...
    ok le compilateur ne dit plus rien, mais c'est pas du tout fonctionnel

    un Timer est soit rattaché à une fenetre, soit rattaché à un thread à condition qu'il possède une boucle à message...

    dans ton cas, tu essayes de rattacher un timer à une fenetre qui n'existe pas ... donc normal que ça plante

    utilises la fonction globale SetTimer() en indiquant une procédure et non la méthode SetTimer() de la classe CWnd

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    m_IdTimer=::SetTimer(NULL,0,1000,TimerProc);  // création d'un timer qui bat à la seconde
     
    ...
     
    KillTimer(m_IdTimer);  // pour arreter le timer
     
    ...
     
    VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/)
    {
      // ici la procédure du timer
    }
    tu auras remarqué que j'ai mis le préfixe "m_" devant la variable m_IdTimer. C'est à dire que c'est une variable membre de la classe et qu'elle doit etre persistante pendant toute la durée de vie du timer, sinon tu pourras pas arreter le Timer ...

    @+

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Merci beaucoup pour ta réponse clair

    cependant j'ai encore du mal faire quelquechose car j'ai l'erreur suivante:
    errorC3867:'InstantResult::TimerProc' function call missing argument list; use '&InstantResult::TimerProc' to create a pointer to member.
    Et si je fais ca... j'ai une autre erreur.

    je ne comprends vraiment pas tout les exemples que j'étudie font la même chose. SetTimer prend bien comme 4ième argument un pointeur de type TIMERPROC vers la fonction callback.

    Pourquoi ai je l'erreur précédente ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Personne n'a d'idée ?

    voila ce que j'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    BOOL InstantResult::OnInitDialog()
    {
     
    m_IdTimer=::SetTimer(NULL,0,1000,TimerProc);  // création d'un timer qui bat à la seconde
     
    return TRUE;
    }
     
     
    void InstantResult::OnBnClickedButton2()
    {
     
    	// TODO: Add your control notification handler code here
     
    	KillTimer(m_IdTimer);  // pour arreter le timer
     
    }
     
    VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/)
    {
      // ici la procédure du timer
     
    	unsigned char Authmov[1]={140}; // authorization to move command
    	unsigned char NoAuthmov[1]={141}; // not allowed to move command
     
     
    	CCom::ClosePortCom();
    	CCom::InitPortCom();
     
    			WriteFile(hcom,Authmov, 1, &m, NULL);
    			CCom::ReadBuffer();
    }
    et donc j'ai l'erreur 'TimerProc' function call missing argument use &InstantResult::TimerProc to create a pointer to member.

  9. #9
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    tu es dans une boite de dialogue ?
    si c'est le cas, utilise un Timer lié à la fenetre de ta boite de dialogue, c'est plus simple.

    sinon, la fonction TimerProc doit etre static si c'est une fonction déclarée dans une classe. a ce que je vois, dans ton code, il ne manque que le prototype de la fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    VOID CALLBACK TimerProc(HWND,UINT,UINT_PTR,DWORD);
    a déclarer avant de faire référence à TimerProc.

    @+

  10. #10
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Rahhhh .... il me manque une librairie apparemment. Oui mais laquelle ?

    J'ai déclaré TimerProc en static dans mon .h et je mis le prototype de cette fonction dans mon .cpp au début.

    Au niveau librairie, j'ai pourtant tout ce qu'il faut je pensais :
    <Time.h>
    <windows.h>

  11. #11
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    il ne te manque aucune librairie
    les timer sont définis dans <windows.h> ...

    tu travailles avec les MFC non ?
    donc vire moi ces includes inutiles
    tout est déjà dans le fichier StdAfx.h

    tu es sous quelle version de VS ?

    si c'est VS98 (VC6), il ne reconnaitra pas UINT_PTR ; remplaces le par UINT

    @+

  12. #12
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Oui je travaille avec les MFC.

    Je suis sous Visual Studio 2005.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Bon alors comme tu mas dit j'ai fait ca dans mon .cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    static VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/);
     
     
    InstantResult::InstantResult(CWnd* pParent /*=NULL*/)
    	: CDialog(InstantResult::IDD, pParent)
    {
    	//m_IdTimer=::SetTimer(NULL,0,1000,TimerProc);  // création d'un timer qui bat à la seconde
    }
     
     
    void InstantResult::OnBnClickedButton2()
    {
     
    	// TODO: Add your control notification handler code here
     
     
    	KillTimer(m_IdTimer);  // pour arreter le timer
    }
    VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/)
    {
      // ici la procédure du timer
     
    	unsigned char Authmov[1]={140}; // authorization to move command
     
     
    	CCom::ClosePortCom();
    	CCom::InitPortCom();
    	WriteFile(hcom,Authmov, 1, &m, NULL);
    	CCom::ReadBuffer();
     
    }
    et dans mon .h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public:
     
    	UINT_PTR m_IdTimer;
     
    	static VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/);
    En effet ca ne change rien si je définis m_IdTimer en UINT.

  14. #14
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    ben sois tu définies la procédure dans la portée de ta classe, donc:

    dans le .h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class InstantResult
    {
      ...
      static VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/);
      ...
    };
    et donc dans le .cpp ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    VOID CALLBACK InstantResult::TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/)
    {
    }
    et dans ce cas tu aurais oublié le InstantResult:: ...

    sois tu définies la procédure en portée globale :

    dans le .h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/);
     
    class InstantResult
    {
      ...
    };
    tu auras remarqué que la déclaration n'est pas à l'intérieur de la classe ...

    et dans le .cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    VOID CALLBACK TimerProc(HWND /*hwnd*/,UINT /*uMsg*/,UINT_PTR /*idEvent*/,DWORD /*dwTime*/)
    {
      ...
    }
    et là pas de InstantResult:: devant

    ça c'est les bases du C++

    @+

  15. #15
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    youuuuuhouuuuuuuuuuu

    Ca marche je reçois bien ce que je désire toutes les 10 ms!!!

    Merci beaucoup ton aide m'est trés précieuse!

  16. #16
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    :'(

    euhh juste encore un truc KillTimer(1); normalement ca arrête directement mon timer ?

    la je l'appel dans la fonction suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void InstantResult::OnBnClickedButton2()//return button
    {
     
    	// TODO: Add your control notification handler code here
     
    	toto = KillTimer(1);  // pour arreter le timer 
     
    }
    (j'ai changé l'id du timer je l'ai mis à 1 dans settimer)

  17. #17
    Membre confirmé Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Points : 521
    Points
    521
    Par défaut
    si ton Timer n'est pas attaché à une fenetre, il faut conserver l'Id retourné par SetTimer()
    c'est pas toi qui choisit l'Id mais le systeme ; c'est bien expliqué dans la MSDN

    par contre, si tu fournis un HWND à SetTimer(), là c'est toi qui le choisit ...

    @+

  18. #18
    Nouveau membre du Club
    Inscrit en
    Juin 2006
    Messages
    126
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 126
    Points : 37
    Points
    37
    Par défaut
    Oula il y a un truc louche.

    Quand je fais afficher la valeur de m_IdTimer juste aprés SetTimer de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    m_IdTimer=::SetTimer(NULL,0,1000,TimerProc);  // création d'un timer qui bat à la seconde	
    str.Format(_T("%.1i"),m_IdTimer);
    AfxMessageBox(str);
    j'ai m_IdTimer =26974

    et quand je fais la même chose juste avant l'appel de KillTimer dans mon handle de bouton. J'ai:
    m_IdTimer =26968


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MFC] erreur de compilation
    Par moulefrite dans le forum MFC
    Réponses: 3
    Dernier message: 03/05/2006, 15h26
  2. Réponses: 2
    Dernier message: 31/01/2006, 14h31
  3. [MFC] erreur sans le winmain
    Par r0d dans le forum MFC
    Réponses: 5
    Dernier message: 27/01/2006, 10h17
  4. [MFC] Erreur mémoire
    Par leMehdi dans le forum MFC
    Réponses: 8
    Dernier message: 26/01/2006, 16h09
  5. [MFC] erreur bizar a cause d'un activeX
    Par pitch21 dans le forum MFC
    Réponses: 12
    Dernier message: 29/06/2005, 14h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo