輸入框包含兩部分:圖案選擇器(下篇實作)與多功能文字框。文字框繼承 CRichEditCtrl 擴充為 CRichEditCtrlEx,解決三大缺口:
void CRichEditCtrlEx::OnRButtonUp(UINT nFlags, CPoint point) {
SetFocus();
CMenu menu; menu.CreatePopupMenu();
menu.AppendMenu(0, ID_RICH_UNDO, _T("&Undo"));
menu.AppendMenu(0, MF_SEPARATOR);
menu.AppendMenu(0, ID_RICH_CUT, _T("Cu&t"));
menu.AppendMenu(0, ID_RICH_COPY, _T("C&opy"));
menu.AppendMenu(0, ID_RICH_PASTE, _T("&Paste"));
menu.AppendMenu(0, ID_RICH_CLEAR, _T("C&lear"));
menu.AppendMenu(0, MF_SEPARATOR);
menu.AppendMenu(0, ID_RICH_SELECTALL, _T("Select &All"));
menu.AppendMenu(0, MF_SEPARATOR);
menu.AppendMenu(0, ID_RICH_SETFONT, _T("Select &Font"));
// 啟用/停用項目...
CPoint pt; GetCursorPos(&pt);
menu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this);
menu.DestroyMenu();
CRichEditCtrl::OnRButtonDown(nFlags, point);
CRichEditCtrl::OnRButtonUp(nFlags, point);
}
OleCreateFromFile → 建立儲存體、客戶端網站 → IRichEditOle::InsertObject。OleCreateStaticFromData → 以 CF_BITMAP 格式封裝 HBITMAP → 插入 OLE 物件。適合資源內嵌圖片。void CRichEditCtrlEx::InsertBitmap(HBITMAP hBitmap) {
STGMEDIUM stgm = {TYMED_GDI, .hBitmap = hBitmap};
FORMATETC fm = {CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI};
// 建立儲存體、資料物件、OLE 物件...
REOBJECT reo = {0}; reo.cbStruct = sizeof(REOBJECT);
reo.clsid = clsid; reo.cp = REO_CP_SELECTION;
reo.poleobj = pOleObject; reo.polesite = lpClientSite;
reo.pstg = pStorage; reo.dvaspect = DVASPECT_CONTENT;
reo.dwFlags = REO_RESIZABLE;
GetIRichEditOle()->InsertObject(&reo);
}
將 StreamIn/StreamOut 封裝為 GetRTF() 回傳 CString、SetRTF(CString) 設定內容,簡化呼叫。
實作表情符號選擇器(CIconPicker),自動偵測轉義字串(如 :))並以圖片取代。