source: dev/ProjectEditor/TextEditor_KeyEvent.cpp@ 22

Last change on this file since 22 was 22, checked in by dai_9181, 17 years ago

バックアップ用ディレクトリが消去されていたときは、自動生成する。
プロ版の概念を除去。機能制限を解除。

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