source: dev/trunk/ab5.0/abdev/abdev/TextEditor_KeyEvent.cpp@ 629

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

MDIINFO構造体をリファクタリング。

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