首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

MFC 應用程式中指標的取得與使用技巧

     編輯:關於VC++

VC 程式設計對初學者最大的障礙是訊息機制與指標取得操作。這些內容幾乎是每本 VC 入門書必講的,透過 MSDN 也能解決大部分問題。以下分享個人在程式設計中指標使用的體會,錯誤處請指正。

一般使用 Wizard 產生的 MFC App Wizard (exe) 架構,無論單一或多文件,都存在指標取得與操作問題。使用到的類別需包含對應標頭檔。首先取得本類別(視圖、文件、對話方塊皆支援)實例指標 this,目的在於透過類別函數將指標傳遞給其他類別或函數,方便在非本類別中操作本類別功能。

常見指標取得方法

  1. 在 View 中取得 Doc 指標:CYouSDIDoc *pDoc = GetDocument();(一個視圖對應一個文件)
  2. 在 App 中取得 MainFrame 指標:CWinApp 的 m_pMainWnd 即為 MainFrame 指標,或 CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd();
  3. 在 View 中取得 MainFrame 指標:CMainFrame *pMain = (CMainFrame *)AfxGetApp()->m_pMainWnd;
  4. 取得已建立的 View 指標:
    CMainFrame *pMain = (CMainFrame *)AfxGetApp()->m_pMainWnd;
    CYouView *pView = (CYouView *)pMain->GetActiveView();
  5. 取得目前文件指標:CDocument *pCurrentDoc = (CFrameWnd *)m_pMainWnd->GetActiveDocument();
  6. 取得狀態列與工具列指標:
    CStatusBar *pStatusBar = (CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);
    CToolBar *pToolBar = (CToolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);
  7. 若框架已加入工具列/狀態列成員變數:
    (CMainFrame *)GetParent()->m_wndToolBar;
    (CMainFrame *)GetParent()->m_wndStatusBar;
  8. 在 MainFrame 取得選單指標:CMenu *pMenu = m_pMainWnd->GetMenu();
  9. 在任何類別中取得應用程式類別:AfxGetApp()

從文件類別取得視圖類別指標

目的通常為控制同一文件多個視圖的定位問題(特別是文字處理 CEditView 產生多視圖時)。CDocument 提供兩個函數:

virtual POSITION GetFirstViewPosition() const;
virtual CView* GetNextView(POSITION& rPosition) const;

注意:GetNextView() 參數用引用,執行後值會改變。GetFirstViewPosition() 傳回第一個視圖位置(POSITION 型別),GetNextView() 雙重功能:傳回下一個視圖指標,並透過引用改變傳入的 POSITION 參數值。

範例(需定義 POSITION 變數輔助):

CTestView* pTestView;
POSITION pos = GetFirstViewPosition();
pTestView = GetNextView(pos);

執行後 pos = NULL(無下一視圖)。但此寫法通用性與安全性不足。當需在多視圖中傳回指定類別指標時,需遍歷所有視圖直到找到為止。判斷指標是否指向某類別實例,可用 IsKindOf():

pView->IsKindOf(RUNTIME_CLASS(CTestView));

封裝為文件類別成員函數:

CView* CTestDoc::GetView(CRuntimeClass* pClass)
{
    CView* pView;
    POSITION pos = GetFirstViewPosition();
    while (pos != NULL) {
        pView = GetNextView(pos);
        if (pView->IsKindOf(pClass)) break;
    }
    if (!pView->IsKindOf(pClass)) {
        AfxMessageBox("Connt Locate the View.\r\n https://www.VCKBASE.com");
        return NULL;
    }
    return pView;
}

使用方式:CTestView* pTestView = (CTestView*)GetView(RUNTIME_CLASS(CTestView));。RUNTIME_CLASS 宏將類別名稱轉為 CRuntimeClass 指標。強制型別轉換為安全考量。

從一個視圖取得另一視圖指標

綜合以上,以文件類別作中介:先取得文件指標,再用文件的視圖定位函數取得另一視圖。同樣可封裝為函數:

CView* CTestAView::GetView(CRuntimeClass* pClass)
{
    CTestDoc* pDoc = (CTestDoc*)GetDocument();
    CView* pView;
    POSITION pos = pDoc->GetFirstViewPosition();
    while (pos != NULL) {
        pView = pDoc->GetNextView(pos);
        if (pView->IsKindOf(pClass)) break;
    }
    if (!pView->IsKindOf(pClass)) {
        AfxMessageBox("Connt Locate the View.");
        return NULL;
    }
    return pView;
}

使用:CTestBView* pTestBView = (CTestView*)GetView(RUNTIME_CLASS(CTestBView));

多文件模板相關

單一文件也可加入多文件模板,但通常用 MDI 開發。方法與視圖取得類似:

  • CWinApp::GetFirstDocTemplatePosition() 取得第一個文件模板位置
  • CWinApp::GetNextDocTemplate() 取得 CDocTemplate 指標
  • CDocTemplate::GetFirstDocPosition() / GetNextDoc() 遍歷文件
  • CDocument::GetDocTemplate() 取得文件模板指標
  • CDocument::GetFirstViewPosition() / GetNextView() 遍歷視圖

本文內容多來自網路與 MSDN,整理旨在讓大家不用再搜尋,列出標題方便操作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved