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

Last change on this file since 625 was 625, checked in by dai_9181, 15 years ago

・WindowInfoクラスをリファクタリング
・MdiInfoを単純配列からvectorに変更した。

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