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 :

Thread et communication de variables


Sujet :

MFC

  1. #1
    Membre � l'essai
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    5
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 30
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 5
    Par d�faut Thread et communication de variables
    Bonjour,

    Je suis bloqu� dans le d�veloppement d'une application MFC (je suis d�butant).

    Enfaite, j'ai une classe contenant ma boite de dialogue, avec boutons et zone d'�dition et une autre classe contenant une machine � �tat (envoi/r�ception de donn�e en fonction de l'�tat via port s�rie).

    A l'appui sur un bouton, je cr�er un thread avec AfxBeginThread qui d�marre ma machine � �tat. Ainsi, je peux continuer � utiliser ma boite de dialogue sans qu'elle soit bloqu�e par ma machine � �tat.

    Le probl�me, c'est que je n'arrive pas � communiquer les �tats (sous forme de CString ou int peu importe) de ma machine � �tat vers ma boite de dialogue pour pouvoir afficher l'�tat en temps r�el dans une zone d'�dition.

    Comment je peux faire?

    StateMachine.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
     
    void StateMachine::Etats (int state)
    {
        while (state != x)
        {
            switch (state)
            {
                case 0:
                ...
                case 1:
                ...
            }
        }
    }
    Dialog.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
     
    StateMachine *stateMachine1 = new StateMachine;
     
    void Dialog::OnClickedStart
    {
        ...
        AfxBeginThread(MyThread,0);
    }
     
    UINT MyThread(LPVOID Param)
    {
        ...
        stateMachine1->Etats(0);
        ...
    }

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Pour communiquer vers un thread d'UI avec l'API Win32 ou MFC, g�n�ralement on utilise SendMessage() ou PostMessage(), selon qu'on ait besoin ou non d'�tre synchrone. L'avantage d'un appel synchrone est qu'on n'a pas besoin de transf�rer la "propri�t�" d'une variable allou�e dynamiquement, vu que le traitement du message sera fini avant que SendMessage() retourne.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre � l'essai
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    5
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 30
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 5
    Par d�faut
    Merci beaucoup pour cette r�ponse , je vais essayer �a!

  4. #4
    Membre � l'essai
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    5
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 30
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 5
    Par d�faut
    Bon alors, j'ai bien essay� SendMessage() et PostMessage().

    Malheureusement, dans les deux cas, j'ai :
    - Exception lev�e � 0x004016DE dans VC_Sample.exe : 0xC0000005 :Violation d'acc�s lors de la lecture de l'emplacement 0x00000020.



    StateMachine.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
     
    StateMachine::StateMachine()
    {
     
    }
     
    void StateMachine::Etats (int state)
    {
        Dialog *pDLg = (Dialog *) GetParent(HWND_BROADCAST);
     
        while (state != x)
        {
            switch (state)
            {
                case 0:
                    pDLg -> SendMessage(WM_PROC_CONTROL2, (WPARAM)"test", 0);
                case 1:
                ...
            }
        }
    }
    Dialog.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
    33
    34
    35
    36
    37
     
    StateMachine *stateMachine1 = new StateMachine;
     
    Dialog::Dialog(CWnd* pParent) : CDialog(Dialog::IDD, pParent)
    {
     
    }
     
    void Dialog::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
    }
     
    BEGIN_MESSAGE_MAP(Dialog, CDialog)
        ...
        ON_MESSAGE(WM_PROC_CONTROL2, OnProcControl2) //Il existe un autre ProcControl qui utilise une dll
     
    END_MESSAGE_MAP()
     
    LRESULT Dialog::OnProcControl2(WPARAM wParam, LPARAM lParam)
    {
        CString *pstr = (CString*)wParam;
        return (LRESULT)0;
    }
     
    void Dialog::OnClickedStart
    {
        ...
        AfxBeginThread(MyThread,0);
    }
     
    UINT MyThread(LPVOID Param)
    {
        ...
        stateMachine1->Etats(0);
        ...
    }
    Une id�e?

    A+

  5. #5
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Que retourne GetParent(HWND_BROADCAST)?
    PS: Attention � ne pas confondre CWnd::GetParent() qui retourne un CWnd*, et ::GetParent(HWND) qui retourne un HWND. Dans aucun des deux cas la valeur retourn�e ne devrait �tre castable en Dialog*...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre � l'essai
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    5
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 30
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 5
    Par d�faut
    Merci beaucoup, �a m'a mis sur la piste pour r�soudre le probl�me!

    Maintenant, �a fonctionne impeccable.

    StateMachine.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
    StateMachine::StateMachine()
    {
     
    }
     
    void StateMachine::Etats (int state)
    {
        CString* state0 = new CString (_T("State 0"));
        CString* state1 = new CString (_T("State 1"));
        ...
     
        while (state != x)
        {
            switch (state)
            {
                case 0:
                    AfxGetMainWnd() -> SendMessage(WM_PROC_CONTROL2, (WPARAM)state0, 0);
                case 1:
                    AfxGetMainWnd() -> SendMessage(WM_PROC_CONTROL2, (WPARAM)state1, 0);
                ...
            }
        }
    }
    Dialog.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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    StateMachine *stateMachine1 = new StateMachine;
     
    Dialog::Dialog(CWnd* pParent) : CDialog(Dialog::IDD, pParent)
    {
     
    }
     
    void Dialog::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
    }
     
    BEGIN_MESSAGE_MAP(Dialog, CDialog)
        ...
        ON_EN_CHANGE(IDC_EDIT_LOG, &Dialog::OnEnChangeEditLog)
        ON_MESSAGE(WM_PROC_CONTROL2, OnProcControl2) //Il existe un autre ProcControl qui utilise une dll
     
    END_MESSAGE_MAP()
     
    LRESULT Dialog::OnProcControl2(WPARAM wParam, LPARAM lParam)
    {
        CString *pstr = (CString*)wParam;
        CString& Temp = *pstr;
     
        CString strTmp;
        CString strTxtLog;
        GetDlgItemText(IDC_EDIT_LOG, strTxtLog);
     
        strTmp.Format(_T("") + Temp + SZ_CRLF);
     
        strTxtLog += strTmp;
     
        SetDlgItemText(IDC_EDIT_LOG, strTxtLog);
     
        ((CEdit*)GetDlgItem(IDC_EDIT_LOG)->SetSel(strTxtLog.GetLength(), strTxtLog.GetLength());
     
        return (LRESULT)0;
    }
     
    void Dialog::OnClickedStart
    {
        ...
        AfxBeginThread(MyThread,0);
    }
     
    UINT MyThread(LPVOID Param)
    {
        ...
        stateMachine1->Etats(0);
        ...
    }
    Derni�re question et ce sera bon pour moi je pense :
    - Y-a-t-il un truc plus "sexy" que de faire �a :
    CString* state0 = new CString (_T("State 0"));
    CString* state1 = new CString (_T("State 1"));
    ...

  7. #7
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    D�j�, vu que tu utilises SendMessage() qui est synchrone, tu pourrais simplement faire ceci:
    Code C++ : 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
    //Ici on prend directement un LPCTSTR, 
    //vu qu'on ne le modifie pas et qu'on ne l'utilise plus une fois que SendMessage() a retourné
    void AfficherTexte(LPCTSTR texte)
    {
    	AfxGetMainWnd()->SendMessage(WM_PROC_CONTROL2, reinterpret_cast<WPARAM>(texte), 0);
    }
     
    LRESULT Dialog::OnProcControl2(WPARAM wParam, LPARAM lParam)
    {
    	//Changement pour prendre en compte le fait de passer le texte sous forme de LPCTSTR
    	LPCTSTR texte = reinterpret_cast< LPCTSTR >(wParam);
     
    	//Note: le GetDlgItem() n'est peut-être pas nécessaire, si la textbox est déjà une variable membre.
    	CEdit* textBox = static_cast< CEdit* >(GetDlgItem(IDC_EDIT_LOG));
     
    	//Technique spéciale pour ajouter du texte à la fin d'une textbox:
    	//On sélectionne juste la fin, puis on la remplace par le texte voulu
    	int length = textBox->GetWindowTextLength();
    	textBox->SetSel(textBox, textBox)
    	textBox->ReplaceSel(texte);
     
    	return 0L;
    }
    Avec un PostMessage() ce serait plus compliqu�, � cause du transfert de responsabilit�.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre � l'essai
    Homme Profil pro
    �tudiant
    Inscrit en
    Avril 2018
    Messages
    5
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 30
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Avril 2018
    Messages : 5
    Par d�faut
    Okeeey �a marche impeccable

    Maintenant je voudrais faire la m�me chose dans l'autre sens, c'est � dire communiquer � partir d'une gestionnaires d'�v�nement de mon Dialog vers mon thread en cours, mais encore une fois �a casse tout

    StateMachine.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
    StateMachine::StateMachine()
    {
     
    }
     
    void StateMachine::Etats (int state)
    {
        ...
     
        while (state != x)
        {
            switch (state)
            {
                case 0:
                ...
                ////////////////////// J'attends de recevoir "OK1" � partir de ma gestionnaire d'evnt "OnProcControl" pour passer � case 1 //////////////////////
                case 1:
                ...
                ////////////////////// J'attends de recevoir "OK2" case 2 //////////////////////
                ...
            }
        }
    }
    Dialog.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
    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
    StateMachine *stateMachine1 = new StateMachine;
     
    Dialog::Dialog(CWnd* pParent) : CDialog(Dialog::IDD, pParent)
    {
     
    }
     
    void Dialog::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
    }
     
    BEGIN_MESSAGE_MAP(Dialog, CDialog)
        ...
        ON_EN_CHANGE(IDC_EDIT_LOG, &Dialog::OnEnChangeEditLog)
        
        ON_MESSAGE(WM_PROC_CONTROL, OnProcControl) // Le proc control qui communique avec une DLL
        
        ON_MESSAGE(WM_PROC_CONTROL2, OnProcControl2)
     
    END_MESSAGE_MAP()
    
    LRESULT Dialog::OnProcControl(WPARAM aParam, LPARAM aParam)
    {
        CString strTmp;
        
        const int MAX_RECEIVE = 1024; // Nombre maximal d'octets de tampon de r�ception
    
        TCHAR szReceive[MAX_RECEIVE];
    
        memset ( szReceive, 0, sizeof(szReceive) );
    
        // Re�u via l'application xxx � travers la DLL
        int nRecCount = RecieveCommand( szReceive, sizeof(szReceive) ); ////////////////////// Information re�u par la DLL que j'affiche ensuite dans mon Log //////////////////////
    
        CString strTxtLog
        GetDlgItemText(IDC_EDIT_LOG, strTxtLog);
    
        if( 0 < nRecCount )
        {
            strTmp.Format( _T("*[Receive]%s%s"), szReceive, SZ_CRLF );
            strTxtLog += strTmp;
        }
        else
        {
            
            strTmp.Format( _T("*[Receive]Error[No received data.)%s"), SZ_CRLF );
            strTxtLog += strTmp;
        }
        SetDlgText( IDC_EDIT_LOG, strTxtLog );
        ((CEdit*)GetDlgItem(IDC_EDIT_LOG))->SetSel( strTxtLog.GetLength(), strTxtLog.GetLength() );
    
        ////////////////////// Transmettre strTxtLog � mon thread //////////////////////
    
        return (LRESULT)0;
    
    }
     
    LRESULT Dialog::OnProcControl2(WPARAM wParam, LPARAM lParam)
    {
        ...
    }
     
    void Dialog::OnClickedStart
    {
        ...
        AfxBeginThread(MyThread,This);
    }
     
    UINT MyThread(LPVOID Param)
    {
        ...
        stateMachine1->Etats(0);
        ...
    }
    Voilou

    A+

  9. #9
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Vu que le thread de travail n'a pas de boucle de messages, tu ne peux pas utiliser SendMessage() pour communiquer avec. Par contre, si tu dois juste �changer des "OK1" et "OK2", tu peux utilise deux Events. Renseigne-toi sur les fonctions CreateEvent(), SetEvent(), WaitForSingleObject() et CloseHandle().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parl� avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. OOP : communication des variables fille -> m�re
    Par Pleinpopossum dans le forum Langage
    R�ponses: 9
    Dernier message: 02/04/2008, 16h37
  2. Gestion des threads de communication TCP/IP
    Par Daminus dans le forum Delphi
    R�ponses: 6
    Dernier message: 01/12/2006, 13h37
  3. R�ponses: 2
    Dernier message: 29/08/2006, 01h07
  4. [MFC] Thread de communication et Dialog Data Exchange
    Par Philippe320 dans le forum MFC
    R�ponses: 4
    Dernier message: 20/05/2006, 17h07
  5. Thread C++ C et variables.....
    Par panda_fonfon dans le forum MFC
    R�ponses: 4
    Dernier message: 28/04/2006, 15h06

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