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

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

構成管理を変更中・・・(いったんコミット)

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