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

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

Tryスコープのコード補完機能のバグを修正(EndTryコード補間が過剰に行われていた)。
コンパイラのログ生成処理をきった。

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