久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

用VC++在單文檔界面中創(chuàng)建多個視圖

 筱肆 2014-06-01

用VC++在單文檔界面中創(chuàng)建多個視圖

(2010-05-09 19:56:07)
標(biāo)簽:

it

分類: IT相關(guān)
用VC++在單文檔界面中創(chuàng)建多個視圖
北京 周偉     電腦報2000年第46期  
   
      一個單文檔界面中存在多個視圖,并且可以根據(jù)需要進行視圖的動態(tài)切換,,這是當(dāng)前比較流行的界面風(fēng)格,它可以滿足許多用戶在操作和顯示方面的需要。這種 界面風(fēng)格的主要代表軟件是Outlook    
      Express,。而用VC++實現(xiàn)這種風(fēng)格的界面有一定難度,,筆者就這個問題進行了研究,并歸納總結(jié)出兩種實現(xiàn)方法(這些代碼都在VC++    
      6.0下調(diào)試通過),,使用時關(guān)鍵注意步驟和實現(xiàn)思路,,不必拘泥于代碼的形式,。  
      方法一:靜態(tài)創(chuàng)建切換法  
        步驟描述:  
        1.在窗口顯示之前先將需要切換的所有的視圖對象創(chuàng)建好,除首先顯示的視圖以外,,其他在創(chuàng)建時都設(shè)置為不可見屬性,。  
        CMyWinApp::InitInstance()  
        {   ......  
        m_pViews[0]   =   pView1;  
        m_pViews[1]   =   (CView*)   new   CView2;  
        CDocument*   pCurrentDoc   =   ((CFrameWnd*)   m_pMainWnd)->GetActiveDocument();  
        //   初始化創(chuàng)建上下文相關(guān)指針  
        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,對新創(chuàng)建的視圖增加這個值,,注意對CSplitterWnd不能這樣使用  
        UINT   viewID[2];  
           viewID[1]   =   AFX_IDW_PANE_FIRST   +   1;  
        CRect   rect(0,   0,   0,   0);  
        for   (   int   nView=1;   nView<NUMVIEWS;   nView++   )  {  
        //   創(chuàng)建新的視圖,,創(chuàng)建的視圖在應(yīng)用中永久存在,直到應(yīng)用程序退出,,應(yīng)用程序會自動刪除新創(chuàng)建的視圖  
        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);  
        }  
        //   當(dāng)文檔模板創(chuàng)建視圖的時候,,會自動發(fā)送WM_INITIALUPDATE消息,因此對于我們自己創(chuàng)建的視圖,,需要人工發(fā)送這條消息  
        ((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   )   //   當(dāng)前沒有激活的視圖  
        return   NULL;  
        if   (   pNewView   ==   pActiveView   )   //   當(dāng)前視圖和需要切換的視圖相同  
        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;  
        }  
      方法二:動態(tài)創(chuàng)建切換法  
        步驟描述:  
        1.刪除當(dāng)前的視圖  
        首先需要獲得當(dāng)前視圖的指針,,不能使用GetActiveView()和GetActiveDocument()這兩個函數(shù),,當(dāng)前視圖有可能處在未激 活狀態(tài),  
        所以應(yīng)該使用EnumChildWindows這個Win32API函數(shù),,函數(shù)定義如下:  
        BOOL   EnumChildWindows(  
        HWND   hWndParent,   //   父窗口的句柄  
        WNDENUMPROC   lpEnumFunc,   //   用戶自定義回調(diào)函數(shù)  
        LPARAM   lParam   //   傳給回調(diào)函數(shù)的自定義參數(shù)  
        );  
        回調(diào)函數(shù)的定義如下:  
        BOOL   CALLBACK   EnumChildProc(  
        HWND   hwnd,   //   字窗口的句柄  
        LPARAM   lParam   //   自定義參數(shù)  
        );  
        EnumChildWindows函數(shù)遍歷父窗口的所有子窗口,,遞歸調(diào)用用戶定義的回調(diào)函數(shù),當(dāng)回調(diào)函數(shù)返回FALSE時,,停止遍歷,,  
        至于何時返回FALSE,這根據(jù)用戶自己需要編寫的回調(diào)函數(shù)來決定,。  
        刪除視圖使用DeleteWindow()這個函數(shù),,用delete也可以刪除,但還要其他底層的操作,,這里就不詳細介紹了,,因為刪除視圖使用 DeleteWindow()最合適、方便了,。在刪除視圖的時候還要注意不能將文檔同時自動刪除,。  
        刪除視圖的代碼如下:  
        {   ......  
        CWnd*   pWnd;  
        CWnd*   pWndToDelete;  
        //   使用EnumChildWindows查找從CView繼承的子窗口  
        ::EnumChildWindows(m_hWnd,   MyWndEnumProc,   (LPARAM)&(pWnd));  
        if(pWnd   ==   NULL)  
        {//   沒有發(fā)現(xiàn)子窗口  
        return   FALSE;}  
        //   發(fā)現(xiàn)子窗口,找到級別最高的子窗口,,即父窗口為CMainFrame的窗口  
        while(   lstrcmp(pWnd->GetRuntimeClass()->m_lpszClassName,   ″CMainFrame″)   )  
        {  
        pWndToDelete   =   pWnd;  
        pWnd   =   pWnd->GetParent();  
        }  
        //   確保視圖被刪除時文檔不被刪除  
        pDoc->m_bAutoDelete   =   FALSE;}  
              //   刪除視圖  
           pWndToDelete->DestroyWindow();  
           pDoc->m_bAutoDelete   =   TRUE;  
           ......  
           }  
           用戶定義的回調(diào)函數(shù):  
           BOOL   CALLBACK   MyWndEnumProc(HWND   hWnd,   LPARAM   ppWndLPARAM)  
           {  
           CWnd*   pWndChild   =   CWnd::FromHandlePermanent(hWnd);  
           CWnd**   ppWndTemp   =   (CWnd**)ppWndLPARAM;  
           if(   pWndChild   &&   pWndChild->IsKindOf(RUNTIME_CLASS(CView))   )  
           {  
           //   發(fā)現(xiàn)任何從CView繼承的子窗口,,將子窗口指針傳遞出去  
           *ppWndTemp   =   pWndChild;  
           //   停止繼續(xù)搜索    
           return   FALSE;  
           }  
           else  
           {  
           *ppWndTemp   =   NULL;  
           //   繼續(xù)搜索  
           return   TRUE;  
           }}  
           2.創(chuàng)建新的視圖  
           CDocument*   pCurrentDoc   =   ((CFrameWnd*)   m_pMainWnd)->GetActiveDocument();  
           //   初始化創(chuàng)建上下文相關(guān)指針  
           CCreateContext   newContext;  
           newContext.m_pNewViewClass   =   RUNTIME_CLASS(CView1);  
           newContext.m_pCurrentDoc   =   pCurrentDoc;  
           newContext.m_pNewDocTemplate   =   NULL;  
           newContext.m_pLastView   =   NULL;  
           newContext.m_pCurrentFrame   =   NULL;  
           CView*   pNewView   =   STATIC_DOWNCAST(CView,   CreateView(&newContext));  
           if(   pNewView   ==   NULL   )  
           {  
           return   FALSE;  
           }  
           //    
      使用CreateView創(chuàng)建的視圖不能自動調(diào)用OnInitialUpdate函數(shù),需要人工調(diào)用OnInitialUpdate函數(shù)或者發(fā)送 WM_INITIALUPDATE消息  
           pNewView->OnInitialUpdate();    
           //   使用CreateView創(chuàng)建的視圖不會自動顯示并且激活,,需要人工操作  
           pNewView->ShowWindow(SW_SHOW);    
           SetActiveView(pNewView);  
           RecalcLayout();  
        注:RUNTIME_CLASS宏含義  
        每一個從CObject類繼承的類,,在定義DECLARE_DYNAMIC、DECLARE_DYNCREATE、DECLARE_SERIAL三個 中任意一個宏時都會產(chǎn)生一個CRuntimeClass結(jié)構(gòu)的靜態(tài)對象,,RUNTIME_CLASS返回的就是這個對象的指針,,這個對象包含了其基類和本 身在運行時刻的信息。以上是筆者在編寫多個視應(yīng)用在單文檔的程序時整理出來的兩種方法,,因為VC++的強大和靈活,,筆者相信還有更加巧妙的方法實現(xiàn)這個功 能,,希望這篇文章能夠起到拋磚引玉的作用,,也希望廣大VC++編程愛好者對本文能夠給予批評和指正。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多