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

Last change on this file since 681 was 681, checked in by dai_9181, 16 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.