語法編輯器能針對程式語言的關鍵字、註解、字串、數字等進行語法高亮,大幅提升程式碼可讀性。Visual Basic、VC++、Delphi 等 IDE 皆內建此功能。本文探討如何使用 VC++ 從零打造一個語法編輯器。
Windows 提供強大的 Rich Edit 控制項(riched20.dll),寫字板即基於此開發。MFC 封裝為 CRichEditCtrl 與 CRichEditView。雖然 CRichEditView::SetCharFormat 可設定字元格式,但實測效率極差,特別是處理 C++ 多行註解時表現不佳。
作者發現一個關鍵現象:建立單一文件專案,將視圖基類改為 CRichEditView,覆寫 OnPaint 但不撰寫任何程式碼,執行後貼上文字雖無顯示,但拖曳滑鼠可見選取區域,且 GetLine 仍能取得文字內容。這啟發了自繪方案:
Rich Edit 採像素級捲動,首行可能只顯示一半。必須精確計算第一行的 top 座標,確保繪製位置與編輯器內部一致。
Tab 寬度非固定,依字元位置動態調整(如寫字板行為)。繪製時必須模擬相同的 Tab 展開邏輯,否則會造成文字錯位。
class CSyntaxEditorView : public CRichEditView {
// 核心方法
void OnPaint() override; // 自訂繪製入口
void DrawSyntaxHighlightedText(); // 語法分析與繪製
void CalculateVisibleLines(); // 計算可視行範圍
int GetTabWidth(int col); // 動態 Tab 寬度計算
// 語法分析輔助
bool IsKeyword(LPCTSTR text, int len);
bool IsComment(LPCTSTR text, int len);
bool IsString(LPCTSTR text, int len);
};
GetFirstVisibleLine 與 GetLineCount完整原始碼可參考文末提供的下載連結。此架構兼具編輯效能與高亮靈活性,是開發專屬 IDE 編輯器的堅實基礎。