原文:http://hi.baidu.com/combojiang/blog/item/6e65d6f322f81bce0a46e0c0.html4 H+ Z' F' T0 u j; p3 Q: [
' L$ l3 c! {0 B% t
在读这篇教程之前先提醒你,这是一个复杂的主题:不适合初学者。这是最后一篇RichEdit 控件教程。
' C$ d5 ]3 I3 j/ `$ z4 j# V# r! _$ \' y, v* \
理论: : [* |0 Z% A6 f2 u, z6 Q4 t
语法高亮显示对那些编写文本编辑器的人来说是一个热点主题。最好的解决方法是编写一个定制的Edit控件,这也是很多商业软件所使用的方法。然而,对于那些没什么时间来编写这么一个控件的人来说,次策就是改写现有的控件使之符合我们的需要。
7 R( c; C/ M B- u* g[size=-1]让我们看一看,到底 [size=-1]RichEdit [size=-1]控件提供了什么功能来帮助我们实现语法高亮。现在我应该声明,下面的方法不是一个[size=-1]“[size=-1]正确[size=-1]”[size=-1]方法:我只是给你们指出那些缺陷。 [size=-1]RichEdit [size=-1]控件提供了[size=-1]EM_SETCHARFORMAT [size=-1]消息,是你可以用来改变正文颜色。乍一看,这个消息好象是一个完美的解决方法[size=-1]([size=-1]我之所以知道是因为我也是其中的一个受骗者[size=-1])[size=-1]。然而靠近看看,将会发现有几个不合意的地方: - [size=-1]EM_SETCHARFORMAT [size=-1]仅仅对选定的正文或者控件中所有的正文有影响。如果你想改变正文颜色(高亮显示某一个特定的词),你必须先选定它。
- [size=-1]EM_SETCHARFORMAT [size=-1]执行速度很慢。
- [size=-1]RichEdit [size=-1]控件中的插入点位置处理也有一点问题。
# } I# a* @" K; d4 R [size=-1]通过上面的讨论,你可以看到使用 [size=-1]EM_SETCHARFORMAT [size=-1]是一个错误的选择,我会给你演示 [size=-1]"[size=-1]相当正确[size=-1]" [size=-1]的选择。" W+ A' N5 x/ W1 [8 p( k. ~
[size=-1]我现在使用的方法是[size=-1]“[size=-1]即时语法高亮[size=-1]”[size=-1],我只高亮显示可见部分的正文。因此高亮显示的速度跟文件的大小根本是无关的。无论是多大的文件,在某一时刻只有一小部分是可见的。9 p/ w% ?$ A y6 ]
[size=-1]怎么样实现?答案很简单: * m& u" c/ d8 T* Z
- [size=-1]子类化[size=-1]RichEdit[size=-1]控件并在你自己的窗口处理函数中处理 [size=-1]WM_PAINT [size=-1]消息。
- [size=-1]当收到 [size=-1]WM_PAINT [size=-1]消息时,它调用[size=-1]RichEdit[size=-1]控件原来的窗口过程,让它正常地更新屏幕。
- [size=-1]之后,我们将要高亮显示的词用不同的颜色来覆盖掉。/ W7 L l8 D/ X `
[size=-1]当然了,路也不是这么容易走的:仍然有两个次要的问题需要矫正,不过上面的方法工作起来很好。显示速度令人很满意。
# F @# E& ?' i P: P[size=-1]现在让我们集中在细节上。子类化处理是很简单的,不需要很多注意力。真正复杂的部分是:我们必须找到一个快速的方法来搜索那些需要高亮的词。更复杂的那些在某个注释块里的 不 需要高亮显示的词。 # m: E" E' q# C( m8 `
[size=-1]我使用的方法可能不是最好的,但是它工作的很好。我敢肯定你可以找到更快的方法。不管怎么说,先看看我下面的方法:
$ q7 i1 v6 j+ K- [size=-1]我创建一个有[size=-1]256[size=-1]元素的双字[size=-1](DWORD)[size=-1]数组,全部初始化为[size=-1]0[size=-1]。每一个元素对应一个可能的 [size=-1]ASCII [size=-1]字符,数组名叫 [size=-1]CppSyntaxArray[size=-1]。例如,第[size=-1]21[size=-1]个元素代表[size=-1]ASCII 20h ([size=-1]空格字符[size=-1])[size=-1]。我将他们作为快速查询表使用:譬如,假定我有一个词 [size=-1]"include"[size=-1],我从词中分离出第一个字符 [size=-1](i) ,[size=-1]并以响应索引查找数组。如果该元素为[size=-1]0[size=-1],我就立刻知道需要高亮的词是没有以 [size=-1]"i" [size=-1]开头的。如果该元素非[size=-1]0[size=-1],它就包含一个指针,指向一个 [size=-1]WORDINFO [size=-1]结构的链表。里面包含了需要高亮词的信息。
- [size=-1]我读取需要高亮显示的词,并为每个词创建一个 [size=-1]WORDINFO [size=-1]结构。: t8 ]! T6 G: E9 u* t3 x
typedef struct WORDINFO
$ Y4 y' K1 a& h$ ^{: h5 O' Z: d4 e! a! |
DWORD WordLen; //词的长度,用来快速比较
5 }+ J$ ~5 a" z z7 T/ k6 r LPTSTR pszWord; //词的指针
7 l: R4 q6 y7 a D COLORREF Color; //颜色值) O( P1 o Q9 V' T
WORDINFO * NextLink; //下一个 WORDINFO 结构
- B& S5 `* c' P}WORDINFO;
; d/ n" C; ~3 K6 a[size=-1]正如你所看到的,我使用词的长度来作为第二个快速比较方法。如果词中的第一个字符匹配后,我们下一个比较的是词的才长度。[size=-1]CppSyntaxArray [size=-1]中的每一个元素包含了一个指针,指向一个相关的[size=-1]WORDINFO [size=-1]数组[size=-1].[size=-1]例如,代表字符 [size=-1]"i" [size=-1]的元素将会包含一个指向以[size=-1]"i"[size=-1]开头的词的链表。 [size=-1]Color [size=-1]成员指向一个[size=-1]DWORD,[size=-1]包含用来做高亮显示该词的颜色值。[size=-1]pszWord [size=-1]指向要高亮显示的词。是小写形式的。0 n# e9 L* g; H9 W! e
- [size=-1]链表的内存是从堆([size=-1]heap)[size=-1]中分配的,速度快,容易清除,也就是说根本不用清楚。
6 Y% z3 S( c" H5 c [size=-1]高亮词列表保存在文件 [size=-1]"wordfile.txt"[size=-1]中,我通过 [size=-1]GetPrivateProfileString API [size=-1]函数来访问。我提供了多达[size=-1]10[size=-1]种不同的语法颜色,从 [size=-1]C1 [size=-1]到 [size=-1]C10[size=-1]。颜色数组名叫 [size=-1]CppColorArray[size=-1]。每一个 [size=-1]WORDINFO [size=-1]结构的 [size=-1]Color [size=-1]成员都指向 [size=-1]CppColorArray [size=-1]中的某一个元素。因此闲时很容易改变语法颜色:你只需要改变 [size=-1]CppColorArray [size=-1]中的元素的值,这样所有使用那种颜色高亮的词就立刻使用新颜色显示。
6 t# _ B/ G8 s( ^0 X( Q) N9 d例子:见光盘FirstWindow33#include "Windows.h"9 y- s2 ~9 G1 b/ m' }; [
#include "tchar.h"' I1 a# U+ S# j( v' T) w
#include "Richedit.h"
: j/ L! V7 {4 g5 P#include "shlwapi.h"
; w9 X! n% l1 l8 B+ A$ m#pragma comment(lib,"shlwapi.lib")
" F' b$ v5 W+ r0 a2 k" N( {
) Z. s) ?; \4 G' p; V6 Otypedef struct WORDINFO C4 y8 _+ b! I; y* K! H' K( y
{- A7 m) [; n. f' H2 k
DWORD WordLen; //the length of the word: used as a quick comparison
" o9 J/ \* V# H LPTSTR pszWord; //pointer to the word6 r! Z4 H* S/ C
COLORREF Color; //point to the dword that contains the color used to hilite the word
0 `9 ?- }+ r$ d9 v WORDINFO * NextLink; //point to the next WORDINFO structure
* Y2 M) j+ m9 K9 A9 u}WORDINFO;
G Z R/ D* b4 b$ n" ^' W" c4 o, r5 o- T9 U6 a- h& m( I9 i! p6 ]
#define IDR_MAINMENU 101% ]4 x1 y5 F/ q% A; _2 @5 Z
#define IDM_OPEN 40001
7 n. Z% l! w/ x& R#define IDM_SAVE 40002
4 g: u' X7 S, z* {, Y5 a8 z R#define IDM_CLOSE 40003
* z% N8 ~5 W3 g/ j) z' I#define IDM_SAVEAS 40004
' x. c' s8 z7 ^6 |: x#define IDM_EXIT 40005
! Y$ n" Q1 b8 E9 n, L#define IDM_COPY 40006
; z& _$ [7 G! @0 [#define IDM_CUT 400075 v9 z5 Z* n1 S
#define IDM_PASTE 400087 X8 l8 q$ f& ^ n+ m
#define IDM_DELETE 40009$ x$ i, v8 v2 H" Z
#define IDM_SELECTALL 40010" V- {8 H7 r- X9 b
#define IDM_OPTION 40011
5 d8 {% T3 @5 r* h#define IDM_UNDO 40012; X( T* V% R7 U r, e' ^
#define IDM_REDO 40013
8 T& d$ q* P& Y2 z4 t0 w% r#define IDD_OPTIONDLG 101
( N0 V C7 e# u* F% |+ M0 v/ a#define IDC_BACKCOLORBOX 10002 g: q' \% v7 z
#define IDC_TEXTCOLORBOX 1001/ A' t* k k9 O {; e* u2 [* C2 i% U" T
#define IDR_MAINACCEL 105( ~; [: _& i8 x5 N
#define IDD_FINDDLG 102 @$ z# R- g' m1 r+ p
#define IDD_GOTODLG 1039 k2 D! _8 ^4 R$ m. |
#define IDD_REPLACEDLG 104' {; j; a! Y! c- D* b' `
#define IDC_FINDEDIT 1000- c% `2 D9 O% @0 d" W5 r. n
#define IDC_MATCHCASE 10012 {+ W* _" b; S W- _4 G: k
#define IDC_REPLACEEDIT 10016 J5 @1 C# A" W: U# v: v
#define IDC_WHOLEWORD 1002
4 r. r# K; Y; f#define IDC_DOWN 10036 Q8 U/ Z/ C1 \# w8 l
#define IDC_UP 1004
) t4 G9 y) C/ t8 S: w#define IDC_LINENO 1005( k) [0 l' z- k* @1 ?
#define IDM_FIND 40014
0 g& H' a5 [' X8 N#define IDM_FINDNEXT 40015- _1 j$ }8 Q/ @" D( Y
#define IDM_REPLACE 40016 [. b- @1 E) V8 A! N0 x9 g7 H
#define IDM_GOTOLINE 40017) F6 O) K$ _6 M6 `, | w4 u( p
#define IDM_FINDPREV 400187 f2 r6 Z4 a* w# {
#define RichEditID 300
- h! c9 C1 O) Z5 Q8 G$ j; }# [7 U5 `' Y3 D7 U
% Y @; s$ c8 h+ ~' x4 @6 _; [2 Z) \2 g0 A8 ^
TCHAR ClassName[] = _T("IczEditClass");
. v0 f3 m! ^; T) D9 aTCHAR AppName[] = _T("IczEdit version 3.0");3 x1 n! P2 W4 P$ X2 a
TCHAR RichEditDLL[] = _T("riched20.dll");9 Y; l: @: d# U: J
TCHAR RichEditClass[] = _T("RichEdit20A");
$ a ]# P% N: \* @, b5 HTCHAR NoRichEdit[] = _T("Cannot find riched20.dll");
5 E" z- a4 V/ k9 w# l: e7 ~- zTCHAR CppFilterString[] = _T("asm source code(*.asm)\0*.asm\0All Files (*.*)\0*.*\0");
! `, D8 y1 V: }2 w3 OTCHAR OpenFileFail[] = _T("Cannot open the file");6 d& Y& W/ `+ l+ k
TCHAR WannaSave[] = _T("The data in the control is modified. Want to save it?");$ M: i; S3 |8 t: y* Q
% m% a2 M2 H9 i1 g j7 i, tBOOL FileOpened = FALSE;
5 \4 P& a% ]$ w4 V! eCOLORREF BackgroundColor = RGB(255,255,255) ;0 l: B: |0 b0 |( k
COLORREF TextColor = RGB(0,0,0);5 w3 x9 _7 x1 K# k! ^' U
HWND hSearch;
. c8 B7 m9 S+ [; w# J' v; Y: jHACCEL hAccel;
, r8 B0 N- ]1 n& w( kTCHAR FileName[256];9 }5 C0 P- ^8 a/ N" f
TCHAR AlternateFileName[256];! S% w1 c& r: V4 J' { c
DWORD CustomColors[16];
! Y3 ~7 n8 }# yHINSTANCE g_hInstance;( z: t9 j/ E0 d; Q
HMODULE hRichEdit;
0 j- ^/ J6 P/ @: VHWND hwndRichEdit;
8 D% Z' H7 d7 }. STCHAR FindBuffer[256];4 s2 R* n% a) l. A
TCHAR ReplaceBuffer[256];
" J) H. r L; }9 n; ?1 SDWORD uFlags;
v' `* E8 u2 x4 H b# bFINDTEXTEX findtext;
- I+ r" W0 ?3 ~& W. S+ Q+ B9 l# s9 n& c$ V1 ~7 F
TCHAR WordFileName[] = _T("\\wordfile.txt");" q; C6 E$ E1 {
TCHAR CppSection[] = _T("AsmSection");% v% Y( L9 L7 k9 h
TCHAR C1Key[] = _T("C1");& I; S4 x7 R) b& K7 I1 w( {/ i
TCHAR C2Key[] = _T("C2");/ }" l# b5 J- `, ]) G: T
TCHAR C3Key[] = _T("C3");% o: `+ X8 H: u# b# o3 I. ]0 D. @
TCHAR C4Key[] = _T("C4");
, R9 h' m: I7 t' _! nTCHAR C5Key[] = _T("C5");3 T6 B& d0 m/ V9 `! y: Z
TCHAR C6Key[] = _T("C6");& q* r& P( Y) p6 o+ n
TCHAR C7Key[] = _T("C7");
! [+ H" H0 Q G' E( q* R8 P S9 V+ iTCHAR C8Key[] = _T("C8");
( R4 W1 Q1 n: j9 X/ W |8 j4 Q, z$ PTCHAR C9Key[] = _T("C9");
5 M7 [9 ^# P% X! x2 eTCHAR C10Key[] = _T("C10");3 r$ ]* X4 i( w+ N" [
TCHAR ZeroString[] = _T("\0");$ z4 p6 g5 T9 E$ s9 C" N# |" M
COLORREF CppColorArray[] = {
/ ~. z$ ?3 n O4 ^ RGB(0,0,0xff),RGB(0x50,0x5f,0x80),RGB(0xff,0,0),RGB(0,0x6f,0x66),, `/ Q5 \* a& A: p
RGB(0xf0,0x44,0),RGB(0x54,0x87,0x5f),RGB(0,0,0xff),RGB(0,0,0xff),9 y2 l F9 R9 Z
RGB(0,0,0xff),RGB(0,0,0xff)* V4 v C5 [% S% {/ k! [5 h1 |9 C
};
l' O4 O" j) Y
- f( A& M3 m- u1 M$ M( _/ U2 ]COLORREF CommentColor = RGB(0,0x80,0x80);
- [" {2 }. k [- _+ ~, z EDWORD CppSyntaxArray[256]; |. u7 W/ p% q! o; q
WNDPROC OldWndProc;4 E, q$ h6 y& H# ?- R2 }, O4 T% _/ O" K8 d
DWORD RichEditVersion; b9 J% o& Z- f4 Z3 Z
HANDLE hMainHeap;( w& u: z+ _9 I( S/ }3 H
LONG CALLBACK NewRichEditProc( HWND hWnd, ' o% n! E" L: K- s- F0 c: U. f
UINT Msg,
& ~0 w) _8 P, o! Q6 R* J WPARAM wParam,
% `$ k) \! j$ B LPARAM lParam
! u; e9 C8 u5 i' o)1 P* Q9 }* H+ {! P1 A7 C
{
' P, n( U. q* T4 p [. H* J HDC hdc;% a6 v' V% \4 h% `% ]( R- k; w
HFONT hOldFont;$ x; |$ A2 n+ w5 G2 A+ _% r
DWORD FirstChar;. v1 f& [+ u1 g$ Q* c! H
RECT rect;. \1 A6 o; k+ ~" ? x
TEXTRANGE txtrange;
& H: L- s) [. M TCHAR buffer[1024 *10];
# z) n: C9 N9 P HRGN hRgn;
" M* ]: p$ Z: @* m; E3 A HRGN hOldRgn;
) H; P& g, Q6 Z5 x' U* H RECT RealRect;# p. R- f) V- }0 V
DWORD BufferSize;0 L$ D) W% U' z- {
LPTSTR pString;1 @9 e1 s" a3 R' C* q, A( h# H6 B
0 W! [* a3 S+ K4 }$ _
switch(Msg)0 I3 h# e+ ~$ p' ?" ?/ X$ R& O
{% T3 q6 S ]/ e8 q' d
case WM_PAINT:
5 f# w" E; ~8 j1 i% T+ M S {
/ S5 h7 d2 t- F9 @ HideCaret(hWnd);
. X8 y r5 V0 d int nRet = CallWindowProc(OldWndProc,hWnd,Msg,wParam,lParam);7 w* o; y4 ~' o4 _
hdc = GetDC(hWnd);
0 E1 S( t* ~3 y2 H. c b$ M! E' P SetBkMode(hdc,TRANSPARENT);, f3 o. I# ~* z
SendMessage(hWnd,EM_GETRECT,0,(LPARAM)&rect);
1 X5 U- I7 a6 k5 j. e0 c! h& m' f int nPos = SendMessage(hWnd,EM_CHARFROMPOS,0,(LPARAM)&rect);" _( @7 W6 A- [
: F; J6 ]3 ?8 k: t" q. p5 ` int nLine = SendMessage(hWnd,EM_LINEFROMCHAR,nPos,0);
6 f4 w/ q& S# b/ F! Z int nIndex = SendMessage(hWnd,EM_LINEINDEX,nLine,0);) Q8 q- s6 v6 p6 n
txtrange.chrg.cpMin = nIndex;/ m3 d7 {' l: k
FirstChar = nIndex;0 U' p' g- s6 S* R3 a. E3 Y
int nNextPos = SendMessage(hWnd,EM_CHARFROMPOS,0,(LPARAM)&rect.right);
* }0 ]3 S; H+ s. \$ O4 \ txtrange.chrg.cpMax = nNextPos;
! i7 n' I. s6 e4 o4 |* o b RealRect.left = rect.left;9 ^7 l: @8 m9 Y: w* v" E
RealRect.top = rect.top;6 I9 Q3 s6 i/ n; C+ s
RealRect.right = rect.right;3 a" U4 a+ q2 R3 z. n
RealRect.bottom = rect.bottom;, r- ]) |0 t9 P
hRgn = CreateRectRgn(RealRect.left,RealRect.top,RealRect.right,RealRect.bottom);
5 d1 H) ~" g2 N% d0 V hOldRgn = (HRGN)SelectObject(hdc,hRgn);( o# y4 a0 t, u! f V- [% ^& e
SetTextColor(hdc,CommentColor);
! f, U: O& n# P3 i, j, }/ _5 z, @2 Q
txtrange.lpstrText = buffer;
/ P7 |4 s" X2 i, _7 y6 Q, C8 v BufferSize = SendMessage(hWnd,EM_GETTEXTRANGE,0,(LPARAM)&txtrange);4 l. e6 B" c5 G# T
pString = buffer;
1 K2 G$ Y; U. v& M2 A5 D+ C while(pString - buffer < BufferSize)8 p1 l. s0 L# a# t
{
: U( n$ w9 d. H2 c7 F pString = strchr(pString,_T(';'));8 U9 `9 H& Y2 f0 s2 I1 T
* N V. r+ w3 k- P5 k
if(pString != NULL)
" T2 y1 ~* R& Z: h) z {, ~- o# G, I3 d- j1 E" J: c) |# q
& S: v1 ?& p' |
txtrange.chrg.cpMin = pString - buffer + FirstChar;: b" E+ R# f3 s4 ]2 {4 V
LPTSTR pTemp = strchr(pString,_T('\r'));3 ]7 A; a/ d7 k4 x0 Q
if(pTemp != NULL)
5 ~1 u3 z& J! k% x. L {
, K( @5 |1 |' Z- B6 d4 ]+ r *(pTemp) = _T('\0');; `! Y6 _3 q( o& ^
}: N2 p- {; Z# M9 T
else
( B6 Y* ~8 }, c4 U( U! D pTemp = buffer + BufferSize;3 g* b% D, v; P5 |! }- i
5 o6 d: f _% L1 l txtrange.chrg.cpMax = pTemp - buffer + FirstChar;" Q6 s$ c" }6 h p
" D/ u/ i2 }, z( d# F; j' A
int nLen = txtrange.chrg.cpMax - txtrange.chrg.cpMin;! d7 y4 ]; V8 ^ C: t/ v
2 s# S, w% `% p6 E$ P0 M
LPTSTR pstr = pString;5 s1 k+ n; ?3 |1 l: H7 n% t9 X
while(nLen > 0)7 H. _' M4 ~% b5 ]
{
: Y( ]& Q8 \# W2 G& T! L+ c% y S if(*pstr == 9)
. M- D' b5 A9 h! G5 ? *pstr = _T('\0');4 }- d9 `+ |; t ]& M l, A; k
4 U' n4 G7 q$ m9 q& ~
pstr ++;
4 v6 `+ G D. n4 a- Z1 a! n nLen --;! S& D4 z. v; \, ^5 ~
}5 h) @) T6 z5 W9 D% M* y
, j, e; @& k9 z4 }' i
int nMyLen = txtrange.chrg.cpMax - txtrange.chrg.cpMin;' \6 N& F+ k `8 h. g# `
LPTSTR pMyStr = pString;
$ j+ ]8 f* f. q# ~4 D% W) q while(nMyLen > 0)& Y5 q. ]7 k j
{8 P% E# p9 E6 j L; t* ], G
int nstrlen = lstrlen(pMyStr);( z& b; ?8 v/ h8 }, x% I! s
if(*pMyStr != _T('\0'))
1 ^3 v& l$ D3 ?9 Q. o, Y7 K7 E {9 x8 {1 d0 O) e
if(RichEditVersion == 3)$ l% S2 v6 Y- g% K" g
SendMessage(hWnd,EM_POSFROMCHAR,(WPARAM)&rect,(pMyStr - buffer + FirstChar));
6 z$ K! r/ j0 ? else9 P: G8 k1 K6 ^' @4 N6 N8 e& R
{& l- G3 m& @9 w
int nWidth = SendMessage(hWnd,EM_POSFROMCHAR,(pMyStr - buffer + FirstChar), 0);0 e& {6 }6 A7 W0 L" L
rect.left = LOWORD(nWidth) ;$ Z+ w/ `7 k% H4 X$ I; q, B9 D: s( E9 ~
rect.top = HIWORD(nWidth);
V% a. X8 F8 X0 I/ I! |/ |1 O6 z5 E }! e7 r3 F( z$ Y0 L
( T; w7 |; V: t+ u' ^9 q* R$ K
DrawText(hdc,pMyStr,-1,&rect,0);
5 n, o- E; @# a9 z$ K2 ?0 D pMyStr += nstrlen;
: _) d9 H. J2 J3 M0 ^ nMyLen -= nstrlen;
4 f7 i1 g( @/ d2 B7 F! l0 W( } }
: Q; Q6 l: }* {" e5 R7 @ else. J# J6 r1 `& g( M; l- t
{
" @9 ?0 ]; @* M- t pMyStr++;# W% R3 W! G$ [4 I9 c7 j _" a
nMyLen--;4 C0 s u' r3 q
}
% n7 o U. `; r2 _) t" c }8 H* h, e) `( V5 t+ ~5 ?$ X F
3 I( F# f; A5 ?0 _8 p RtlZeroMemory(pString,(txtrange.chrg.cpMax - txtrange.chrg.cpMin));, S1 ~3 W5 m* K- B. V5 U. i. v
& ~, `2 K i& X# C pString += (txtrange.chrg.cpMax - txtrange.chrg.cpMin +1);
: G+ Z2 Z2 B! [) S h }
; x! V& k$ e& o, m4 H else9 X! H+ C3 Q5 l2 L( |3 \
break;
& K" u4 H s' }8 O; {
* C; w, e6 y0 B$ P: u3 J7 w }
5 U" t9 d& w; n0 O! B B& I! {( p5 I9 F, R' p
int nMyBufferLen = BufferSize;3 S4 j/ D. V) S% z! x: M, m$ v- ?
LPTSTR pMyBuffer = buffer;
# i2 Y5 Q3 t* X( l9 \$ D2 e' b while(nMyBufferLen > 0)( p2 g' v* T6 k1 [8 _
{
# R9 A \% B& `5 h
5 _- T# u; H3 d! [ J+ f& q: R2 [2 T if(*pMyBuffer == _T(' ') || *pMyBuffer == _T('\r') ||6 e$ A- C9 u* G7 i3 A1 Z$ o
*pMyBuffer == _T('/') || *pMyBuffer == _T(',') ||
1 n9 Y0 p1 X4 T/ y" W1 }7 G) q- V *pMyBuffer == _T('|') || *pMyBuffer == _T('+') ||
* l$ x; v3 x9 I' Q1 u *pMyBuffer == _T('-') || *pMyBuffer == _T('*') ||7 U# U: i: ` f8 M5 e
*pMyBuffer == _T('&') || *pMyBuffer == _T('<') ||
9 _# B' x3 ~. V5 I! e' n# J0 `3 y *pMyBuffer == _T('>') || *pMyBuffer == _T('=') ||# u$ B7 e# F6 V( E' C! j( W
*pMyBuffer == _T('(') || *pMyBuffer == _T(')') ||; k5 @! @# R( P1 G; x
*pMyBuffer == _T('{') || *pMyBuffer == _T('}') ||
. o' l$ Z5 m! U" q$ j/ H) I *pMyBuffer == _T('[') || *pMyBuffer == _T(']') ||; m, @- `9 s$ w1 K7 M
*pMyBuffer == _T('^') || *pMyBuffer == _T(':') ||
; l$ G6 n0 d4 `: `. o% ] *pMyBuffer == 9 )/ U/ W+ q m3 g2 Q8 O
{( M5 s, y; q/ z1 z6 [6 ?2 Z
*pMyBuffer = _T('\0');
9 H6 A) e' l+ ]4 I$ J6 u }" V1 ?: \4 |' T$ q( E
pMyBuffer++;2 f1 M) L* |+ O& m
nMyBufferLen --;% k1 t& t/ L: [% W( E5 C0 k
}) [' C9 E4 x* N; h/ g. o) G: V# }
; M. F+ I) m6 U* \- E& M d Z! u3 |
int nBuffLen = BufferSize;$ d$ a( C1 w( r9 X
LPTSTR pMyBuff = buffer;6 K. B9 G! m% g
while(nBuffLen > 0)$ T! e1 z! _, H1 a
{) ]4 @% ?3 @ ~, ]0 R6 [
if(*pMyBuff != 0)
# F1 s; S+ C5 m" W& U7 H( S1 w {* v) A% N2 o& }$ ]7 w4 @3 C
int nlen1 = lstrlen(pMyBuff);
, c8 n+ F) ?1 G( f8 z CHAR cChar = *pMyBuff;, ~) G% e2 }7 ?" n
if(cChar >= _T('A') && cChar <= _T('Z'))
1 [6 K, [. p1 f# x+ H {: a1 M, h) }/ j/ a D
cChar -= _T('A');
5 E; ^! e9 q q" p6 d cChar += _T('a');- `$ s' @+ m8 r& c) F6 S/ l. r4 P3 z
}$ i* Q( h% V O8 I- N* c2 Z8 V
0 B# v9 J2 p# q9 | if(CppSyntaxArray[cChar] != NULL)
* L3 q E2 `' D, j0 a) ^& N( H/ `* P {/ D- o( D9 T- p/ C$ I
WORDINFO *pWdInfo = (WORDINFO *)CppSyntaxArray[cChar];. n) {, V0 |- i. R/ m% J
while(pWdInfo != NULL)
4 g- V" R! |( S! G p+ Q' y8 p {. f( E l5 |, |: q. V8 V0 I& d
if(nlen1 == pWdInfo->WordLen)4 v- c; _; s0 R* u; R3 s+ U6 m
{; E' l" d$ J! N
if(lstrcmpi(pWdInfo->pszWord,pMyBuff) == 0)* Q) R8 s8 G7 p; C( E1 B
{* z& L9 r- k; }1 k; R+ J
if(RichEditVersion == 3)1 W2 ]: ~. f* T! x7 D; H
{7 ?/ ^2 H w$ S' w! F
SendMessage(hWnd,EM_POSFROMCHAR,(WPARAM)&rect,(pMyBuff - buffer + FirstChar));8 y' F+ `, p; D- ^9 Y+ u
}
+ |7 I- P( K F: D# k else
; V$ V! x- R7 h m0 A `# b {
. S/ n) ^% n9 V int nDim = SendMessage(hWnd,EM_POSFROMCHAR,(pMyBuff - buffer + FirstChar),0);* f2 x! H) B6 l ]
rect.left = LOWORD(nDim );
" H1 ?5 E: J# c rect.top = HIWORD(nDim);
% s- Z7 m# ?2 ^3 U5 M. F }- F$ [3 H$ \$ l8 D; a
/ O9 u! I. z- o+ z" G5 p0 Q
SetTextColor(hdc,pWdInfo->Color);- y$ P! a3 S; F4 x$ K& p% \
DrawText(hdc,pMyBuff,-1,&rect,0); F" L: w# v- D1 R) J, S
break;' Z0 n+ q) u, m3 p
}
1 g: b% I' X& J: o, O2 g } B+ I6 R p6 o
pWdInfo = pWdInfo->NextLink;
8 u1 Y; p: O4 g& e6 m# [ }: f( E' ?" Z' ^* U
}
! u5 }. l- P( ^) r& c/ s ' f' A: D$ T$ j+ p
pMyBuff += nlen1;
% d% G2 v" ?/ l. Y nBuffLen -= nlen1;
9 y4 q8 h# L5 J8 V$ N }; |) N( D8 A. O
else& P* R0 A! F- t, A7 Q( g
{
) h* O( p* f4 E4 V6 |- X pMyBuff++;
+ d9 n' w. O, Q nBuffLen--;" r }& l# g* k* b
}) u6 K9 J# p/ z( T8 I% W
}
2 P- C4 H+ X/ X, B! g7 v
/ |+ j$ H* G* w* Z+ s* k SelectObject(hdc,hOldRgn);$ R/ m4 y' f5 z* b# p$ }
DeleteObject(hRgn);
, {+ p) l! ~4 T" |3 Q6 p. \ SelectObject(hdc,hOldFont);
0 l% L7 o" X8 N6 N8 W8 p8 A ReleaseDC(hWnd,hdc);
4 P2 t9 k, o2 V1 ]# }% v ShowCaret(hWnd);
0 s/ _, _7 x* L ?! D* }" G return nRet;
5 u1 A. I3 S% o4 ~+ ^% j, H
* T R' E2 g# e3 s0 `' K }
% _# @( P% l0 b" V' s3 j; g! V break;
( M3 t/ l0 _+ }+ k case WM_CLOSE: c; b7 i9 N7 o0 h% s1 O& x
SetWindowLong(hWnd,GWL_WNDPROC,(long)OldWndProc);
! O* A: \% E' `* s8 }7 G break;3 z9 d e( m' M, A0 i
default:: \3 V9 v/ N: t
return CallWindowProc(OldWndProc,hWnd,Msg,wParam,lParam);
2 d5 ^6 h3 L W' Z }
$ w! I' A7 | O0 e) L* _9 _
( h: b: r C7 h+ n) Y return 0;# i3 e7 h7 n( _! e" G
} |