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

Last change on this file since 380 was 380, checked in by dai_9181, 16 years ago

Foreachに対応。
ジェネリクスインターフェイスに対応。

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