source: dev/trunk/abdev/ProjectEditor/TextEditor_KeyEvent.cpp@ 250

Last change on this file since 250 was 118, checked in by dai_9181, 18 years ago

Namespace名前空間のコード補間機能に対応。

File size: 26.7 KB
Line 
1#include "common.h"
2#include "HtmlAnalysis.h"
3
4
5void TextEditEvent_StartAnalysis_Basic(HWND hwnd,int WndNum,int nVirtualKey);
6void TextEditEvent_StartAnalysis_Html(HWND hwnd,int WndNum,int nVirtualKey);
7
8
9void TextEditEvent_KeyUp(HWND hwnd,int nVirtualKey){
10 if(nVirtualKey==VK_CONTROL&&pobj_nv->bCtrlKeyHyperLink){
11 int WndNum;
12 WndNum=GetWndNum(GetParent(hwnd));
13
14 if(MdiInfo[WndNum].pMdiTextEdit->iUnderStart!=-1){
15 //ハイパーリンク下線の表示を解除
16 MdiInfo[WndNum].pMdiTextEdit->iUnderStart=-1;
17 MdiInfo[WndNum].pMdiTextEdit->iUnderEnd=-1;
18
19 //再描画
20 InvalidateRect(hwnd,NULL,0);
21 UpdateWindow(hwnd);
22 }
23
24 obj_WebStrings.clear();
25 }
26}
27
28
29int IsIndentAdditionCommand_FromBuffer(char *buffer){
30 int i;
31 char temporary[255];
32
33 for(i=0;;i++){
34 if(!IsVariableChar(buffer[i])){
35 temporary[i]=0;
36 break;
37 }
38 temporary[i]=buffer[i];
39 }
40
41 if(lstrcmpi(temporary,"If")==0){
42 //If文の場合はブロック形式の有無を判定
43
44 for(;;i++){
45 if(buffer[i]=='\''||
46 IsCommandDelimitation(buffer,i)){
47 i--;
48 break;
49 }
50 }
51
52 while(buffer[i]==' '||buffer[i]=='\t') i--;
53
54 if(memicmp(buffer+i-3,"Then",4)==0){
55 //ブロック形式のIf
56 return 1;
57 }
58 else{
59 //一行のみのIf
60 return 0;
61 }
62 }
63
64 if(
65 lstrcmpi(temporary,"Case")==0||
66 lstrcmpi(temporary,"Class")==0||
67 lstrcmpi(temporary,"Do")==0||
68 lstrcmpi(temporary,"Else")==0||
69 lstrcmpi(temporary,"ElseIf")==0||
70 lstrcmpi(temporary,"Enum")==0||
71 lstrcmpi(temporary,"For")==0||
72 lstrcmpi(temporary,"Function")==0||
73 lstrcmpi(temporary,"Namespace")==0||
74 lstrcmpi(temporary,"Override")==0||
75 lstrcmpi(temporary,"Sub")==0||
76 lstrcmpi(temporary,"Type")==0||
77 lstrcmpi(temporary,"Virtual")==0||
78 lstrcmpi(temporary,"Static")==0||
79 lstrcmpi(temporary,"While")==0||
80 lstrcmpi(temporary,"With")==0||
81
82 lstrcmpi(temporary,"Private")==0||
83 lstrcmpi(temporary,"Protected")==0||
84 lstrcmpi(temporary,"Public")==0
85 ) return 1;
86 else if(lstrcmpi(temporary,"Select")==0) return 2;
87 else if(lstrcmpi(temporary,"Interface")==0) return 3;
88
89 return 0;
90}
91int IsIndentDecreaseCommand_FromBuffer(char *buffer){
92 int i;
93 char temporary[255];
94
95 for(i=0;;i++){
96 if(!IsVariableChar(buffer[i])){
97 temporary[i]=0;
98 break;
99 }
100 temporary[i]=buffer[i];
101 }
102
103 if(lstrcmpi(temporary,"End")==0&&(buffer[i]==' '||buffer[i]=='\t')){
104 //End ~の場合
105
106 int i2=i;
107
108 while(buffer[i]==' '||buffer[i]=='\t') i++;
109
110 for(;;i++,i2++){
111 if(!IsVariableChar(buffer[i])){
112 temporary[i2]=0;
113 break;
114 }
115 temporary[i2]=buffer[i];
116 }
117 }
118
119 if(
120 lstrcmpi(temporary,"Case")==0||
121 lstrcmpi(temporary,"EndClass")==0||
122 lstrcmpi(temporary,"Loop")==0||
123 lstrcmpi(temporary,"Else")==0||
124 lstrcmpi(temporary,"ElseIf")==0||
125 lstrcmpi(temporary,"EndIf")==0||
126 lstrcmpi(temporary,"EndEnum")==0||
127 lstrcmpi(temporary,"Next")==0||
128 lstrcmpi(temporary,"EndFunction")==0||
129 lstrcmpi(temporary,"EndNamespace")==0||
130 lstrcmpi(temporary,"EndSub")==0||
131 lstrcmpi(temporary,"EndType")==0||
132 lstrcmpi(temporary,"Wend")==0||
133 lstrcmpi(temporary,"EndWith")==0||
134
135 lstrcmpi(temporary,"Private")==0||
136 lstrcmpi(temporary,"Protected")==0||
137 lstrcmpi(temporary,"Public")==0
138 ) return 1;
139 else if(lstrcmpi(temporary,"EndSelect")==0) return 2;
140 else if(lstrcmpi(temporary,"EndInterface")==0) return 3;
141
142
143 return 0;
144}
145
146int TextEdit_GetLineIndex(int WndNum,int iPos){
147 extern MDIINFO MdiInfo[MAX_WNDNUM];
148 int i;
149 char *pBuf;
150
151 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
152 for(i=iPos;i>0;i--){
153 if(pBuf[i-1]=='\r'&&pBuf[i]=='\n') return i+1;
154 }
155 return i;
156}
157void TextEditEvent_Char(HWND hwnd,int nVirtualKey){
158 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
159 int i,i2,i3;
160 char temporary[1024];
161 char *pBuf,*pTemp;
162 CHARRANGE CharRange;
163
164
165 //BackSpaceはWM_KEYDOWNで処理
166 if(nVirtualKey==VK_BACK) return;
167
168 if(nVirtualKey==VK_ESCAPE){
169 if(ComplementWndInfo.hWnd){
170 //コード補完リストを破棄する
171 DestroyWindow(ComplementWndInfo.hWnd);
172 ComplementWndInfo.hWnd=0;
173 }
174
175 extern METHODCHECKINFO MethodCheckInfo;
176 if(MethodCheckInfo.hWnd){
177 //パラメータヒントを破棄する
178 DestroyWindow(MethodCheckInfo.hWnd);
179 MethodCheckInfo.hWnd=0;
180 }
181
182 return;
183 }
184
185 //未対応の文字コードの誤り入力を阻止
186 if(GetKeyState(VK_CONTROL)&0x8000) return;
187
188 int WndNum;
189 WndNum=GetWndNum(GetParent(hwnd));
190
191 if(ComplementWndInfo.hWnd){
192 if((!(IsVariableChar(nVirtualKey)||nVirtualKey==VK_RETURN))||nVirtualKey=='.'){
193 //コード補完リストを破棄する
194
195 //ペアステートメント補完の場合は、空白文字を容認する
196 if(!(nVirtualKey==' '&&ComplementWndInfo.pMemberInfo[0].dwAccess==ACCESS_PAIRCOMMAND)){
197 DestroyWindow(ComplementWndInfo.hWnd);
198 ComplementWndInfo.hWnd=0;
199 }
200 }
201 }
202
203 if(nVirtualKey==VK_RETURN){
204 if(ComplementWndInfo.hWnd){
205 //コード補完リストが表示されているとき
206 for(i=0;i<ComplementWndInfo.MemberNum;i++){
207 if(ListView_GetItemState(ComplementWndInfo.hList,i,LVIS_SELECTED)) break;
208 }
209 if(i!=ComplementWndInfo.MemberNum){
210 SendMessage(ComplementWndInfo.hList,WM_KEYDOWN,VK_RETURN,0);
211 return;
212 }
213 else{
214 //コード補完リストを破棄する
215 DestroyWindow(ComplementWndInfo.hWnd);
216 ComplementWndInfo.hWnd=0;
217 }
218 }
219
220 temporary[0]='\r';
221 temporary[1]='\n';
222 temporary[2]=0;
223
224 if(nVirtualKey==VK_RETURN&&pobj_nv->bAutoIndent){
225 //////////////////
226 // 自動インデント
227 //////////////////
228
229 //インデント処理中はちらつき防止のため、キャレットを一時非表示にする
230 extern int hide_caret_switch;
231 HideCaret(hwnd);
232 hide_caret_switch=1;
233
234 if(MdiInfo[WndNum].IndentStr){
235 //以前の自動インデントを消去する
236 CancelBeforeAutoIndent(WndNum);
237 }
238
239 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
240
241 int StartX;
242
243 //リプレイス前のカーソルバッファ位置を取得
244 i=GetBufferIndexFromCaretPos(pBuf,
245 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
246 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
247 StartX=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x;
248
249 //リプレイス
250 TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
251 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
252
253 //リプレイス後のカーソル行のインデントをi3に取得
254 for(i3=0;;i3++){
255 if(pBuf[i+i3]!='\t') break;
256 }
257
258 //前の行のインデントをコピー(i2にタブ数を格納)
259 for(;i>0;i--){
260 if(
261 pBuf[i-1]=='\r'&&pBuf[i]=='\n'&&
262 (!(pBuf[i+1]=='\r'&&pBuf[i+2]=='\n'))
263 ){
264 i++;
265 break;
266 }
267 }
268
269 for(i2=0;;i2++){
270 if(pBuf[i+i2]!='\t') break;
271 }
272
273 if(MdiInfo[WndNum].DocType==WNDTYPE_BASIC){
274 //インデント追加のコマンドかどうかを判断
275 if(IsIndentAdditionCommand_FromBuffer(pBuf+i+i2)) i2++;
276 }
277
278 i2-=i3;
279 if(i2<0) i2=0;
280
281 //インデントが無いとき
282 if(i2==0){
283 hide_caret_switch=0;
284 ResetCaretPos(WndNum);
285 ShowCaret(hwnd);
286 return;
287 }
288
289 /*(I…カーソル)
290 (「\t\tⅠ」のような場合)、
291 (「\t\tⅠtext...」のような場合)を判断
292 */
293 i=GetBufferIndexFromCaretPos(pBuf,
294 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
295 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
296 if(pBuf[i]=='\r'&&
297 pBuf[i+1]=='\n'){
298 //自動インデントを開始する(「\t\tⅠ」のような場合)
299 MdiInfo[WndNum].IndentStr=(char *)HeapAlloc(hHeap,0,i2+1);
300 memset(MdiInfo[WndNum].IndentStr,'\t',i2);
301 MdiInfo[WndNum].IndentStr[i2]=0;
302 TextEdit_Replace(WndNum,MdiInfo[WndNum].IndentStr,1);
303 }
304 else{
305 //自動インデントを有効にする(「\t\tⅠtext...」のような場合)
306
307 //リプレイス前のカーソルが行の先頭位置にあった場合は抜け出す
308 if(StartX==0){
309 hide_caret_switch=0;
310 ResetCaretPos(WndNum);
311 ShowCaret(hwnd);
312 return;
313 }
314
315 memset(temporary,'\t',i2);
316 temporary[i2]=0;
317 TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
318 }
319
320 hide_caret_switch=0;
321 ShowCaret(hwnd);
322 return;
323 }
324 }
325 else if(nVirtualKey==VK_TAB){
326 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
327
328 TextEdit_GetSel(WndNum,&CharRange);
329 for(i=CharRange.cpMin;i>0;i--){
330 if(pBuf[i-1]=='\r'&&pBuf[i]=='\n'){
331 i++;
332 break;
333 }
334 }
335 CharRange.cpMin=i;
336
337 for(i2=0;i<CharRange.cpMax;i++){
338 if(pBuf[i]=='\0') break;
339 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n') i2++;
340 }
341 if(i2){
342 if(GetKeyState(VK_SHIFT)&0x8000){
343 //////////////////////////////////
344 // 複数行にわたってタブ文字を削除
345 //////////////////////////////////
346
347 if(pBuf[CharRange.cpMax-2]=='\r'&&pBuf[CharRange.cpMax-1]=='\n'){
348 CharRange.cpMax-=2;
349 }
350
351 TextEdit_SetSel(WndNum,CharRange.cpMin,CharRange.cpMax);
352
353 pTemp=(char *)HeapAlloc(hHeap,0,CharRange.cpMax-CharRange.cpMin+1);
354
355 i=CharRange.cpMin;
356 for(i3=0;i<CharRange.cpMax;i++,i3++){
357 if(i==CharRange.cpMin&&pBuf[i]=='\t'){
358 i3--;
359 continue;
360 }
361 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'&&pBuf[i+2]=='\t'){
362 pTemp[i3]='\r';
363 pTemp[i3+1]='\n';
364 i3++;
365
366 i+=2;
367 continue;
368 }
369 pTemp[i3]=pBuf[i];
370 }
371 pTemp[i3]=0;
372 }
373 else{
374 //////////////////////////
375 // 複数行にタブ文字を追加
376 //////////////////////////
377
378 if(pBuf[CharRange.cpMax-2]=='\r'&&pBuf[CharRange.cpMax-1]=='\n'){
379 CharRange.cpMax-=2;
380 }
381
382 i2++; //先頭行のタブ文字も追加の対象
383 TextEdit_SetSel(WndNum,CharRange.cpMin,CharRange.cpMax);
384
385 pTemp=(char *)HeapAlloc(hHeap,0,CharRange.cpMax-CharRange.cpMin+1 +i2);
386
387 i=CharRange.cpMin;
388 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
389 i3=0;
390 }
391 else{
392 pTemp[0]='\t';
393 i3=1;
394 }
395 for(;i<CharRange.cpMax;i++,i3++){
396 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'&&
397 (!(pBuf[i+2]=='\r'&&pBuf[i+3]=='\n'))){
398 pTemp[i3]='\r';
399 pTemp[i3+1]='\n';
400 pTemp[i3+2]='\t';
401 i3+=2;
402
403 i++;
404 continue;
405 }
406 pTemp[i3]=pBuf[i];
407 }
408 pTemp[i3]=0;
409 }
410
411 //リプレイス
412 TextEdit_ReplaceUpdateUndoData(WndNum,pTemp,0,0);
413 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
414
415 HeapDefaultFree(pTemp);
416
417 //キャレット位置の設定
418 for(i=CharRange.cpMin+i3;;i++){
419 if(pBuf[i]=='\0') break;
420 if(pBuf[i]=='\r'&&pBuf[i+1]=='\n'){
421 i+=2;
422 break;
423 }
424 }
425 TextEdit_SetSel(WndNum,
426 CharRange.cpMin,
427 i);
428
429 //再描画
430 if(!TextEdit_ScrollCaret(WndNum,0))
431 InvalidateRect(hwnd,NULL,0);
432 ResetCaretPos(WndNum);
433
434 return;
435 }
436 else{
437 temporary[0]='\t';
438 temporary[1]=0;
439 }
440 }
441 else{
442 temporary[0]=nVirtualKey;
443 temporary[1]=0;
444 }
445
446
447 if(ComplementWndInfo.hWnd){
448 //コード補完リスト表示中のとき
449 ComplementWndInfo.iLength++;
450 }
451
452
453
454 ///////////////////////
455 // キー入力の受け入れ
456 ///////////////////////
457
458 TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
459
460
461
462 ////////////////////////////////////////////
463 // コード補完機能、パラメータヒントなど
464 ////////////////////////////////////////////
465
466 if(MdiInfo[WndNum].DocType==WNDTYPE_BASIC)
467 TextEditEvent_StartAnalysis_Basic(hwnd,WndNum,nVirtualKey);
468 else if(MdiInfo[WndNum].DocType==WNDTYPE_HTML){
469 TextEditEvent_StartAnalysis_Html(hwnd,WndNum,nVirtualKey);
470 }
471}
472void TextEditEvent_KeyDown(HWND hwnd,int nVirtualKey,int lKeyData){
473 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
474 int i,i2;
475 CHARRANGE CharRange;
476 char *pBuf;
477
478 int WndNum;
479 WndNum=GetWndNum(GetParent(hwnd));
480
481 if(nVirtualKey==VK_LEFT||nVirtualKey==VK_UP||nVirtualKey==VK_RIGHT||nVirtualKey==VK_DOWN||nVirtualKey==VK_PRIOR||nVirtualKey==VK_NEXT){
482 if(MdiInfo[WndNum].IndentStr){
483 //自動インデント中のインデントを無効にする
484 CancelBeforeAutoIndent(WndNum);
485 if(nVirtualKey==VK_LEFT) return;
486 }
487
488 if(ComplementWndInfo.hWnd){
489 //コード補完リスト表示中のとき
490 if(!(nVirtualKey==VK_LEFT||nVirtualKey==VK_RIGHT)){
491 //コード補完リストにフォーカスを与える
492 PostMessage(ComplementWndInfo.hList,WM_KEYDOWN,nVirtualKey,lKeyData);
493 return;
494 }
495 }
496
497 switch(nVirtualKey){
498 case VK_LEFT:
499 //上下キャレット移動時の左右位置保持機能を解除
500 MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
501
502 if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
503 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
504 GetKeyState(VK_SHIFT)&0x8000){
505 //選択中でないとき、またはシフトキーが押されているとき
506 GetNaturalCaretPos_Left(WndNum);
507 }
508 else{
509 //選択中のとき
510 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
511 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
512 else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
513 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
514 else{
515 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
516 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
517 else
518 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
519 }
520 }
521 break;
522 case VK_RIGHT:
523 //上下キャレット移動時の左右位置保持機能を解除
524 MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
525
526 if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
527 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
528 GetKeyState(VK_SHIFT)&0x8000){
529 //選択中でないとき、またはシフトキーが押されているとき
530 GetNaturalCaretPos_Right(WndNum,
531 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
532 }
533 else{
534 //選択中のとき
535 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
536 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
537 else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
538 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
539 else{
540 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
541 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
542 else
543 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
544 }
545 }
546 break;
547 case VK_UP:
548 if((GetKeyState(VK_CONTROL)&0x8000)&&
549 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x!=0){
550 //行の先頭へキャレットを移動
551 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
552
553 //上下キャレット移動時の左右位置保持機能を解除
554 MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
555 }
556 else{
557 if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
558 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
559 GetKeyState(VK_SHIFT)&0x8000){
560 //選択中でないとき、またはシフトキーが押されているとき
561 GetNaturalCaretPos_Up(WndNum,
562 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
563 }
564 else{
565 //選択中のとき
566 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
567 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
568 else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
569 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
570 else{
571 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
572 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
573 else
574 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
575 }
576
577 GetNaturalCaretPos_Up(WndNum,
578 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
579 }
580 }
581 break;
582 case VK_DOWN:
583 i2=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y;
584 if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
585 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
586 GetKeyState(VK_SHIFT)&0x8000){
587 //選択中でないとき、またはシフトキーが押されているとき
588 GetNaturalCaretPos_Down(WndNum,
589 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
590 }
591 else{
592 //選択中のとき
593 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
594 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
595 else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
596 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
597 else{
598 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
599 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
600 else
601 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
602 }
603
604 GetNaturalCaretPos_Down(WndNum,
605 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
606 }
607
608 if(GetKeyState(VK_CONTROL)&0x8000){
609 if(i2!=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y){
610 //行の先頭へキャレットを移動
611 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
612 }
613 else{
614 //行の末端へキャレットを移動(終端行の場合)
615 CaretPos_LooseToNatural(WndNum,
616 INT_MAX,
617 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y,
618 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
619 }
620
621 //上下キャレット移動時の左右位置保持機能を解除
622 MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
623 }
624 break;
625 case VK_PRIOR:
626 GetNaturalCaretPos_PageUp(WndNum,
627 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
628 break;
629 case VK_NEXT:
630 GetNaturalCaretPos_PageDown(WndNum,
631 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
632 break;
633 }
634
635 if(!(GetKeyState(VK_SHIFT)&0x8000)){
636 //シフトキーが押されていない、通常時
637 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
638 }
639
640 if(nVirtualKey==VK_PRIOR){
641 //ページアップスクロール
642 SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);
643 }
644 else if(nVirtualKey==VK_NEXT){
645 //ページダウンスクロール
646 SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);
647 }
648 else{
649 //その他、スクロールが必要な場合を考慮
650 TextEdit_ScrollCaret(WndNum,0);
651 ResetCaretPos(WndNum);
652 }
653
654 //編集メニューをリセット
655 ResetState_EditMenu();
656
657 //再描画(選択時の反転表示が解除されたときを考慮)
658 UpdateWindow(hwnd); //ちらつき防止
659 InvalidateRect(hwnd,NULL,0);
660 }
661 else if(nVirtualKey==VK_HOME||nVirtualKey==VK_END){
662
663 //上下キャレット移動時の左右位置保持機能を解除
664 MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
665
666 if(GetKeyState(VK_CONTROL)&0x8000){
667 //ファイルの先頭または末端へキャレットを移動
668 if(nVirtualKey==VK_HOME){
669 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
670 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y=0;
671 }
672 else if(nVirtualKey==VK_END){
673 //存在するキャレット位置に変換
674 CaretPos_LooseToNatural(WndNum,
675 INT_MAX,
676 INT_MAX,
677 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
678 }
679 }
680 else{
681 //行の先頭または末端へキャレットを移動
682 if(nVirtualKey==VK_HOME) MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
683 else if(nVirtualKey==VK_END){
684 //存在するキャレット位置に変換
685 CaretPos_LooseToNatural(WndNum,
686 INT_MAX,
687 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y,
688 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
689 }
690 }
691
692 if(!(GetKeyState(VK_SHIFT)&0x8000)){
693 //シフトキーが押されていない、通常時
694 MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
695 }
696
697 if(!TextEdit_ScrollCaret(WndNum,0)){
698 //再描画(選択時の反転表示が解除されたときを考慮)
699 InvalidateRect(hwnd,NULL,0);
700 }
701 ResetCaretPos(WndNum);
702
703 //編集メニューをリセット
704 ResetState_EditMenu();
705 }
706 else if(nVirtualKey==VK_DELETE){
707 ////////////
708 // 削除キー
709 ////////////
710
711 TextEdit_GetSel(WndNum,&CharRange);
712
713 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
714
715 //キャレットがファイルの終端にあるとき
716 if(CharRange.cpMin==lstrlen(pBuf)) return;
717
718 if(CharRange.cpMin==CharRange.cpMax){
719 if(MdiInfo[WndNum].IndentStr){
720 //自動インデントを有効にする
721 char temporary[1024];
722 lstrcpy(temporary,MdiInfo[WndNum].IndentStr);
723
724 CancelBeforeAutoIndent(WndNum);
725 TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
726 }
727
728 if(pBuf[CharRange.cpMin]=='\r'&&pBuf[CharRange.cpMin+1]=='\n'||
729 IsDBCSLeadByte(pBuf[CharRange.cpMin])){
730 CharRange.cpMax+=2;
731 }
732 else CharRange.cpMax++;
733
734 GetCaretPosFromBufferIndex(
735 MdiInfo[WndNum].pMdiTextEdit->buffer,
736 CharRange.cpMax,
737 &MdiInfo[WndNum].pMdiTextEdit->EndCaretPos);
738 }
739
740 TextEdit_ReplaceUpdateUndoData(WndNum,"",0,1);
741 }
742 else if(nVirtualKey==VK_BACK){
743 /////////////////
744 // BackSpaceキー
745 /////////////////
746
747 if(MdiInfo[WndNum].IndentStr){
748 //自動インデント中のインデントの場合、インデントの1文字を削除する
749 if(lstrlen(MdiInfo[WndNum].IndentStr)==1){
750 //1文字しか残っていない場合は自動インデントそのものを消去する
751 CancelBeforeAutoIndent(WndNum);
752 }
753 else{
754 MdiInfo[WndNum].IndentStr[lstrlen(MdiInfo[WndNum].IndentStr)-1]=0;
755
756 i=GetBufferIndexFromCaretPos(
757 MdiInfo[WndNum].pMdiTextEdit->buffer,
758 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
759 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
760 GetCaretPosFromBufferIndex(
761 MdiInfo[WndNum].pMdiTextEdit->buffer,
762 i-1,
763 &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
764 TextEdit_Replace(WndNum,"",1);
765 }
766 return;
767 }
768
769 TextEdit_GetSel(WndNum,&CharRange);
770
771 if(CharRange.cpMax==0) return;
772 if(CharRange.cpMin==CharRange.cpMax){
773 if(ComplementWndInfo.hWnd){
774 //コード補完リスト表示中のとき
775 ComplementWndInfo.iLength--;
776 }
777
778 SendMessage(hwnd,WM_KEYDOWN,VK_LEFT,0);
779 }
780 SendMessage(hwnd,WM_KEYDOWN,VK_DELETE,0);
781 }
782}
783
784
785
786void TextEditEvent_StartAnalysis_Basic(HWND hwnd,int WndNum,int nVirtualKey){
787 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
788 int i,i2,i3;
789 CHARRANGE CharRange;
790 char temporary[1024];
791
792 char *pBuf;
793 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
794
795
796 ////////////////////
797 // パラメータヒント
798 ////////////////////
799
800 extern METHODCHECKINFO MethodCheckInfo;
801 if(pobj_nv->dwParameterHint&&
802 (!ComplementWndInfo.hWnd)&&
803 (MethodCheckInfo.hWnd||nVirtualKey==' '||nVirtualKey=='\"'||nVirtualKey=='(')){
804 //直前に入力された文字を表示
805 UpdateWindow(hwnd);
806
807 //パラメータヒントを表示
808 ShowParameterHint(WndNum);
809 }
810
811
812 ///////////////////////////////
813 // ペアステートメント補完
814 ///////////////////////////////
815
816 if(
817 pobj_nv->BackNum_PairStatementComplement&&
818 (nVirtualKey=='c'||nVirtualKey=='C'|| //Case
819 nVirtualKey=='e'||nVirtualKey=='E'|| //End ~
820 nVirtualKey=='l'||nVirtualKey=='L'|| //Loop
821 nVirtualKey=='n'||nVirtualKey=='N'|| //Next
822 nVirtualKey=='p'||nVirtualKey=='P'|| //Private、Protected、Public
823 nVirtualKey=='w'||nVirtualKey=='W') //Wend
824 ){
825
826 i=GetBufferIndexFromCaretPos(pBuf,
827 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
828 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
829
830 i2=i-2;
831 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2--;
832 if(IsCommandBackDelimitation(pBuf,i2)){
833 if(GetEndPairCommandInfo(pBuf,i-1)){
834
835 //入力された頭文字と一致するかどうかを検証
836 for(i3=0;i3<ComplementWndInfo.MemberNum;i3++){
837 if((char)CharUpper((LPSTR)(char)nVirtualKey)==
838 (char)CharUpper((LPSTR)ComplementWndInfo.pMemberInfo[i3].pName[0])) break;
839 }
840 if(i3==ComplementWndInfo.MemberNum){
841 DeleteComplementInfo();
842 return;
843 }
844
845 ComplementWndInfo.iLength=1;
846 CodeComplement(WndNum,i-1);
847
848 //初期入力時に補完リストの選択をさせるため
849 ResetCaretPos(WndNum);
850 }
851 }
852 }
853
854
855 //////////////////
856 // コード補完機能
857 //////////////////
858
859 if(nVirtualKey=='.'&&pobj_nv->bShowComplementWnd){
860 TextEdit_GetSel(WndNum,&CharRange);
861
862Complement:
863 i2=CharRange.cpMin-1;
864
865 i3=TextEdit_GetLineIndex(WndNum,i2);
866 int IsStr;
867 for(IsStr=0;i3<i2;i3++){
868 if(IsDBCSLeadByte(pBuf[i3])){
869 i3++;
870 continue;
871 }
872 if(pBuf[i3]=='\r'&&pBuf[i3+1]=='\n') break;
873 if(pBuf[i3]=='\''){
874 //注釈文のとき
875 return;
876 }
877 if(pBuf[i3]=='\"') IsStr^=1;
878 }
879 if(IsStr){
880 //文字列内のとき
881 return;
882 }
883
884 for(i=i2;i>0;i--){
885 if(pBuf[i-1]=='-'&&pBuf[i]=='>')i-=2;
886 if(pBuf[i]==']'){
887 for(i3=1,i--;i>0;i--){
888 if(pBuf[i]==']') i3++;
889 if(pBuf[i]=='['){
890 i3--;
891 if(i3==0) break;
892 }
893 }
894 if(pBuf[i]=='[') continue;
895 break;
896 }
897 if(pBuf[i]==')'){
898 for(i3=1,i--;i>0;i--){
899 if(pBuf[i]==')') i3++;
900 if(pBuf[i]=='('){
901 i3--;
902 if(i3==0) break;
903 }
904 }
905 if(pBuf[i]=='(') continue;
906 break;
907 }
908 if(!(IsVariableChar(pBuf[i])||pBuf[i]=='.')){
909 i++;
910 break;
911 }
912 }
913
914 if((nVirtualKey=='.'&&i2-i==0)||
915 nVirtualKey=='>'&&i2-i==1){
916 //オブジェクト識別子がないとき、Withを検索
917 GetWithObjectVariable(pBuf,i2,temporary);
918
919 if(nVirtualKey=='.') lstrcat(temporary,".");
920 else lstrcat(temporary,"->");
921 }
922 else{
923 //オブジェクト識別子をtemporaryにコピー
924
925 //アクセス違反を防ぐため、VN_SIZE以上の参照データへの補完は行わない
926 if(i2-i>VN_SIZE) return;
927
928 if(pBuf[i]=='.'){
929 GetWithObjectVariable(pBuf,i2,temporary);
930 }
931 else if(pBuf[i]=='-'&&pBuf[i+1]=='>'){
932 GetWithObjectVariable(pBuf,i2,temporary);
933 }
934 else temporary[0]=0;
935
936 i3=lstrlen(temporary);
937 memcpy(temporary+i3,pBuf+i,i2-i+1);
938 temporary[i3+i2-i+1]=0;
939 }
940
941 if(temporary[0]){
942 //オブジェクト識別子を検出した場合
943 if(GetComplementInfo(temporary,pBuf,i2)){
944 ComplementWndInfo.iLength=0;
945 CodeComplement(WndNum,i2+1);
946 }
947 }
948 }
949 else if(nVirtualKey=='>'&&pobj_nv->bShowComplementWnd){
950 TextEdit_GetSel(WndNum,&CharRange);
951 if(pBuf[CharRange.cpMin-2]=='-'){
952 goto Complement;
953 }
954 }
955}
956void TextEditEvent_StartAnalysis_Html(HWND hwnd,int WndNum,int nVirtualKey){
957 //////////////////////////
958 // HTMLのコード補完
959 //////////////////////////
960
961 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
962 int i;
963
964 char *pBuf;
965 pBuf=MdiInfo[WndNum].pMdiTextEdit->buffer;
966
967
968
969 ///////////////////////////////
970 // コード補完
971 ///////////////////////////////
972
973 if(nVirtualKey==' '){
974
975 i=GetBufferIndexFromCaretPos(pBuf,
976 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
977 MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
978
979 if(GetNowTagInfo(pBuf,i-1)){
980 ComplementWndInfo.iLength=0;
981 CodeComplement(WndNum,i);
982
983 //初期入力時に補完リストの選択をさせるため
984 ResetCaretPos(WndNum);
985 }
986 }
987}
Note: See TracBrowser for help on using the repository browser.