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

Last change on this file since 771 was 771, checked in by イグトランス (egtra), 15 years ago

リモートデスクトップ使用時の描画を改善(ダブルバッファの不使用、キャレット移動時の再描画をいくらか排除)。

File size: 27.4 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 bool isSelectedBefore = MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x!=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x
491 || MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y!=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y;
492
493 if(nVirtualKey==VK_LEFT||nVirtualKey==VK_UP||nVirtualKey==VK_RIGHT||nVirtualKey==VK_DOWN||nVirtualKey==VK_PRIOR||nVirtualKey==VK_NEXT){
494 if(MdiInfo[WndNum]->IndentStr){
495 //自動インデント中のインデントを無効にする
496 CancelBeforeAutoIndent(WndNum);
497 if(nVirtualKey==VK_LEFT) return;
498 }
499
500 if(ComplementWndInfo.hWnd){
501 //コード補完リスト表示中のとき
502 if(!(nVirtualKey==VK_LEFT||nVirtualKey==VK_RIGHT)){
503 //コード補完リストにフォーカスを与える
504 PostMessage(ComplementWndInfo.hList,WM_KEYDOWN,nVirtualKey,lKeyData);
505 return;
506 }
507 }
508
509 switch(nVirtualKey){
510 case VK_LEFT:
511 //上下キャレット移動時の左右位置保持機能を解除
512 MdiInfo[WndNum]->pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
513
514 if((MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x&&
515 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)||
516 GetKeyState(VK_SHIFT)&0x8000){
517 //選択中でないとき、またはシフトキーが押されているとき
518 GetNaturalCaretPos_Left(WndNum);
519 }
520 else{
521 //選択中のとき
522 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
523 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
524 else if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
525 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
526 else{
527 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x)
528 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
529 else
530 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
531 }
532 }
533 break;
534 case VK_RIGHT:
535 //上下キャレット移動時の左右位置保持機能を解除
536 MdiInfo[WndNum]->pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
537
538 if((MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x&&
539 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)||
540 GetKeyState(VK_SHIFT)&0x8000){
541 //選択中でないとき、またはシフトキーが押されているとき
542 GetNaturalCaretPos_Right(WndNum,
543 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
544 }
545 else{
546 //選択中のとき
547 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
548 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
549 else if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
550 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
551 else{
552 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x)
553 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
554 else
555 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
556 }
557 }
558 break;
559 case VK_UP:
560 if((GetKeyState(VK_CONTROL)&0x8000)&&
561 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x!=0){
562 //行の先頭へキャレットを移動
563 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x=0;
564
565 //上下キャレット移動時の左右位置保持機能を解除
566 MdiInfo[WndNum]->pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
567 }
568 else{
569 if((MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x&&
570 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)||
571 GetKeyState(VK_SHIFT)&0x8000){
572 //選択中でないとき、またはシフトキーが押されているとき
573 GetNaturalCaretPos_Up(WndNum,
574 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
575 }
576 else{
577 //選択中のとき
578 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
579 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
580 else if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
581 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
582 else{
583 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x)
584 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
585 else
586 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
587 }
588
589 GetNaturalCaretPos_Up(WndNum,
590 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
591 }
592 }
593 break;
594 case VK_DOWN:
595 i2=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y;
596 if((MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x&&
597 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)||
598 GetKeyState(VK_SHIFT)&0x8000){
599 //選択中でないとき、またはシフトキーが押されているとき
600 GetNaturalCaretPos_Down(WndNum,
601 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
602 }
603 else{
604 //選択中のとき
605 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
606 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
607 else if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.y)
608 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
609 else{
610 if(MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos.x)
611 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos=MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos;
612 else
613 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
614 }
615
616 GetNaturalCaretPos_Down(WndNum,
617 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
618 }
619
620 if(GetKeyState(VK_CONTROL)&0x8000){
621 if(i2!=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y){
622 //行の先頭へキャレットを移動
623 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x=0;
624 }
625 else{
626 //行の末端へキャレットを移動(終端行の場合)
627 CaretPos_LooseToNatural(WndNum,
628 INT_MAX,
629 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y,
630 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
631 }
632
633 //上下キャレット移動時の左右位置保持機能を解除
634 MdiInfo[WndNum]->pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
635 }
636 break;
637 case VK_PRIOR:
638 GetNaturalCaretPos_PageUp(WndNum,
639 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
640 break;
641 case VK_NEXT:
642 GetNaturalCaretPos_PageDown(WndNum,
643 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
644 break;
645 }
646
647 if(!(GetKeyState(VK_SHIFT)&0x8000)){
648 //シフトキーが押されていない、通常時
649 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
650 }
651
652 if(nVirtualKey==VK_PRIOR){
653 //ページアップスクロール
654 SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);
655 }
656 else if(nVirtualKey==VK_NEXT){
657 //ページダウンスクロール
658 SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);
659 }
660 else{
661 //その他、スクロールが必要な場合を考慮
662 TextEdit_ScrollCaret(WndNum,0);
663 ResetCaretPos(WndNum);
664 }
665
666 //編集メニューをリセット
667 ResetState_EditMenu();
668
669 if(!TextEdit_ScrollCaret(WndNum,0)&&isSelectedBefore){
670 UpdateWindow(hwnd); //ちらつき防止
671 //再描画(選択時の反転表示が解除されたときを考慮)
672 InvalidateRect(hwnd,NULL,0);
673 }
674 }
675 else if(nVirtualKey==VK_HOME||nVirtualKey==VK_END){
676
677 //上下キャレット移動時の左右位置保持機能を解除
678 MdiInfo[WndNum]->pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
679
680 if(GetKeyState(VK_CONTROL)&0x8000){
681 //ファイルの先頭または末端へキャレットを移動
682 if(nVirtualKey==VK_HOME){
683 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x=0;
684 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y=0;
685 }
686 else if(nVirtualKey==VK_END){
687 //存在するキャレット位置に変換
688 CaretPos_LooseToNatural(WndNum,
689 INT_MAX,
690 INT_MAX,
691 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
692 }
693 }
694 else{
695 //行の先頭または末端へキャレットを移動
696 if(nVirtualKey==VK_HOME) MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x=0;
697 else if(nVirtualKey==VK_END){
698 //存在するキャレット位置に変換
699 CaretPos_LooseToNatural(WndNum,
700 INT_MAX,
701 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y,
702 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
703 }
704 }
705
706 if(!(GetKeyState(VK_SHIFT)&0x8000)){
707 //シフトキーが押されていない、通常時
708 MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
709 }
710
711 if(!TextEdit_ScrollCaret(WndNum,0)&&isSelectedBefore){
712 //再描画(選択時の反転表示が解除されたときを考慮)
713 InvalidateRect(hwnd,NULL,0);
714 }
715 ResetCaretPos(WndNum);
716
717 //編集メニューをリセット
718 ResetState_EditMenu();
719 }
720 else if(nVirtualKey==VK_DELETE){
721 ////////////
722 // 削除キー
723 ////////////
724
725 TextEdit_GetSel(WndNum,&CharRange);
726
727 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
728
729 //キャレットがファイルの終端にあるとき
730 if(CharRange.cpMin==lstrlen(pBuf)) return;
731
732 if(CharRange.cpMin==CharRange.cpMax){
733 if(MdiInfo[WndNum]->IndentStr){
734 //自動インデントを有効にする
735 char temporary[1024];
736 lstrcpy(temporary,MdiInfo[WndNum]->IndentStr);
737
738 CancelBeforeAutoIndent(WndNum);
739 TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
740 }
741
742 if(pBuf[CharRange.cpMin]=='\r'&&pBuf[CharRange.cpMin+1]=='\n'||
743 IsDBCSLeadByte(pBuf[CharRange.cpMin])){
744 CharRange.cpMax+=2;
745 }
746 else CharRange.cpMax++;
747
748 GetCaretPosFromBufferIndex(
749 MdiInfo[WndNum]->pMdiTextEdit->buffer,
750 CharRange.cpMax,
751 &MdiInfo[WndNum]->pMdiTextEdit->EndCaretPos);
752 }
753
754 TextEdit_ReplaceUpdateUndoData(WndNum,"",0,1);
755 }
756 else if(nVirtualKey==VK_BACK){
757 /////////////////
758 // BackSpaceキー
759 /////////////////
760
761 if(MdiInfo[WndNum]->IndentStr){
762 //自動インデント中のインデントの場合、インデントの1文字を削除する
763 if(lstrlen(MdiInfo[WndNum]->IndentStr)==1){
764 //1文字しか残っていない場合は自動インデントそのものを消去する
765 CancelBeforeAutoIndent(WndNum);
766 }
767 else{
768 MdiInfo[WndNum]->IndentStr[lstrlen(MdiInfo[WndNum]->IndentStr)-1]=0;
769
770 i=GetBufferIndexFromCaretPos(
771 MdiInfo[WndNum]->pMdiTextEdit->buffer,
772 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x,
773 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y);
774 GetCaretPosFromBufferIndex(
775 MdiInfo[WndNum]->pMdiTextEdit->buffer,
776 i-1,
777 &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
778 TextEdit_Replace(WndNum,"",1);
779 }
780 return;
781 }
782
783 TextEdit_GetSel(WndNum,&CharRange);
784
785 if(CharRange.cpMax==0) return;
786 if(CharRange.cpMin==CharRange.cpMax){
787 if(ComplementWndInfo.hWnd){
788 //コード補完リスト表示中のとき
789 ComplementWndInfo.iLength--;
790 }
791
792 SendMessage(hwnd,WM_KEYDOWN,VK_LEFT,0);
793 }
794 SendMessage(hwnd,WM_KEYDOWN,VK_DELETE,0);
795 }
796}
797
798
799
800void TextEditEvent_StartAnalysis_Basic(HWND hwnd,int WndNum,int nVirtualKey){
801 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
802 int i,i2,i3;
803 CHARRANGE CharRange;
804 char temporary[1024];
805
806 char *pBuf;
807 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
808
809
810 ////////////////////
811 // パラメータヒント
812 ////////////////////
813
814 extern METHODCHECKINFO MethodCheckInfo;
815 if(pobj_nv->dwParameterHint&&
816 (!ComplementWndInfo.hWnd)&&
817 (MethodCheckInfo.hWnd||nVirtualKey==' '||nVirtualKey=='\"'||nVirtualKey=='(')){
818 //直前に入力された文字を表示
819 UpdateWindow(hwnd);
820
821 //パラメータヒントを表示
822 ShowParameterHint(WndNum);
823 }
824
825
826 ///////////////////////////////
827 // ペアステートメント補完
828 ///////////////////////////////
829
830 if(
831 pobj_nv->BackNum_PairStatementComplement&&
832 (nVirtualKey=='c'||nVirtualKey=='C'|| //Case、Catch
833 nVirtualKey=='e'||nVirtualKey=='E'|| //End ~
834 nVirtualKey=='f'||nVirtualKey=='F'|| //Finally
835 nVirtualKey=='l'||nVirtualKey=='L'|| //Loop
836 nVirtualKey=='n'||nVirtualKey=='N'|| //Next
837 nVirtualKey=='p'||nVirtualKey=='P'|| //Private、Protected、Public
838 nVirtualKey=='w'||nVirtualKey=='W') //Wend
839 ){
840
841 i=GetBufferIndexFromCaretPos(pBuf,
842 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x,
843 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y);
844
845 i2=i-2;
846 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2--;
847 if(IsCommandBackDelimitation(pBuf,i2)){
848 if(GetEndPairCommandInfo(pBuf,i-1)){
849
850 //入力された頭文字と一致するかどうかを検証
851 for(i3=0;i3<ComplementWndInfo.MemberNum;i3++){
852 if((char)CharUpper((LPSTR)(char)nVirtualKey)==
853 (char)CharUpper((LPSTR)ComplementWndInfo.pMemberInfo[i3].pName[0])) break;
854 }
855 if(i3==ComplementWndInfo.MemberNum){
856 DeleteComplementInfo();
857 return;
858 }
859
860 ComplementWndInfo.iLength=1;
861 CodeComplement(WndNum,i-1);
862
863 //初期入力時に補完リストの選択をさせるため
864 ResetCaretPos(WndNum);
865 }
866 }
867 }
868
869
870 //////////////////
871 // コード補完機能
872 //////////////////
873
874 if(nVirtualKey=='.'&&pobj_nv->bShowComplementWnd){
875 TextEdit_GetSel(WndNum,&CharRange);
876
877Complement:
878 i2=CharRange.cpMin-1;
879
880 i3=TextEdit_GetLineIndex(WndNum,i2);
881 int IsStr;
882 for(IsStr=0;i3<i2;i3++){
883 if(IsDBCSLeadByte(pBuf[i3])){
884 i3++;
885 continue;
886 }
887 if(pBuf[i3]=='\r'&&pBuf[i3+1]=='\n') break;
888 if(pBuf[i3]=='\''){
889 //注釈文のとき
890 return;
891 }
892 if(pBuf[i3]=='\"') IsStr^=1;
893 }
894 if(IsStr){
895 //文字列内のとき
896 return;
897 }
898
899 for(i=i2;i>0;i--){
900 if(pBuf[i-1]=='-'&&pBuf[i]=='>')i-=2;
901 if(pBuf[i]==']'){
902 for(i3=1,i--;i>0;i--){
903 if(pBuf[i]==']') i3++;
904 if(pBuf[i]=='['){
905 i3--;
906 if(i3==0) break;
907 }
908 }
909 if(pBuf[i]=='[') continue;
910 break;
911 }
912 if(pBuf[i]==')'){
913 for(i3=1,i--;i>0;i--){
914 if(pBuf[i]==')') i3++;
915 if(pBuf[i]=='('){
916 i3--;
917 if(i3==0) break;
918 }
919 }
920 if(pBuf[i]=='(') continue;
921 break;
922 }
923 if(!(IsVariableChar(pBuf[i])||pBuf[i]=='.')){
924 i++;
925 break;
926 }
927 }
928
929 if((nVirtualKey=='.'&&i2-i==0)||
930 nVirtualKey=='>'&&i2-i==1){
931 //オブジェクト識別子がないとき、Withを検索
932 GetWithObjectVariable(pBuf,i2,temporary);
933
934 if(nVirtualKey=='.') lstrcat(temporary,".");
935 else lstrcat(temporary,"->");
936 }
937 else{
938 //オブジェクト識別子をtemporaryにコピー
939
940 //アクセス違反を防ぐため、VN_SIZE以上の参照データへの補完は行わない
941 if(i2-i>VN_SIZE) return;
942
943 if(pBuf[i]=='.'){
944 GetWithObjectVariable(pBuf,i2,temporary);
945 }
946 else if(pBuf[i]=='-'&&pBuf[i+1]=='>'){
947 GetWithObjectVariable(pBuf,i2,temporary);
948 }
949 else temporary[0]=0;
950
951 i3=lstrlen(temporary);
952 memcpy(temporary+i3,pBuf+i,i2-i+1);
953 temporary[i3+i2-i+1]=0;
954 }
955
956 if(temporary[0]){
957 //オブジェクト識別子を検出した場合
958 if(GetComplementInfo(temporary,pBuf,i2)){
959 ComplementWndInfo.iLength=0;
960 CodeComplement(WndNum,i2+1);
961 }
962 }
963 }
964 else if(nVirtualKey=='>'&&pobj_nv->bShowComplementWnd){
965 TextEdit_GetSel(WndNum,&CharRange);
966 if(pBuf[CharRange.cpMin-2]=='-'){
967 goto Complement;
968 }
969 }
970}
971void TextEditEvent_StartAnalysis_Html(HWND hwnd,int WndNum,int nVirtualKey){
972 //////////////////////////
973 // HTMLのコード補完
974 //////////////////////////
975
976 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
977 int i;
978
979 char *pBuf;
980 pBuf=MdiInfo[WndNum]->pMdiTextEdit->buffer;
981
982
983
984 ///////////////////////////////
985 // コード補完
986 ///////////////////////////////
987
988 if(nVirtualKey==' '){
989
990 i=GetBufferIndexFromCaretPos(pBuf,
991 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.x,
992 MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos.y);
993
994 if(GetNowTagInfo(pBuf,i-1)){
995 ComplementWndInfo.iLength=0;
996 CodeComplement(WndNum,i);
997
998 //初期入力時に補完リストの選択をさせるため
999 ResetCaretPos(WndNum);
1000 }
1001 }
1002}
Note: See TracBrowser for help on using the repository browser.