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

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

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

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