MFC 中 CRichEditView / CRichEditCtrl 原生支援文字編輯,圖片處理需透過 OLE (Object Linking and Embedding) 機制嵌入物件,而非直接「輸入圖片」。
| 層級 | 類別/介面 | 職責 |
|---|---|---|
| 視圖 | CRichEditView | UI 容器、訊息路由、列印 |
| 控制項 | CRichEditCtrl | Rich Edit 2.0/3.0/4.1 封裝 |
| OLE 客戶端 | CRichEditCntrItem | 嵌入物件生命週期管理 |
| OLE 伺服器 | WordPad、Paint、Excel 等 | 提供編輯能力的外部應用 |
InitInstance 呼叫 AfxEnableControlContainer()、AfxOleInit()class CMyRichEditCntrItem : public CRichEditCntrItem {
public:
CMyRichEditCntrItem(REOBJECT* preo = NULL, CRichEditView* pView = NULL)
: CRichEditCntrItem(preo, pView) {}
// 覆寫雙擊編輯行為
virtual void OnEdit() {
// 預設啟動關聯應用 (如 Paint 編輯圖片)
CRichEditCntrItem::OnEdit();
}
};
class CMyRichEditView : public CRichEditView {
protected:
virtual CRichEditCntrItem* CreateClientItem(REOBJECT* preo) {
return new CMyRichEditCntrItem(preo, this);
}
// 插入圖片功能
void InsertImage() {
CFileDialog dlg(TRUE, _T("bmp"), NULL, OFN_FILEMUSTEXIST,
_T("圖片檔案 (*.bmp;*.jpg;*.png)|*.bmp;*.jpg;*.png|"));
if (dlg.DoModal() == IDOK) {
// 透過 OLE 插入檔案
HRESULT hr = GetRichEditCtrl().InsertFile(dlg.GetPathName());
if (FAILED(hr)) AfxMessageBox(_T("插入失敗"));
}
}
};
| 操作 | 方法 | 說明 |
|---|---|---|
| 插入檔案/圖片 | InsertFile(path) | 建立 OLE 連結/嵌入 |
| 插入位圖 | InsertBitmap(hBitmap) | 直接嵌入 HBITMAP |
| 取得選取物件 | GetSelectedItem() | 回傳 CRichEditCntrItem* |
| 儲存 RTF | StreamOut(SF_RTF, es) | 含 OLE 物件資料 |
| 載入 RTF | StreamIn(SF_RTF, es) | 自動還原 OLE 物件 |
「Word 也不支援輸入圖片」—— 正確說法:Word 將圖片作為 OLE 嵌入物件 或 DrawingML 圖形 處理,雙擊啟動關聯編輯器 (如 Picture Manager)。MFC RichEdit 同樣遵循此模型。
若需即時編輯圖片像素 (而非啟動外部編輯器),建議:
CScrollView 衍生類vector<Layer> (文字層、圖片層、繪圖層)CImage、GDI+ 進行像素操作