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

VC++ 自訂 CRichEditCtrl 控件:新增右鍵選單與字體設定功能

     編輯:關於VC++

在 Visual C++ 中,CEdit 和 CRichEditCtrl 是兩個最常用的編輯控件,它們已能滿足大多數開發需求。然而,CEdit 支援滑鼠右鍵訊息,方便使用者進行剪貼簿操作,而 CRichEditCtrl 雖支援豐富文字格式(如 Word 般的字型、顏色設定),卻缺乏內建的右鍵選單支援。本文將示範如何透過繼承 CRichEditCtrl,為其加入完整的右鍵快捷選單,包含復原、剪下、複製、貼上、清除、全選與字型設定等功能。

一、建立自訂類別 CMyRichEdit

首先從 CRichEditCtrl 衍生一個新類別 CMyRichEdit,所有擴充功能將在這個類別中實作。

二、處理滑鼠右鍵訊息 (WM_RBUTTONDOWN)

在類別精靈中為 WM_RBUTTONDOWN 新增處理函式 OnRButtonDown,並在其中建立彈出式選單:

// 設定焦點 SetFocus(); // 建立彈出式選單 CMenu popmenu; popmenu.CreatePopupMenu(); // 新增選單項目 popmenu.AppendMenu(MF_STRING, ID_RICH_UNDO, _T("&Undo")); popmenu.AppendMenu(MF_SEPARATOR); popmenu.AppendMenu(MF_STRING, ID_RICH_CUT, _T("Cu&t")); popmenu.AppendMenu(MF_STRING, ID_RICH_COPY, _T("C&opy")); popmenu.AppendMenu(MF_STRING, ID_RICH_PASTE, _T("&Paste")); popmenu.AppendMenu(MF_STRING, ID_RICH_CLEAR, _T("C&lear")); popmenu.AppendMenu(MF_SEPARATOR); popmenu.AppendMenu(MF_STRING, ID_RICH_SELECTALL, _T("Select &All")); popmenu.AppendMenu(MF_SEPARATOR); popmenu.AppendMenu(MF_STRING, ID_RICH_SETFONT, _T("Select &Font")); // 依狀態啟用/停用選單項目 UINT nUndo = CanUndo() ? 0 : MF_GRAYED; popmenu.EnableMenuItem(ID_RICH_UNDO, MF_BYCOMMAND | nUndo); UINT nSel = (GetSelectionType() != SEL_EMPTY) ? 0 : MF_GRAYED; popmenu.EnableMenuItem(ID_RICH_CUT, MF_BYCOMMAND | nSel); popmenu.EnableMenuItem(ID_RICH_COPY, MF_BYCOMMAND | nSel); popmenu.EnableMenuItem(ID_RICH_CLEAR, MF_BYCOMMAND | nSel); UINT nPaste = CanPaste() ? 0 : MF_GRAYED; popmenu.EnableMenuItem(ID_RICH_PASTE, MF_BYCOMMAND | nPaste); // 顯示選單 CPoint pt; GetCursorPos(&pt); popmenu.TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN, pt.x, pt.y, this); popmenu.DestroyMenu();

三、定義命令 ID

在標頭檔 (.h) 中定義選單項目對應的命令 ID,數值可自訂,或透過「View → Resource Symbols」由 VC++ 自動管理:

#define ID_RICH_UNDO 101 #define ID_RICH_CUT 102 #define ID_RICH_COPY 103 #define ID_RICH_PASTE 104 #define ID_RICH_CLEAR 105 #define ID_RICH_SELECTALL 106 #define ID_RICH_SETFONT 107

四、新增命令處理函式與訊息對應

在標頭檔宣告處理函式:

afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnCopy() { Copy(); } afx_msg void OnCut() { Cut(); } afx_msg void OnPaste() { Paste(); } afx_msg void OnSelectall() { SetSel(0, -1); } afx_msg void OnUndo() { Undo(); } afx_msg void OnClear() { Clear(); } afx_msg void OnSelectfont(); // 變更字型

在實作檔 (.cpp) 的訊息對應巨集中加入:

ON_COMMAND(ID_RICH_COPY, OnCopy) ON_COMMAND(ID_RICH_CUT, OnCut) ON_COMMAND(ID_RICH_PASTE, OnPaste) ON_COMMAND(ID_RICH_SELECTALL, OnSelectall) ON_COMMAND(ID_RICH_UNDO, OnUndo) ON_COMMAND(ID_RICH_CLEAR, OnClear) ON_COMMAND(ID_RICH_SETFONT, OnSelectfont)

五、實作字型選擇功能 (OnSelectfont)

此函式會依目前選取狀態(有選取文字或無選取)決定套用對象,並呼叫 CFontDialog 讓使用者挑選字型:

void CMyRichEdit::OnSelectfont() { CHARFORMAT cf = {0}; LOGFONT lf = {0}; cf.cbSize = sizeof(CHARFORMAT); // 判斷是否有選取文字 BOOL bSelect = (GetSelectionType() != SEL_EMPTY); if (bSelect) GetSelectionCharFormat(cf); else GetDefaultCharFormat(cf); // 將 CHARFORMAT 轉為 LOGFONT 供 CFontDialog 使用 lf.lfCharSet = cf.bCharSet; lf.lfHeight = cf.yHeight / 15; // twips to logical units lf.lfPitchAndFamily = cf.bPitchAndFamily; lf.lfItalic = (cf.dwEffects & CFE_ITALIC) ? TRUE : FALSE; lf.lfWeight = (cf.dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL; lf.lfUnderline = (cf.dwEffects & CFE_UNDERLINE) ? TRUE : FALSE; lf.lfStrikeOut = (cf.dwEffects & CFE_STRIKEOUT) ? TRUE : FALSE; _tcscpy_s(lf.lfFaceName, LF_FACESIZE, cf.szFaceName); CFontDialog dlg(&lf); dlg.m_cf.rgbColors = cf.crTextColor; if (dlg.DoModal() == IDOK) { dlg.GetCharFormat(cf); if (bSelect) SetSelectionCharFormat(cf); // 套用至選取區塊 else SetWordCharFormat(cf); // 套用至後續輸入 } }

六、使用方式

在專案中包含 CMyRichEdit.h 與 CMyRichEdit.cpp,將原本宣告為 CRichEditCtrl 的控制項變數改為 CMyRichEdit 即可。別忘了在 CWinApp::InitInstance() 中呼叫 AfxInitRichEdit() (或 AfxInitRichEdit2()) 以初始化 Rich Edit 程式庫。

圖示:程式執行效果,右鍵選單包含編輯與字型功能。

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