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 :

Problème slider MFC avec visual studio


Sujet :

MFC

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 41
    Par défaut Problème slider MFC avec visual studio
    Bonjour,


    je suis actuellement en train de réaliser un lecteur multimédia en C++.
    J'utilise pour l'interface graphique les MFC, épaulé par l'éditeur graphique de ressources de visual studio 2005.
    Pour la lecture, j'utilise directshow (enfin VMR9 qui est un wrapper mais ca change presque rien).
    Mon problème est le suivant :
    Pour réaliser l'interface graphique, comme je l'ai dit plus haut j'utilise l'éditeur de ressources. Cette interface est composée d'une fenètre dans laquelle j'ai ajouté une barre de menu en haut (qd on crée un projet MFC ds VS2005 ca le met automatiquement), une DialogBar juste en dessous contenant un bouton et le fameux slider, puis enfin d'une zone dans laquelle s'affiche la vidéo. Le slider doit se déplacer lorsque le fichier est en cours de lecture et doit aussi permettre de changer la position de lecture.

    Le gros problème est que , comme je l'ai crée graphiquement avec l'éditeur de ressources, je n'ai pas crée le slider à la main en faisant (c'est comme ca que je l'ai vu sur certains tutos) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CSliderCtrl m_objSeekBar;
    Je ne peux pas manipuler le slider directement en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    m_objSeekBar.SetPos(sliderTick);
    m_objSeekBar.GetPos();
    m_objSeekBar.SetRange(0,100);
    ...etc...
    En effet, en regardant de plus près le code produit par l'éditeur graphique (fichier .rc), ca ressemble à ca :
    IDD_DIALOGBAR DIALOGEX 0, 0, 330, 26
    STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
    FONT 8, "MS Shell Dlg", 0, 0, 0x0
    BEGIN
    CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,137,7,133,15 //ici !
    PUSHBUTTON "Play",IDC_PLAY,10,7,50,14
    PUSHBUTTON "Bouger",IDC_BUTTON1,75,7,50,14
    END

    Il n'y a donc pas création d'objet que je peux manipuler.
    J'ai essayé de remédier à ca en utilisant un code que j'avais trouvé ailleurs et qui est censé contourner ce problème (voir méthodes OnTimer et OnNMReleasedcaptureSlider1, je met tout pour le contexte):
    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
     
    // MainFrm.cpp : implémentation de la classe CMainFrame
    //
     
    #include "stdafx.h"
    #include "Superjoe MPv3.h"
     
    #include "MainFrm.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
     
     
    // CMainFrame
     
    IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
     
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    	ON_WM_CREATE()
    	ON_WM_SETFOCUS()
    	ON_COMMAND(ID_FICHIER_OPEN, &CMainFrame::OnFichierOpen)
    	ON_COMMAND(ID_ACTIONS_PLAY, &CMainFrame::OnActionsPlay)
    	ON_BN_CLICKED(IDC_PLAY, &CMainFrame::OnBnClickedPlay)
    	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER1, &CMainFrame::OnNMReleasedcaptureSlider1)
    	ON_BN_CLICKED(IDC_BUTTON1, &CMainFrame::OnBnClickedButton1)
    END_MESSAGE_MAP()
     
    static UINT indicators[] =
    {
    	ID_SEPARATOR,           // indicateur de la ligne d'état
    	ID_INDICATOR_CAPS,
    	ID_INDICATOR_NUM,
    	ID_INDICATOR_SCRL,
    };
     
     
    // construction ou destruction*de CMainFrame
     
    CMainFrame::CMainFrame()
    {
    	// TODO : ajoutez ici le code d'une initialisation de membre
    }
     
    CMainFrame::~CMainFrame()
    {
    }
     
     
    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    		return -1;
    	// créer une vue de manière qu'elle occupe la zone cliente du frame
    	if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
    		CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
    	{
    		TRACE0("Impossible de créer la fenêtre d'affichage\n");
    		return -1;
    	}
     
    	if (!m_wndStatusBar.Create(this) ||
    		!m_wndStatusBar.SetIndicators(indicators,
    		  sizeof(indicators)/sizeof(UINT)))
    	{
    		TRACE0("Impossible de créer la barre d'état\n");
    		return -1;      // échec de la création
    	}
     
    	if (!m_wndDlgBar.Create(this, IDD_DIALOGBAR, 
    		CBRS_ALIGN_TOP, AFX_IDW_DIALOGBAR))
    	{
    		TRACE0("Failed to create dialogbar\n");
    		return -1;		// fail to create
    	}
    	m_graph.SetMediaWindow(m_wndView.GetSafeHwnd());
     
    	return 0;
    }
     
    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    	if( !CFrameWnd::PreCreateWindow(cs) )
    		return FALSE;
    	// TODO : changez ici la classe ou les styles Window en modifiant
    	//  CREATESTRUCT cs
     
    	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
    	cs.lpszClass = AfxRegisterWndClass(0);
    	return TRUE;
    }
     
     
    // diagnostics pour CMainFrame
     
    #ifdef _DEBUG
    void CMainFrame::AssertValid() const
    {
    	CFrameWnd::AssertValid();
    }
     
    void CMainFrame::Dump(CDumpContext& dc) const
    {
    	CFrameWnd::Dump(dc);
    }
     
    #endif //_DEBUG
     
     
    // gestionnaires de messages pour CMainFrame
     
    void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
    {
    	// passe le focus à la fenêtre d'affichage
    	m_wndView.SetFocus();
    }
     
    BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
    {
    	// laisser la priorité à la vue pour cette commande
    	if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
    		return TRUE;
     
    	// sinon, la gestion par défaut est utilisée
    	return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
     
     
     
    void CMainFrame::OnFichierOpen()
    {
    	// TODO : ajoutez ici le code de votre gestionnaire de commande
    	CFileDialog fileDlg(TRUE,
    						NULL,
    						NULL,
    						OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
    						"All Media Files|*.jpg;*.jpeg;*.gif;*.tga;*.bmp;*.dib;*.avi;*.divx;*.mpg;*.mpeg|Images Files|*.jpg;*.jpeg;*.gif;*.tga;*.bmp;*.dib;*.png|Videos Files|*.avi;*.divx;*.mpg;*.mpeg|All Files|*.*||",
    						this);
    	if (fileDlg.DoModal() == IDOK) {
    		m_graph.SetMediaFile(fileDlg.GetPathName(), 0);
    		m_graph.SetLayerZOrder(0, 0);
    		m_graph.m_pMediaSeeking->GetDuration(&m_fileDuration);
    	}
    }
     
    void CMainFrame::OnActionsPlay()
    {
    	// TODO : ajoutez ici le code de votre gestionnaire de commande
    	m_graph.PlayGraph();
    }
     
    void CMainFrame::OnBnClickedPlay()
    {
    	// TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle
    	m_graph.PlayGraph();
    }
     
    void CMainFrame::OnTimer(UINT nIDEvent)
    {  //pour faire bouger le slider en fonction de la position de lecture du fichier
    	LONGLONG timeNow;
    	m_graph.m_pMediaSeeking->GetCurrentPosition(&timeNow);
    	long sliderTick = (long)((timeNow * 100) / m_fileDuration);
    	CSliderCtrl *pSlider=static_cast<CSliderCtrl *>(GetDlgItem(IDC_SLIDER1));
    	//CWnd* slid=GetDlgItem(IDC_SLIDER1);   ne marche pas non+
    	((CSliderCtrl*)slid)->SetRange(0,100);
     
    	((CSliderCtrl*)slid)->SetPos(sliderTick);
    }
     
     
    void CMainFrame::OnNMReleasedcaptureSlider1(NMHDR *pNMHDR, LRESULT *pResult)  //bouger le slider pour modifier postion de lecture(contraire precedent)
    {
    	// TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle
    	CSliderCtrl *pSlider=static_cast<CSliderCtrl *>(GetDlgItem(IDC_SLIDER1));
     
     
    	// CWnd* slid=GetDlgItem(IDC_SLIDER1); ne marche pas non+
    	int n= ((CSliderCtrl*)slid)->GetPos();
    	m_graph.SetPos(n*10000000);    //surement pas tres correct, c'est juste pour tester pr l'instant
    	*pResult = 0;
     
    }
     
    void CMainFrame::OnBnClickedButton1()
    {
    	// TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle
    	LONGLONG temps = 60*10000000; //60 est le tps en sec, 10000000 pr le mettre en 100eme de nanosec
    	m_graph.SetPos(temps);
    }
    Cependant lorsque je bouge le curseur, avec ou sans lecture d'un fichier, je me retrouve avec une erreur :
    Exception non gérée à 0x68fcf60a (mfc80d.dll) dans Superjoe MPv3.exe*: 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000020.

    Si j'enlève le code des méthodes OnNMReleasedcaptureSlider1 et OnTimer, je peux bouger le slider mais il ne se passe rien (normal^^).

    Quelqu'un saurait il donc comment utiliser correctement le slider en le créant uniquement avec l'éditeur de ressources ^^?
    Désolé s'il ya de grosses bourdes dans le code, je n'excelle pas encore en C++ , encore moins sur les MFC ^^
    Merci de vos réponses !

  2. #2
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 41
    Par défaut
    Une tite réponse ? non?

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 41
    Par défaut
    up :/

  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
    salut,
    ton projet est de type SDI ?
    pourquoi gérer les évènements du slider sur la mainframe ?
    ce n'est pas l'endroit approprié et ton GetDlgItem(IDC_SLIDER1) doit certainement renvoyer null, d'ou ton plantage.
    que tu dois pouvoir constater en mode debug trace.
    les traitements avec les contrôles sont a faire dans la vue qui les gères...

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 41
    Par défaut
    salut !

    Mon projet est bien de type SDI.
    Les fichiers .h et .cpp présents dans mon projet sont :
    VMR9Graph.h/.cpp (un wrapper pour DShow)
    MainFrm.h/.cpp (la où je traite les boutons - et le slider -de la m_wndDlgBar)
    Ressource.h
    stdafx.h/.cpp
    Superjoe MPv3.h/.cpp (Définit les comportements de classe pour l'application)
    ChildView.h/.cpp (contient la zone qui permet de lire la vidéo, se trouve en dessous de la dialogBar)
    Et Superjoe MPv3.rc pour les ressouces.

    En fait je traite tous les messages des boutons/slider dans le MainFrm car j'ai vu pas mal d'exemples où ils le traitaient directement dedans.
    Faudrait il le traiter dans le Superjoe MPv3 ? ou créer une vue exprès pour chaque composant?

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/06/2009, 11h56
  2. problème de compilation avec Visual Studio 6.0 (Win.XP)
    Par KINGINFO dans le forum SL & STL
    Réponses: 1
    Dernier message: 29/11/2008, 01h01
  3. Démarrer avec les MFC avec Visual studio 2005 (Volume 2) introuvable
    Par simonphenix dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 5
    Dernier message: 21/05/2008, 19h01
  4. Réponses: 2
    Dernier message: 15/03/2007, 12h10
  5. [MFC] MFC avec visual studio 2003
    Par leoninho dans le forum MFC
    Réponses: 9
    Dernier message: 11/03/2006, 18h13

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