MFC實現MDI多檢視介面 (一)
MDI (Multiple Document Interface) 是Windows 界 面 的 一 種 規 範, 它 建 立 多 個 窗 口 來 瀏 覽 文 檔 數 據, 如Windows 中 的Program Manager 等 都 是 按MDI 規 範 實 現 的。 在 實 際 工 程 軟 件 開 發 中, 許 多 程 序 員 將 其 作 為 一 種 實 現 多 窗 口 的 標 準 方 法。 微 軟 基 礎 類 庫(Microsoft Foundation Class Library, 簡 稱MFC 庫), 是 微 軟 公 司 為 方 便Windows 程 序 開 發 所 提 供 的 一 個 功 能 強 大 的 通 用 類 庫。MFC 的 核 心 是 以 類 的 形 式 封 裝 了 大 量Windows API。 在 可 視 化 編 程 工具VC++ 下 應 用MFC 是 目 前 開 發Windows 程 序 最 方 便 的 途 徑 之 一。VC++ 提 供 的 各 種 開 發 工 具 如AppWizard、ClassWizard 和App Studio, 可 以 建 立 起 具 備 基 本 功 能 的Windows 框 架 程 序(Framework)。 而 程 序 員 所 需 要 做 的 工 作 就 是 將 自 己 特 有 的 代 碼 填 入 到 框 架 程 序 中 去, 從 而 極 大 地 減 少 了 用 戶 界 面 編 程 的 工 作 量, 加 快 了 開 發 速 度。 關 於MDI 的 標 準 開 發 方 法 可 參 考 一 般 的Windows 編 程 書 籍, 本 文 將 介 紹 利 用MFC 實 現MDI 界 面。
MFC 2.0 以 上 版 本 支 持" 文 檔/ 瀏 覽 視 窗"(Document/View) 結 構 模 式。 由 文 檔 負 責 管 理 數 據, 瀏 覽 視 窗 負 責 數 據 顯 示 及 與 用 戶 的 交 互, 從 而 實 現 了 數 據 與 界 面 的 分 離, 使 整 個 程 序 設 計 更 具 規 範 化、 模 塊 化。MFC 中," 文 檔" 由 類CDocument 及 其 派 生 類 實 現( 簡 稱Doc 類);" 瀏 覽 視 窗" 由 類CView 及 其 派 生 類 實 現 ( 簡 稱View 類)。 二 者 都 包 含 於 應 用 程 序 的 框 架 窗 口 中, 並 由 其 管 理。 使 用 單 文 檔 時, 框 架 窗 口 由 類CFrameWnd 及 其 派 生 類 實 現; 使 用 多 文 檔 時, 框 架 窗 口 是 利 用 類CMDIFrameWnd 和CMDIChildWnd 實 現。 由 文 檔 模 板 將 文 檔、 瀏 覽 窗 口 和 框 架 窗 口 三 者 聯 系 起 來。
當 程 序 員 在App Wizard 的Option 選 項 中 選 擇 Multiple Document Interface 時,MFC 構 架 程 序(Framework) 將 自 動 生 成 實 現MDI 基 本 功 能 的 代 碼。 類CMDIFrameWnd 負 責 整 個 應 用 程 序 的 主 框 架 窗 口; 類CMDIChildWnd 實 現MDI 的 子 窗 口 框 架, 它 不 帶 菜 單 項, 而 與 主 框 架 窗 口 共 享 菜 單。 主 框 架 窗 口 依 據 當 前 激 活 的 子 窗 口 自 動 更 換 菜 單 項。CView 則 負 責MDI 子 窗 口 客 戶 區 中 顯 示 的 具 體 內 容。 例 如,App Wizard 的 以M01 為Project 名 建 立 的 構 架 程 序(framework) 中 包 括 一 些 基 本 類: 主 框 架 窗 口CMainFrame: 派 生 自CMDIFrameWnd; 文 檔CM01Doc : 派 生 自CDocument; 瀏 覽 窗 口CM01View: 派 生 自CView; 其 中CM01Doc、CM01View 和CMDIChildWnd 由 多 文 檔 模 板CMultiDocTemplate 聯 系 在 一 起。 在CM01App::InitInstance() 函 數 中 代 碼 如 下:
BOOL CM01App::InitInstance()
{
......
CMultiDocTemplate* pDocTemplate;
// CMultiDocTemplate 用 於MDI 文 檔
pDocTemplate = new CMultiDocTemplate(
IDR_M01TYPE,// 資 源 標 識
RUNTIME_CLASS(CM01Doc),
// 文 檔 類
RUNTIME_CLASS(CMDIChildWnd),
// 標 準MDI 子 窗 口 框 架
RUNTIME_CLASS(CM01View));
// 瀏 覽 視 窗 類
AddDocTemplate(pDocTemplate);
// 為 整 個 應 用 程 序 添 加 新 模 板
......
}
此 時, 數 據Doc 類 僅 與 一 種View 類 相 關 聯,MDI 每 個 子 窗 口 顯 示 的 內 容 是 一 致 的。 如 果 用 戶 希 望 不 同 的 子 窗 口 顯 示 不 同 的 文 檔, 則 需 要 分 別 建 立 新 的 資 源 項、 新 的 文 檔 類、 新 的View 類, 並 且 用 新 模 板 將 他 們 與CMDIChildWnd 聯 系 起 來 即 可。MFC 框 架 程 序 將 復 雜 的 消 息 發 送 和 接 收 機 制 隱 藏 起 來, 自 動 實 現 子 窗 口 的 調 度 安 排。 程 序 員 只 需 設 定 自 己 的 數 據, 並 在 各 個View 中 重 載OnDraw() 函 數, 完 成 所 需 的 繪 制。
然 而 在 實 際 開 發 應 用 程 序 中, 常 常 希 望 對 某 一 類 數 據 進 行 不 同 方 式 的 顯 示, 既 可 觀 察 數 值, 又 可 有 圖 形 顯 示。 這 就 要 求 同 一 種Doc 類 與 多 個View 類 相 關 聯, 而 每 個View 類 對 應 一 個 不 同 的MDI 子 窗 口。CMultiDocTemplate 的 典 型 用 法 是 建 立 獨 立 的 文 檔 結 構 和View 對 象。 而 下 面CMultiDocTemplate 將 使 用 同 一 文 檔 和 多 個View 類。
(1) 用ClassWizard 建 立 一 新 的View 類:CM02View。
(2) 建 立 新 模 板:
CMultiDocTemplate* pDocTemplate02=new CMultiDocTemplate(
IDR_M01TYPE, // 使 用 同 一 資 源
RUNTIME_CLASS(CM01Doc), // 同 一 文 檔
RUNTIME_CLASS(CMDIChildWnd), // 標 準MDI 子 窗 口 框 架
RUNTIME_CLASS(CM02View)); // 新View
然 後 使 用CApp::AddDocTemplate 函 數 添 加 新 模 板。
如 果 此 時 仍 然 在CM01App::InitInstance() 函 數 中 添 加 新 模 板, 則 構 架 程 序 會 錯 誤 地 認 為 程 序 支 持 兩 種 文 檔 類 型, 從 而 在 編 譯 產 生 的EXE 文 件 執 行 時 彈 出 對 話 框, 要 求 用 戶 選 擇 文 檔 類 型。 而 實 際 上 兩 種 文 檔 類 型 是 一 樣 的。
為 避 免 此 種 情 況, 可 使 用MFC 開 發 者 建 議 的 方 法: 在 前 例 情 況 下, 首 先, 應 在App Studio 中 將 字 串 資 源IDR_M01TYPE 復 制 為 一 個 新 字 串 資 源IDR_M02TYPE。 然 後, 刪 去 字 串 資 源IDR_M02TYPE 中 第 二 個/n 後 的 字 符 串M01 Document( 該 字 串 即 為CDocTemplate::fileNewName 項)。 之 後, 用 新 資 源IDR_M02TYPE 來 建 立 第 二 個 模 板。 這 樣 編 譯 的EXE 文 件 將 不 會 彈 出 對 話 框。 在 研 究MFC 的 源 碼 之 後, 發 現 之 所 以 彈 出 文 檔 類 型 對 話 框, 是 由 於CM01App::InitInstance() 函 數 中 調 用 了OnFileNew() 函 數。OnFileNew() 函 數 檢 查 文 檔 模 板 數 量; 當 不 止 一 個 模 板 時, 則 彈 出 對 話 框; 待 用 戶 選 擇 之 後, 按 所 選 的 文 檔 類 型 建 立MDI 窗 口。 由 於 刪 去 了 第 二 個 模 板 的fileNewName 項, 無 法 顯 示 文 檔 類 型, 就 自 動 停 止 對 話 框, 而 將 第 一 種 類 型 作 為 缺 省 文 檔 類 型 建 立MDI 窗 口。
在 工 程 應 用 程 序 中,OnFileNew() 函 數 一 般 只 在 程 序 初 始 化 時 調 用 一 次( 至 於 菜 單File |New 的 響 應, 用 戶 可 接 管 處 理), 所 以 可 以 不 在CMyApp::InitInstance() 函 數 中 添 加 新 文 檔 模 板, 躲 過OnFileNew() 函 數 的 檢 查, 而 在 需 要 的 時 候 添 加 所 需 的 文 檔 模 板, 建 立 新 的 子 窗 口。 這 樣 既 避 免 了 文 檔 類 型 對 話 框, 又 不 必 增 加 字 串 資 源。
一 種 簡 單 的 例 子 如 下: 第 一 個 子 窗 口 仍 由 構 架 程 序 自 動 建 立; 設 定 一 個 新 的 菜 單 項" 新 窗 口(NewWindow)", 在CMainFrame 中 處 理 該 菜 單 消 息, 消 息 響 應 函 數 中 顯 示 第 二 個 子 窗 口。
void CMainFrame::OnNewWindow()
{
// 添 加 新 的 文 檔 模 板
static CMultiDocTemplate* pDocTemplate_New;
static BOOL bChildCreated=FALSE;
// 標 志, 新 窗 口 是 否 建 立; 如 已 建, 將 不 重 建
if(bChildCreated==FALSE)
{
pDocTemplate_New = new CMultiDocTemplate(
IDR_M01TYPE, // 使 用 同 一 資 源
RUNTIME_CLASS(CM01Doc),
RUNTIME_CLASS(CMDIChildWnd),
// 標 準MDI 子 窗 口 框 架
RUNTIME_CLASS(CM02View));
AfxGetApp()->AddDocTemplate(pdocTemplate_New);
// 創 建 新 的 子 窗 口
CMDIChildWnd* pMDIActive = MDIGetActive(); // 獲 得 當 前 活 動 子 窗 口 的 指 針
CMpvDoc* pDoc = (CMpvDoc*)pMDIActive->GetActiveDocument(); // 獲 得 文 檔 指 針
CMDIChildWnd* pNewFrame=(CMDIChildWnd*) (pDocTemplate_New ->CreateNewFrame(pDoc, NULL));
// 建 立 新 的 框 架 窗 口
if (pNewFrame == NULL)
{
AfxMessageBox(" 新 窗 口 不 能 建 立",MB_OK,0);
return; // not created
}
pDocTemplate_New ->InitialUpdateFrame(pNewFrame, pDoc); // 顯 示 窗 口
MDITile(MDITILE_HORIZONTAL); // 將 多 個 窗 口 平 鋪
bChildCreated=TRUE;
}
不 同 的View 在OnDraw() 函 數 中 有 各 自 的 繪 制 代 碼, 當 數 據 更 新 時, 只 要 調 用CDocument::UpdateAllViews() 函 數, 即 可 更 新 全 部 的MDI 子 窗 口。
相關文章
- 多文件介面(MDI)(轉)
- MFC MDI GetActiveView() 為空View
- C#學習筆記——MDI窗體(多文件介面)C#筆記
- c# mdi多窗體C#
- VC MFC SDI/MDI框架各部分指標獲取方式框架指標
- 在多個遊戲檢視間切換實現效果遊戲
- 檢視mfc原始碼的一個很好的導航工具 (轉)原始碼
- 11 UML中的邏輯檢視、程序檢視、實現檢視、部署檢視
- Monaco Editor 實現一個日誌檢視器
- Linux實時檢視Java介面資料LinuxJava
- Runnable介面實現多執行緒執行緒
- java 介面,介面的特性,介面實現多型,面向介面程式設計Java多型程式設計
- MFC 程式基本介面配置
- 域名檢測介面原理,微信js介面域名該如何實現JS
- iOS 實現檢視指定圓角iOS
- 一分鐘實現Android遮罩引導檢視Android遮罩
- 實時微信域名檢測API介面的實現方式API
- MFC登入介面,跳轉到功能介面
- 微信域名檢測線上批次檢測如何實現?——利用域名檢測api介面實現批次檢測工具教程API
- centos 檢視USB介面的版本CentOS
- [MAUI程式設計]介面多型與實現UI程式設計多型
- 程式介面多模式顯示的實現 (轉)模式
- windows核心程式設計課程實踐---多執行緒檔案搜尋器(MFC介面)Windows程式設計執行緒
- 實現【檢視更多】功能的程式碼
- 實現跨庫可更新物化檢視
- Spring MVC多檢視SpringMVC
- 5分鐘實現呼叫ChatGPT介面API實現多輪問答ChatGPTAPI
- Java之實現多執行緒的方式二:實現Runnable介面Java執行緒
- MFC中文件檢視框架和文件模板之間的關係框架
- java多執行緒與併發 - 自己實現一個簡單的鎖(實現Lock介面)Java執行緒
- MFC實現桌面版Flappy BirdAPP
- MySQL筆記之一致性檢視與MVCC實現MySql筆記MVC
- Asp.net 多語言介面的實現方法...ASP.NET
- 多執行緒實現多工一執行緒
- 【MV】實現跨庫可更新物化檢視
- 配置多檢視解析器
- 短視訊系統,實現介面陰影效果
- C 實現射線檢測多邊形碰撞