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 :

BIG HELP : changer de vue


Sujet :

MFC

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 114
    Par défaut BIG HELP : changer de vue
    Bonjour,

    j'ai un gros souci. Je galère depuis ce matin sur mon application pour faire fonctionner le changement de vue sur une application SDI.
    Je précise que je développe sur Pocket PC car cela a peut etre son importance.

    J'ai déclaré une classe dérivant de CFrameWnd qui me permet de switcher entre différentes vues :
    Voici le code
    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
     
    CBaseFrame::stViewInfo CBaseFrame::m_ViewInfo[] = 
    {
    	{ IDD_MAIN_FORM,		CBaseFrame::CREATE_ONCE,		AFX_IDW_PANE_FIRST + 0,	NULL },
    	{ IDD_WELCOME_DLG,		CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 1,	NULL },
    	{ IDD_WIZZARD_DLG,		CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 2, NULL },
    	{ IDD_OPTIONS_DLG,		CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 3, NULL },
    	{ IDD_CNX_DLG,			CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 4, NULL },
    	{ IDD_SCHEDULE_DLG,		CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 5, NULL },
    	{ IDD_HISTORY_DLG,		CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 6, NULL },
    	{ IDD_ABOUT_DLG,		CBaseFrame::CREATE_AND_DESTROY,	AFX_IDW_PANE_FIRST + 7, NULL },
     
     
     
    };
     
     
    BOOL CBaseFrame::InitViews(UINT a_FirstViewId)
    {
    	BOOL		bRet = FALSE;
    	CView*		pCurView = NULL;
    	int			iCurViewIdx = -1;
     
     
    	if ((m_pMainApp != NULL) ){
    		m_pFrame = static_cast<CFrameWnd*>(m_pMainApp->m_pMainWnd);
    		if (m_pFrame != NULL){
    			pCurView = m_pFrame->GetActiveView();
    			if (pCurView != NULL){
    				iCurViewIdx = GetIndexFromId( a_FirstViewId );
    				if (iCurViewIdx != -1){
    					m_ViewInfo[ iCurViewIdx ].pView = pCurView;
    					bRet = TRUE;
    				}
    			}
    		} 
    	}
     
    	return bRet;
    }
     
    CView* CBaseFrame::CreateView( UINT a_ViewId, int a_iIndex )
    {
    	CView*		l_pView = NULL;
    	CDocument* l_pCurrentDoc = m_pFrame->GetActiveDocument();
     
    	// Initialize a CCreateContext to point to the active document.
    	// With this context, the new view is added to the document
    	// when the view is created in CView::OnCreate().
    	CCreateContext newContext;
    	newContext.m_pNewViewClass = NULL;
    	newContext.m_pNewDocTemplate = NULL;
    	newContext.m_pLastView = NULL;
    	newContext.m_pCurrentFrame = m_pFrame;
    	newContext.m_pCurrentDoc = l_pCurrentDoc;
     
    	CRect rect(0, 0, 0, 0); // gets resized later
     
    	switch (a_ViewId)
    	{
    	case IDD_MAIN_FORM:				{ l_pView = new CMainView();		break; }
    	case IDD_WELCOME_DLG:			{ l_pView = new CWelcomeView();		break; }
    	case IDD_WIZZARD_DLG:			{ l_pView = new CBackupSimView();	break; }
    	case IDD_OPTIONS_DLG:			{ l_pView = new COptionsView();		break; }
    	case IDD_CNX_DLG:				{ l_pView = new CConnectionView();	break; }
    	case IDD_SCHEDULE_DLG:			{ l_pView = new CScheduleView();	break; }
    	case IDD_HISTORY_DLG:			{ l_pView = new CHistoryView();		break; }
    	case IDD_ABOUT_DLG:				{ l_pView = new CAboutView();		break; }
    	}
     
    	// views are created with the style of AFX_WS_DEFAULT_VIEW
    	// In MFC 4.0, this is (WS_BORDER | WS_VISIBLE | WS_CHILD)
    	l_pView->Create(NULL, NULL,
    		(AFX_WS_DEFAULT_VIEW & ~WS_VISIBLE),
    		rect, m_pMainApp->m_pMainWnd,
    		m_ViewInfo[a_iIndex].iSysViewId, &newContext);
     
    	return l_pView;
    }
     
    //************************************************************************
    // CMainApp::OnSwitchView()
    //
    // Purpose:
    //        Switch from one view to another.  Save and validate current view's
    //        data to document - fail if validation fails.
    //
    // Parameters:
    //        UINT nIndex (of view to switch to)
    //***********************************************************************
    LRESULT CBaseFrame::OnSwitchView( WPARAM wParam, LPARAM lParam )
    {
    	int		iCurViewIdx	= 0;
    	int		iNewViewIdx	= 0;
    	CView*	pCurView = NULL;
    	CView*	pNewView	= NULL;
    	BOOL	bDestroyOldView = FALSE;
    	UINT	ViewId = (UINT) wParam;
    	CDocument* pCurrentDoc = GetActiveDocument();
    	BOOL	bAutoDelete = FALSE;
     
     
    	//Get current active view
    	pCurView = m_pFrame->GetActiveView();
    	if ( pCurView == NULL)
    		return 0L;
     
    	//Get Curview and NextView index 
    	iCurViewIdx = GetIndexFromView( pCurView );
    	iNewViewIdx = GetIndexFromId( wParam );
    	if ((iCurViewIdx == -1) || (iNewViewIdx == -1))
    		return 0L;
     
    	TRACE( _T("CViewMgr::SwitchView : pCurView[%d] = 0x%x\r\n"), iCurViewIdx, pCurView );
    	pNewView = m_ViewInfo[iNewViewIdx].pView;
     
    	// View is already displayed
    	if ( pNewView == pCurView ){    
    		return 0L/*pCurView*/;
    	}
     
     
     
     
    	// New view is NULL - we must create it
    	if ( pNewView == NULL ){
    		pNewView = CreateView( ViewId, iNewViewIdx);
    		TRACE( _T("pNewView = 0x%x\r\n"), pNewView );
    		if (pNewView != NULL){
    			// Save new created view
    			m_ViewInfo[iNewViewIdx].pView = pNewView;
    		}
    	}//pView == NULL
     
     
    	// exchange view window ID's so RecalcLayout() works
    	UINT temp = ::GetWindowLong(pCurView->m_hWnd, GWL_ID);
    	::SetWindowLong(pCurView->m_hWnd, GWL_ID,
    		::GetWindowLong(pNewView->m_hWnd, GWL_ID));
    	::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
     
    	// Hide Old view
    	pCurView->ShowWindow(SW_HIDE);
     
    	//OnInitialUpdate() is not called as a result of calling CreateView() above. 
    	//It is not always called by the framework, so it is called here:
    	pNewView->OnInitialUpdate();
     
    	// Now show the new view
    	pNewView->ShowWindow(SW_SHOW);
    	m_pFrame->SetActiveView(pNewView);
    	m_pFrame->RecalcLayout();
    	pNewView->Invalidate();
     
    	//Make sure that the document won't be destroyed when the view is destroyed.
    	//m_bAutoDelete is a public, but non-documented member of CDocument.
    	if ( m_ViewInfo[iCurViewIdx].eCreationMode == CREATE_AND_DESTROY){
    		BOOL bAutoDelete = pCurrentDoc->m_bAutoDelete;
    		pCurrentDoc->m_bAutoDelete = FALSE;
    		pCurView->DestroyWindow();
    		pCurrentDoc->m_bAutoDelete = bAutoDelete;
    	}
     
    	// try to destroy old view
    	//if ( m_ViewInfo[iCurViewIdx].eCreationMode == CREATE_AND_DESTROY){
    	//	::SendMessage(pCurView->m_hWnd, WM_DESTROY, 0, 0);
    	//	//pCurView->DestroyWindow();
    	//	m_ViewInfo[iCurViewIdx].pView = NULL;
    	//}
     
    	return 0L/*pNewView*/;
    }
    Le changement de vue se passe bien par contre la destruction de l'ancienne vue échoue.

    A chaque fois j'ai l'assert suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    LRESULT CALLBACK
    AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {
    	// special message which identifies the window as using AfxWndProc
    	if (nMsg == WM_QUERYAFXWNDPROC)
    		return 1;
     
    	// all other messages route through message map
    	CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
     
    -->   ASSERT(pWnd != NULL && pWnd->m_hWnd == hWnd);
    ...
    }

    Je fais tout comme il faut pourtant, je detruis la vue apres l'avoir échangée avec la nouvelle, j'échange les IDs, je fais gaffe a passer bAutoDelete a FALSE.
    Donc je ne comprends plus.

    Lorsque je suis dans ma vue CWelcomeView j'essaye de switcher sur ma MainView comme ceci :
    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
     
    void CWelcomeView::OnYesCommand()
    {
    	Ret_t l_iRet = SM_ERR_OK;
     
     
    	// Ask user if they want to backup their SIM contacts
    	if ( TBackupSIMManager::GetInstance()->HasSIMContacts() )
    	{
    		CViewMgr::GetInstance()->SwitchView( IDD_WIZZARD_DLG ); 
    	}
    	else
    	{
    		TBackupSIMManager::DestroyInstance();
    		// TERMS have been accepted so now we can enable AUTOSYNC mode
    		l_iRet = CSyncClient::GetInstance()->ActivateAutoSyncEx( true );
    		if (l_iRet == SM_ERR_OK){
    			// Save Syncing settings
    			l_iRet = CSyncClient::GetInstance()->SaveCustomParam();
    		}
    	}
     
     
    ((CBaseFrame*)AfxGetMainWnd())->OnSwitchView( IDD_MAIN_FORM, 0 );
    ////::PostMessage( AfxGetMainWnd()->m_hWnd, WM_SWITCH_VIEW, IDD_MAIN_FORM, 0);
    ((CBaseFrame*)AfxGetMainWnd())->GetActiveDocument()->UpdateAllViews(NULL, INIT_SCREEN);
    }

  2. #2
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 527
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 527
    Par défaut
    A mon avis il y a un plantage car lorsque tu appelles SwitchView le programme est dans le "vide"
    Tu appelles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pCurView = m_pFrame->GetActiveView();
    d'ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    -->   ASSERT(pWnd != NULL && pWnd->m_hWnd == hWnd);
    Alors que tu viens de détruire la CView courante! Ce qui fait que l'application n'a aucune vue courante.
    Met un point d'arrêt (f9) sur cette ligne je suis sur que m_pFrame=NULL
    La seule solution c'est de créer temporairement une CView déclarée globale..

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 6
    Par défaut
    Citation Envoyé par Mat.M
    A mon avis il y a un plantage car lorsque tu appelles SwitchView le programme est dans le "vide"
    Tu appelles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pCurView = m_pFrame->GetActiveView();
    d'ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    -->   ASSERT(pWnd != NULL && pWnd->m_hWnd == hWnd);
    Alors que tu viens de détruire la CView courante! Ce qui fait que l'application n'a aucune vue courante.
    Met un point d'arrêt (f9) sur cette ligne je suis sur que m_pFrame=NULL
    La seule solution c'est de créer temporairement une CView déclarée globale..

    Bon en fait c le mystère de l'informatique maintenant ca fonctionne.
    Et juste pour info m_pFrame ne peut pas etre null sinon je n'aurais pas un assert mais un crash car je déférence le pointeur juste avant.

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

Discussions similaires

  1. Changer la vue de source de données d'un cube
    Par phenomeno dans le forum SSAS
    Réponses: 1
    Dernier message: 30/10/2012, 15h40
  2. [RCP]Comment changer de vue avec mon plugin ?
    Par Cpt Anderson dans le forum Eclipse Platform
    Réponses: 14
    Dernier message: 15/12/2010, 12h43
  3. Help : changer la couleur d'une point dans un Nuages de point
    Par yukka dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 16/05/2007, 11h30
  4. changer de vue et de doc
    Par LesLemmings dans le forum MFC
    Réponses: 10
    Dernier message: 07/05/2007, 12h02
  5. SDI - changer de vue en cliquant sur un bouton
    Par Psykotik dans le forum MFC
    Réponses: 3
    Dernier message: 29/11/2005, 16h09

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