| 導購 | 订阅 | 在线投稿
分享
 
 
 

用Visual C++在單文檔界面中創建視圖

來源:互聯網  2008-06-01 01:54:34  評論

一個單文檔界面中存在多個視圖,並且可以根據需要進行視圖的動態切換,這是當前比較流行的界面風格,它可以滿足許多用戶在操作和顯示方面的需要。這種界面風格的主要代表軟件是Outlook EXPress。而用VC++實現這種風格的界面有一定難度,筆者就這個問題進行了研究,並歸納總結出兩種實現方法(這些代碼都在VC++ 6.0下調試通過),使用時要害注重步驟和實現思路,不必拘泥于代碼的形式。

方法一:靜態創建切換法

步驟描述:

1.在窗口顯示之前先將需要切換的所有的視圖對象創建好,除首先顯示的視圖以外,其他在創建時都設置爲不可見屬性。

CMyWinApp::InitInstance()

{ ......

m_pViews[0] = pView1;

m_pViews[1] = (CView*) new CView2;

CDocument* pCurrentDoc = ((CFrameWnd*) m_pMainWnd)->GetActiveDocument();

// 初始化創建上下文相關指針

CCreateContext newContext;

newContext.m_pNewViewClass = NULL;

newContext.m_pNewDocTemplate = NULL;

newContext.m_pLastView = NULL;

newContext.m_pCurrentFrame = NULL;

newContext.m_pCurrentDoc = pCurrentDoc;

// 最初激活視的ID爲AFX_IDW_PANE_FIRST,

//對新創建的視圖增加這個值,注重對CSplitterWnd不能這樣使用

UINT viewID[2];

viewID[1] = AFX_IDW_PANE_FIRST + 1;

CRect rect(0, 0, 0, 0);

for ( int nView=1; nView<NUMVIEWS; nView++ ){

// 創建新的視圖,創建的視圖在應用中永久存在,直到應用程序退出,

//應用程序會自動刪除新創建的視圖

m_pViews[nView]->Create(NULL, NULL,

(AFX_WS_DEFAULT_VIEW & ~WS_VISIBLE),

// AFX_WS_DEFAULT_VIEW代表(WS_BORDER WS_VISIBLE WS_CHILD)

rect, m_pMainWnd, viewID[nView], &newContext);

}

// 當文檔模板創建視圖的時候,會自動發送WM_INITIALUPDATE消息,

//因此對于我們自己創建的視圖,需要人工發送這條消息

((CForm2*)m_pViews[1])->OnInitialUpdate();

((CVswapView*)m_pViews[2])->OnInitialUpdate();

......

}

2.視圖的切換

CView* CMyWinApp::SwitchView( UINT nIndex )

{

ASSERT( nIndex >=0 && nIndex < NUMVIEWS );

CView* pNewView = m_pViews[nIndex];

CView* pActiveView =((CFrameWnd*) m_pMainWnd)->GetActiveView();

if ( !pActiveView ) // 當前沒有激活的視圖

return NULL;

if ( pNewView == pActiveView ) // 當前視圖和需要切換的視圖相同

return pActiveView;

// 交換視圖的窗口ID,使RecalcLayout()可以工作

UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);

::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));

::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);

// 顯示新的視圖,隱藏前一個視圖

pActiveView->ShowWindow(SW_HIDE);

pNewView->ShowWindow(SW_SHOW);

((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);

((CFrameWnd*) m_pMainWnd)->RecalcLayout();

pNewView->Invalidate();

return pActiveView;

}方法二:動態創建切換法

步驟描述:

1.刪除當前的視圖

首先需要獲得當前視圖的指針,不能使用GetActiveView()和GetActiveDocument()這兩個函數,當前視圖有可能處在未激活狀態,

所以應該使用EnumChildWindows這個Win32API函數,函數定義如下:

  一個單文檔界面中存在多個視圖,並且可以根據需要進行視圖的動態切換,這是當前比較流行的界面風格,它可以滿足許多用戶在操作和顯示方面的需要。這種界面風格的主要代表軟件是Outlook EXPress。而用VC++實現這種風格的界面有一定難度,筆者就這個問題進行了研究,並歸納總結出兩種實現方法(這些代碼都在VC++ 6.0下調試通過),使用時要害注重步驟和實現思路,不必拘泥于代碼的形式。   方法一:靜態創建切換法   步驟描述:   1.在窗口顯示之前先將需要切換的所有的視圖對象創建好,除首先顯示的視圖以外,其他在創建時都設置爲不可見屬性。     CMyWinApp::InitInstance()   { ......   m_pViews[0] = pView1;   m_pViews[1] = (CView*) new CView2;   CDocument* pCurrentDoc = ((CFrameWnd*) m_pMainWnd)->GetActiveDocument();   // 初始化創建上下文相關指針   CCreateContext newContext;   newContext.m_pNewViewClass = NULL;   newContext.m_pNewDocTemplate = NULL;   newContext.m_pLastView = NULL;   newContext.m_pCurrentFrame = NULL;   newContext.m_pCurrentDoc = pCurrentDoc;   // 最初激活視的ID爲AFX_IDW_PANE_FIRST,   //對新創建的視圖增加這個值,注重對CSplitterWnd不能這樣使用   UINT viewID[2];    viewID[1] = AFX_IDW_PANE_FIRST + 1;   CRect rect(0, 0, 0, 0);   for ( int nView=1; nView<NUMVIEWS; nView++ )  {   // 創建新的視圖,創建的視圖在應用中永久存在,直到應用程序退出,   //應用程序會自動刪除新創建的視圖   m_pViews[nView]->Create(NULL, NULL,   (AFX_WS_DEFAULT_VIEW & ~WS_VISIBLE),   // AFX_WS_DEFAULT_VIEW代表(WS_BORDER WS_VISIBLE WS_CHILD)   rect, m_pMainWnd, viewID[nView], &newContext);   }   // 當文檔模板創建視圖的時候,會自動發送WM_INITIALUPDATE消息,   //因此對于我們自己創建的視圖,需要人工發送這條消息   ((CForm2*)m_pViews[1])->OnInitialUpdate();   ((CVswapView*)m_pViews[2])->OnInitialUpdate();   ......   }   2.視圖的切換     CView* CMyWinApp::SwitchView( UINT nIndex )   {   ASSERT( nIndex >=0 && nIndex < NUMVIEWS );   CView* pNewView = m_pViews[nIndex];   CView* pActiveView =((CFrameWnd*) m_pMainWnd)->GetActiveView();   if ( !pActiveView ) // 當前沒有激活的視圖   return NULL;   if ( pNewView == pActiveView ) // 當前視圖和需要切換的視圖相同   return pActiveView;   // 交換視圖的窗口ID,使RecalcLayout()可以工作   UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);   ::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));   ::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);   // 顯示新的視圖,隱藏前一個視圖   pActiveView->ShowWindow(SW_HIDE);   pNewView->ShowWindow(SW_SHOW);   ((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);   ((CFrameWnd*) m_pMainWnd)->RecalcLayout();   pNewView->Invalidate();   return pActiveView;   }  方法二:動態創建切換法     步驟描述:   1.刪除當前的視圖   首先需要獲得當前視圖的指針,不能使用GetActiveView()和GetActiveDocument()這兩個函數,當前視圖有可能處在未激活狀態,   所以應該使用EnumChildWindows這個Win32API函數,函數定義如下:
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有