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 :

[MFC] thread d'affichage


Sujet :

MFC

  1. #1
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut [MFC] thread d'affichage
    Bonjour,
    J'essaye de faire un "thread d'affichage" mais il ne fonctionne pas!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    UINT CImageControllerDlg::display( LPVOID p_param )
    {
    CImageControllerDlg* dlg = (CImageControllerDlg*)p_param;
    dlg->_processed_img.SetWindowText("0");
    dlg->_avnct_gnl_haut->SetWindowText("Calcul du nombre total d'images à analyser");
    AfxEndThread(0);
    return 0;
    }
    dès que le code passe à l'instruction "dlg->_processed_img.SetWindowText("0");", il se bloque! savez vous pourquoi?

  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

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    Je ne comprend pas tout dans la faq...

    J'apelle mon thread d'affichage ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    _thread_display = AfxBeginThread( display, GetSafeHwnd(), THREAD_PRIORITY_NORMAL );
    Comment faire la fonction display?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    UINT CImageControllerDlg::display( LPVOID p_param )
    {
    HWND* dlg = (HWND*)p_param;
     
    _progress_bar = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS_DETAIL);
    _processed_img.SetWindowText("0");
    }
    ...

  4. #4
    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
    Par défaut
    soit tu travailles en win32
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    HWND hProgress=::GetDlgItem(dlg,IDC_PROGRESS_DETAIL);
    // etc..
    soit tu fais un message privé dans ta dialogue qui s'occupe de l'affichage.
    comme indiqué dans la faq:
    voir aussi pour le message privé:
    http://www.developpez.net/forums/vie...567222#1567222

  5. #5
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    HWND _progress=::GetDlgItem(dlg,IDC_PROGRESS_DETAIL);
    	_progress->SetPos(100);
    ça ne fonctionne pas...
    le seul attribu que j'ai dans _progress est "unused"...

  6. #6
    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
    Par défaut
    normal HWND n'est pas une classe mais un handle de fenetre...

    fait une fonction message prive suivant les indications du post cité
    met ton code d'affichage dedans et dans ton thread envoi le message comme indiqué dans la faq.


  7. #7
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    lorsque le thread à envoyé le message, comment faire pour le recuperer (c'est pas écris dans la faq, ni dans le message)?

  8. #8
    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
    Par défaut
    c'est tout ecris la dedans lol
    http://www.developpez.net/forums/vie...567222#1567222
    dans la deuxieme partie tu as un exemple pour un thread ....

  9. #9
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    j'ai fais exactement toutes les étapes décrite et pourtant je ne reçoit pas le message "coucou"...

  10. #10
    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
    Par défaut
    tu as mis un point d'arret en debug dans le thread et dans la fonction du message privé ?

  11. #11
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    il passe bien dans le thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    UINT CImageControllerDlg::display( LPVOID p_param )
    {
    	//HWND dlg = (HWND)p_param;
    	HWND hWnd= static_cast< HWND >( p_param) ; 
    	 ::PostMessage(hWnd,WM_TEST,0,0) ; 
    	return 0;
     
    }
    mais ne passe pas dans la fonction associée au message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ON_MESSAGE(WM_TEST, OnReceiveTest)  // message privé 
    END_MESSAGE_MAP()
     
     
    long CImageControllerDlg::OnReceiveTest(WPARAM wparam, LPARAM lparam) 
    { 
       AfxMessageBox("coucou"); 
       return 0L; 
    }
    ...

    EDIT:
    j'ai bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define WM_TEST WM_USER+100
    dans le .h de la boite de dlg ainsi que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    long OnReceiveTest(WPARAM wparam,LPARAM lparam); // fonction de réponse pour le message privé
    en protected...

  12. #12
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    ne faut il pas faire quelque chose dans le proc pere pour récuperer le message?
    EDIT :
    quand je fais un afxMessageBox après avoir lancé le thread dans le proc principal, alors je passe bien dans la fonction et la boite de dlg "coucou" apparait!

  13. #13
    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
    Par défaut
    tu es sur du handle de fenetre passe dans ton thread ?

  14. #14
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    je ne sais pas, j'apelle la fonction GetSafeHwnd:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    AfxBeginThread( display, GetSafeHwnd(), THREAD_PRIORITY_NORMAL );

  15. #15
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    J'ai essayé de faire comme ça :

    Dans le père :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    AfxBeginThread( display, this, THREAD_PRIORITY_NORMAL );
    Dans le thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    UINT CImageControllerDlg::display( LPVOID p_param )
    {
    	CImageControllerDlg* dlg = (CImageControllerDlg*)p_param;
    	::PostMessage(dlg->GetSafeHwnd(),WM_TEST,GetCurrentThreadId(),0);
    return 0;
    }
    ça me donne exactement le même resultat : si je lance une afxmessagebox dans le père après avoir lancé le thread, ça affiche bien "coucou", sinon il ne rentre pas dans la fonction "OnReceiveTest"...
    farscape au secours!

  16. #16
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Essaie dans ton .h de préfixer la fonction de réception du message par afx_msg.

    EDIT : ça ane dvrai rien chager en fait. Tu ne pourrais pas envoyer tes sources si elles ne sont pas volumineuses ?

  17. #17
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    ça fait exactement la même chose

  18. #18
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    mes sources completes sont volumineuses... mais voici les extraits "utiles"
    :
    ImageController.h
    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
     
    #pragma once
    #include "afxwin.h"
    #include "Report.h"
    #include <iostream>
     
    #define WM_TEST WM_USER+100 
    class CImageControllerDlg : public CDialog
    {
     
    public:
    enum { IDD = IDD_IMAGECONTROLLER_DIALOG };
     
    (...)
     
    protected:
    	HICON m_hIcon;
     
    	virtual void DoDataExchange(CDataExchange* pDX);	// Prise en charge DDX/DDV
    	// Fonctions générées de la table des messages
    	virtual BOOL OnInitDialog();
    	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    	afx_msg void OnPaint();
    	afx_msg HCURSOR OnQueryDragIcon();
    	afx_msg long OnReceiveTest(WPARAM wparam,LPARAM lparam); // fonction de réponse pour le message privé 
    	DECLARE_MESSAGE_MAP()
     
    	virtual void OnRangeUpdateCheck(UINT nID);
     
    (...)
    };
    ImageController.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
    76
    77
    78
    79
     
    #include "stdafx.h"
    #include "ImageController.h"
    #include "ImageControllerDlg.h"
    #include ".\imagecontrollerdlg.h"
    #include "Images.h"
    #include "FindFile.h"
    #include "FolderDlg.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
     
    //static int Save_histo;
    //static UINT StartThread (LPVOID param);	//controlling function header
    //static UINT computeTime (LPVOID param);	//controlling function header
     
    // boîte de dialogue CAboutDlg utilisée pour la boîte de dialogue 'À propos de' pour votre application
    class CAboutDlg : public CDialog
    {
    public:
    	CAboutDlg();
     
    // Données de boîte de dialogue
    	enum { IDD = IDD_ABOUTBOX };
     
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // Prise en charge DDX/DDV
     
    // Implémentation
    protected:
    	DECLARE_MESSAGE_MAP()
    };
     
    CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    {
    }
     
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    }
     
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    END_MESSAGE_MAP()
     
     
    // boîte de dialogue CImageControllerDlg
     
    BEGIN_MESSAGE_MAP(CImageControllerDlg, CDialog)
    	ON_WM_SYSCOMMAND()
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	ON_MESSAGE(WM_TEST, OnReceiveTest)  // message privé 
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(B_GO, OnBnClickedGo)
    	ON_BN_CLICKED(B_CANCEL, OnBnClickedCancel)
    	ON_BN_CLICKED(B_STOP, OnBnClickedStop)
    	ON_BN_CLICKED(B_BROWSE_SOURCE, OnBnClickedBrowseSource)
    	ON_BN_CLICKED(B_BROWSE_DEST, OnBnClickedBrowseDest)
    	ON_BN_CLICKED(B_BROWSE_REPORT_DEST, OnBnClickedBrowseReportDest)
    	ON_BN_CLICKED(C_BLUR, OnBnClickedBlur)
    	ON_BN_CLICKED(C_MONOTONE, OnBnClickedMonotone)
    	ON_BN_CLICKED(C_IDENTICAL_FOLDER, OnBnClickedIdenticalFolder)
    	ON_BN_CLICKED(C_COPY_IMAGES, OnBnClickedCopyImages)
    	ON_BN_CLICKED(C_IDENTICAL_FOLDER_REPORT, OnBnClickedIdenticalFolderReport)
    	ON_EN_CHANGE(EC_SENSIBILITE, OnEnChangeSensibilite)
    	ON_BN_CLICKED(C_COPY_MONOTONE, OnBnClickedCopyMonotone)
    	ON_BN_CLICKED(C_CUT_MONOTONE, OnBnClickedCutMonotone)
    	ON_EN_CHANGE(EC_NB_THREAD, OnEnChangeNbThread)
    	ON_EN_CHANGE(EC_DEST_FOLDER, OnEnChangeDestFolder)
    END_MESSAGE_MAP()
     
     
    long CImageControllerDlg::OnReceiveTest(WPARAM wparam, LPARAM lparam) 
    { 
       AfxMessageBox("coucou");
       return 0L; 
    }
    fonction qui lance le programme
    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
     
    //Lancement du processus de verification
    void CImageControllerDlg::OnBnClickedGo()
    {
    	_stop_thread = false;
     
    	if (_is_process == true)
    	{
    		AfxMessageBox ("Processus actuellement en cours !");
    		return;
    	}
    	else
    	{
    		execute();
    		return;
    	}
    }
    fonction execute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int CImageControllerDlg::execute(void)
    {
    (...)
    _thread_display = AfxBeginThread( display, this, THREAD_PRIORITY_NORMAL );
    _thread_time = AfxBeginThread( computeTime, this , THREAD_PRIORITY_NORMAL);
    (...)
    }
    fonction associée au thread display :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    UINT CImageControllerDlg::display( LPVOID p_param )
    {
    	CImageControllerDlg* dlg = (CImageControllerDlg*)p_param;
    	::PostMessage(dlg->GetSafeHwnd(),WM_TEST,GetCurrentThreadId(),0);
    return 0;
    ... si tu veux d'autres "bouts" dis le moi, se sera avec plaisir :-)

  19. #19
    Membre éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Que fais-tu apès dans la méthode execute ?


    Edit : est-ce que tu n'attenderais pas un évènement par hasard ?

  20. #20
    Membre confirmé
    Inscrit en
    Juin 2004
    Messages
    111
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 111
    Par défaut
    Je parcours le dossier passé en paramètre par l'utilisateur en recursif. Dans chaque dossier, j'analyse la liste de toutes les images en effectuant differents traitement. Je sais c'est un peu vague, mais le code est vraiment très long!
    ha si, ce qui est peut-être interressant, c'est que je lance d'autres threads : un thread par image! sans dépasser le nombre de 4 threads. Le principe est des qu'un thread a fini de traiter une image, je lui donne une nouvelle image à traiter, jusqu'à ce qu'il n'y ait plus d'images à traiter.
    enfin, je ne pense pas que le problème vienne du code qui suit, parce que si dans la fonction "execute", juste après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    thread_time = AfxBeginThread( computeTime, this , THREAD_PRIORITY_NORMAL);
    je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    afxMessageBox("toto");
    alors j'ai les deux messages box qui apparaissent : "coucou", puis "toto".

Discussions similaires

  1. [MFC] Thread & memory leaks
    Par Racailloux dans le forum MFC
    Réponses: 7
    Dernier message: 15/03/2005, 12h44
  2. [MFC] Réaliser l'affichage d'un oscilloscope
    Par Racailloux dans le forum MFC
    Réponses: 7
    Dernier message: 04/03/2005, 00h52
  3. [MFC] probleme d'affichage en mode explorer
    Par ryu20 dans le forum MFC
    Réponses: 2
    Dernier message: 11/02/2005, 20h33
  4. Réponses: 3
    Dernier message: 11/02/2004, 12h50
  5. Thread et affichage direct3D plein écran
    Par Harry_polin dans le forum DirectX
    Réponses: 8
    Dernier message: 13/03/2003, 22h22

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