source: dev/trunk/ab5.0/abdev/abdev/TextEditor.cpp @ 681

Last change on this file since 681 was 681, checked in by dai_9181, 15 years ago

・TinyXMLをabdevプロジェクトで使えるようにした。
・コードハイライターを汎用的に実装しなおした。syntaxファイルを読み込む仕様とした。

File size: 7.5 KB
Line 
1#include "stdafx.h"
2
3#include "Common.h"
4
5extern HFONT hFont_TextEdit,hFont_HyperLink_TextEdit;
6extern int font_width,font_height;
7
8
9int GetControlTabSpace(int WndNum,int *piCount){
10    if(pobj_nv->bEditor_LineNumber){
11
12        char *pBuf;
13        pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
14
15        int i,iNum=1,x=0;
16        for(i=0;;i++,x++){
17            if(IsRightTurn(pBuf,i,x)){
18                //右端で折り返す
19                iNum++;
20                x=-1;
21                i--;
22                continue;
23            }
24            if(pBuf[i]=='\0') break;
25            if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
26                iNum++;
27
28                x=-1;
29            }
30        }
31        char temporary[255];
32        sprintf(temporary,"%d",iNum);
33
34        extern SIZE sizeLineNumberFont;
35
36        i=lstrlen(temporary);
37        if(piCount) *piCount=i;
38
39        return sizeLineNumberFont.cx*(i+2);
40    }
41
42    return CONTROL_TAB_SPACE_DEFAULT;
43}
44
45void ResetTextEditFont(HWND hwnd){
46    if(hFont_TextEdit) DeleteObject(hFont_TextEdit);
47    hFont_TextEdit=CreateFontIndirect(&pobj_nv->lf);
48
49    //下線フォント
50    LOGFONT lf;
51    lf=pobj_nv->lf;
52    lf.lfUnderline=TRUE;
53    if(hFont_HyperLink_TextEdit) DeleteObject(hFont_HyperLink_TextEdit);
54    hFont_HyperLink_TextEdit=CreateFontIndirect(&lf);
55
56    HDC hdc;
57    HFONT hOldFont;
58    hdc=GetDC(hwnd);
59
60
61    hOldFont=(HFONT)SelectObject(hdc,hFont_TextEdit);
62
63    //単位文字の幅、高さ
64    SIZE size;
65    GetTextExtentPoint32(hdc,"A",1,&size);
66    font_width=size.cx;
67    font_height=size.cy;
68
69    SelectObject(hdc,hOldFont);
70
71
72    //行番号表示用フォントのサイズ
73    extern HFONT hFont_LineNumber;
74    hOldFont=(HFONT)SelectObject(hdc,hFont_LineNumber);
75    extern SIZE sizeLineNumberFont;
76    GetTextExtentPoint32(hdc,"A",1,&sizeLineNumberFont);
77    SelectObject(hdc, hOldFont);
78   
79   
80    ReleaseDC(hwnd,hdc);
81}
82void SetTextEditWordColor(int WndNum){
83    int i,i2,i3,IsStr;
84    char str[255];
85    char *pBuf;
86
87    pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
88
89    if(MdiInfo[WndNum]->DocType==WNDTYPE_TEXT){
90        //通常のテキストはすべてをデフォルトカラー(標準で黒)にする
91        for(i=0;;i++){
92            if(pBuf[i]=='\0') break;
93            MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i]=tci.rgbDefault;
94        }
95        return;
96    }
97
98
99    for(i=0,IsStr=0;;i++){
100        if(pBuf[i]=='\0') break;
101
102        if((IsVariableTopChar(pBuf[i]))&&IsStr==0){
103            for(i2=0;;i++,i2++){
104                if((!IsVariableChar(pBuf[i]))||pBuf[i]=='.'){
105                    str[i2]=0;
106                    break;
107                }
108                str[i2]=pBuf[i];
109            }
110
111            bool result = false;
112            if(MdiInfo[WndNum]->DocType==WNDTYPE_BASIC)
113            {
114                result = ActiveBasic::IDE::Program::ablang->IsExistKeyword( str );
115            }
116            else if(MdiInfo[WndNum]->DocType==WNDTYPE_HTML){
117                result=IsHtmlReservedWord(str);
118            }
119
120            if(result){
121                for(i3=i-i2;i3<i;i3++){
122                    MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i3]=tci.rgbStatement;
123                }
124            }
125            else{
126                for(i3=i-i2;i3<i;i3++){
127                    MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i3]=tci.rgbDefault;
128                }
129            }
130            i--;
131            continue;
132        }
133        else{
134            if( IsStr || ActiveBasic::IDE::Program::ablang->IsQuoteMark( pBuf[i] ) && IsStr == 0 )
135            {
136                //文字列カラー(""で囲まれる範囲)
137                MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i]=tci.rgbString;
138            }
139            else{
140                //通常カラー
141                MdiInfo[WndNum]->pMdiTextEdit->pColorRef[i]=tci.rgbDefault;
142            }
143        }
144
145        if( ActiveBasic::IDE::Program::ablang->IsQuoteMark( pBuf[i] ) )
146        {
147            IsStr^=1;
148        }
149
150        if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
151            IsStr=0;
152            continue;
153        }
154    }
155}
156void ResetScrollbar(int WndNum,int max_x,int max_y){
157    RECT rect;
158
159    //エディタ画面左端のコントロールタブ
160    int iControlTabSpace;
161    iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
162
163    HWND hEdit;
164    hEdit=GetWindow(MdiInfo[WndNum]->hwnd,GW_CHILD);
165    GetClientRect(hEdit,&rect);
166
167    SCROLLINFO si;
168    si.cbSize=sizeof(SCROLLINFO);
169    si.fMask=SIF_PAGE|SIF_RANGE|SIF_DISABLENOSCROLL;
170
171    //垂直スクロールバーの設定
172    GetScrollInfo(hEdit,SB_VERT,&si);
173    si.nPage=(rect.bottom/font_height)-1;
174    si.nMin=0;
175    si.nMax=max_y+si.nPage/5*3;
176    SetScrollInfo(hEdit,SB_VERT,&si,1);
177
178    //水平スクロールバーの設定
179    GetScrollInfo(hEdit,SB_HORZ,&si);
180    si.nMin=0;
181    si.nPage=(rect.right-iControlTabSpace)/font_width   -1;
182    si.nMax=max_x+si.nPage/3;
183    SetScrollInfo(hEdit,SB_HORZ,&si,1);
184
185    //ルーラーを再描画
186    InvalidateRect(MdiInfo[WndNum]->pMdiTextEdit->pobj_Ruler->hRulerWnd,NULL,0);
187    UpdateWindow(MdiInfo[WndNum]->pMdiTextEdit->pobj_Ruler->hRulerWnd);
188}
189
190#define HIRA_START  (unsigned char)0x9F     //ひらがなの2バイト目の範囲
191#define HIRA_END    (unsigned char)0xF1
192#define KATA_START  (unsigned char)0x40     //カタカナの2バイト目の範囲
193#define KATA_END    (unsigned char)0x96
194BOOL IsHiragana(char *pBuf){
195    if((unsigned char)pBuf[0]==(unsigned char)0x82&&
196        HIRA_START<=(unsigned char)pBuf[1]&&(unsigned char)pBuf[1]<=HIRA_END) return 1;
197    return 0;
198}
199BOOL IsKatakana(char *pBuf){
200    if(((unsigned char)pBuf[0]==(unsigned char)0x83&&
201        KATA_START<=(unsigned char)pBuf[1]&&(unsigned char)pBuf[1]<=KATA_END)||
202        (unsigned char)pBuf[0]==(unsigned char)0x81&&(unsigned char)pBuf[1]==(unsigned char)0x5B) return 1;
203    return 0;
204}
205BOOL IsKanji(char *pBuf){
206    if((unsigned char)0x88<=(unsigned char)pBuf[0] && (unsigned char)pBuf[0]<=(unsigned char)0xEA) return 1;
207    return 0;
208}
209BOOL IsAlphabet(char c){
210    if('a'<=c&&c<='z'||'A'<=c&&c<='Z') return 1;
211    return 0;
212}
213BOOL IsReturnCode(char *pBuf){
214    if(pBuf[0]=='\r'&&pBuf[1]=='\n') return 1;
215    return 0;
216}
217void TextEdit_GetWordCaret(HWND hwnd,int WndNum,POINT *pPos,int *piStart,int *piEnd,BOOL bBeforeAfterFlag){
218    int i,start,end;
219    char *pBuf;
220
221    pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
222
223    //ダブルクリック位置を取得(バッファインデックス)
224    i=GetBufferIndexFromCaretPos(pBuf,
225        pPos->x,
226        pPos->y);
227
228    if(IsDBCSLeadByte(pBuf[i])){
229        ///////////////////
230        // 全角文字のとき
231        ///////////////////
232
233        if(IsHiragana(pBuf+i)){
234            //ひらがな
235
236            //単語の先頭位置を取得
237            start=i;
238            for(;;start-=2){
239                if(0>start){
240                    start+=2;
241                    break;
242                }
243                if(!IsHiragana(pBuf+start)){
244                    start+=2;
245                    break;
246                }
247            }
248
249            //単語の終端位置を取得
250            end=i;
251            for(;;end+=2){
252                if(!IsHiragana(pBuf+end)) break;
253            }
254        }
255        else if(IsKatakana(pBuf+i)){
256            //カタカナ
257
258            //単語の先頭位置を取得
259            start=i;
260            for(;;start-=2){
261                if(0>start){
262                    start+=2;
263                    break;
264                }
265                if(!IsKatakana(pBuf+start)){
266                    start+=2;
267                    break;
268                }
269            }
270
271            //単語の終端位置を取得
272            end=i;
273            for(;;end+=2){
274                if(!IsKatakana(pBuf+end)) break;
275            }
276        }
277        else if(IsKanji(pBuf+i)){
278            //漢字
279
280            //単語の先頭位置を取得
281            start=i;
282            for(;;start-=2){
283                if(0>start){
284                    start+=2;
285                    break;
286                }
287                if(!IsKanji(pBuf+start)){
288                    start+=2;
289                    break;
290                }
291            }
292
293            //単語の終端位置を取得
294            end=i;
295            for(;;end+=2){
296                if(!IsKanji(pBuf+end)) break;
297            }
298        }
299        else{
300            //漢字とその他の全角文字
301            start=i;
302            end=start+2;
303        }
304    }
305    else{
306        ///////////////////
307        // 半角文字のとき
308        ///////////////////
309
310        //単語の先頭位置を取得
311        start=i;
312        for(;0<=start;start--){
313            if(!(IsVariableChar(pBuf[start])&&pBuf[start]!='.')){
314                break;
315            }
316        }
317        start++;
318
319        //単語の終端位置を取得
320        end=i;
321        for(;;end++){
322            if(!(IsVariableChar(pBuf[end])&&pBuf[end]!='.')) break;
323        }
324    }
325
326    *piStart=start;
327    *piEnd=end;
328}
329void CancelBeforeAutoIndent(int WndNum){
330    int i;
331
332    i=GetBufferIndexFromCaretPos(
333        MdiInfo[WndNum]->pMdiTextEdit->buffer,
334        MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x,
335        MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y);
336    GetCaretPosFromBufferIndex(
337        MdiInfo[WndNum]->pMdiTextEdit->buffer,
338        i-lstrlen(MdiInfo[WndNum]->IndentStr),
339        &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
340
341    TextEdit_Replace(WndNum,"",1);
342
343    HeapDefaultFree(MdiInfo[WndNum]->IndentStr);
344    MdiInfo[WndNum]->IndentStr=0;
345}
Note: See TracBrowser for help on using the repository browser.