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

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

Throw→Catch間のパラメータ引渡しに対応。
グローバル領域でのTryスコープを可能にした。これで例外処理機構実装完了。
エディタの補間機能にTry/Catch/Finally/EndTryを追加。

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