source: dev/ProjectEditor/TextEditor_KeyEvent.cpp@ 3

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