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 537
    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 537
    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