source: dev/ProjectEditor/TextEditor_KeyEvent.cpp @ 24

Last change on this file since 24 was 24, checked in by dai_9181, 16 years ago

保存されていないドキュメントのタブに(*)をつける機能に対応。
MDITEXTEDITINFOをCMdiTextEditに変更。今後、オブジェクト指向化を進める。

File size: 26.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].pMdiTextEdit->iUnderStart!=-1){
15            //ハイパーリンク下線の表示を解除
16            MdiInfo[WndNum].pMdiTextEdit->iUnderStart=-1;
17            MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->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].pMdiTextEdit->buffer;
238
239            int StartX;
240
241            //リプレイス前のカーソルバッファ位置を取得
242            i=GetBufferIndexFromCaretPos(pBuf,
243                MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
244                MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
245            StartX=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x;
246
247            //リプレイス
248            TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
249            pBuf=MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->StartCaretPos.x,
293                MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->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].pMdiTextEdit->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].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
499
500                if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
501                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
502                    GetKeyState(VK_SHIFT)&0x8000){
503                    //選択中でないとき、またはシフトキーが押されているとき
504                    GetNaturalCaretPos_Left(WndNum);
505                }
506                else{
507                    //選択中のとき
508                    if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
509                        MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
510                    else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
511                        MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
512                    else{
513                        if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
514                            MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
515                        else
516                            MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
517                    }
518                }
519                break;
520            case VK_RIGHT:
521                //上下キャレット移動時の左右位置保持機能を解除
522                MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
523
524                if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
525                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
526                    GetKeyState(VK_SHIFT)&0x8000){
527                    //選択中でないとき、またはシフトキーが押されているとき
528                    GetNaturalCaretPos_Right(WndNum,
529                        &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
530                }
531                else{
532                    //選択中のとき
533                    if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
534                        MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
535                    else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
536                        MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
537                    else{
538                        if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
539                            MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
540                        else
541                            MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
542                    }
543                }
544                break;
545            case VK_UP:
546                if((GetKeyState(VK_CONTROL)&0x8000)&&
547                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x!=0){
548                    //行の先頭へキャレットを移動
549                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
550
551                    //上下キャレット移動時の左右位置保持機能を解除
552                    MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
553                }
554                else{
555                    if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
556                        MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
557                        GetKeyState(VK_SHIFT)&0x8000){
558                        //選択中でないとき、またはシフトキーが押されているとき
559                        GetNaturalCaretPos_Up(WndNum,
560                            &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
561                    }
562                    else{
563                        //選択中のとき
564                        if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
565                            MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
566                        else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
567                            MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
568                        else{
569                            if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
570                                MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
571                            else
572                                MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
573                        }
574
575                        GetNaturalCaretPos_Up(WndNum,
576                            &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
577                    }
578                }
579                break;
580            case VK_DOWN:
581                i2=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y;
582                if((MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x&&
583                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)||
584                    GetKeyState(VK_SHIFT)&0x8000){
585                    //選択中でないとき、またはシフトキーが押されているとき
586                    GetNaturalCaretPos_Down(WndNum,
587                        &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
588                }
589                else{
590                    //選択中のとき
591                    if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
592                        MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
593                    else if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y>MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.y)
594                        MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
595                    else{
596                        if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x<MdiInfo[WndNum].pMdiTextEdit->EndCaretPos.x)
597                            MdiInfo[WndNum].pMdiTextEdit->StartCaretPos=MdiInfo[WndNum].pMdiTextEdit->EndCaretPos;
598                        else
599                            MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
600                    }
601
602                    GetNaturalCaretPos_Down(WndNum,
603                        &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
604                }
605
606                if(GetKeyState(VK_CONTROL)&0x8000){
607                    if(i2!=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y){
608                        //行の先頭へキャレットを移動
609                        MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
610                    }
611                    else{
612                        //行の末端へキャレットを移動(終端行の場合)
613                        CaretPos_LooseToNatural(WndNum,
614                            INT_MAX,
615                            MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y,
616                            &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
617                    }
618
619                    //上下キャレット移動時の左右位置保持機能を解除
620                    MdiInfo[WndNum].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
621                }
622                break;
623            case VK_PRIOR:
624                GetNaturalCaretPos_PageUp(WndNum,
625                    &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
626                break;
627            case VK_NEXT:
628                GetNaturalCaretPos_PageDown(WndNum,
629                    &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
630                break;
631        }
632
633        if(!(GetKeyState(VK_SHIFT)&0x8000)){
634            //シフトキーが押されていない、通常時
635            MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->Temp_UpDown_CaretXPos=-1;
663
664        if(GetKeyState(VK_CONTROL)&0x8000){
665            //ファイルの先頭または末端へキャレットを移動
666            if(nVirtualKey==VK_HOME){
667                MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
668                MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y=0;
669            }
670            else if(nVirtualKey==VK_END){
671                //存在するキャレット位置に変換
672                CaretPos_LooseToNatural(WndNum,
673                    INT_MAX,
674                    INT_MAX,
675                    &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
676            }
677        }
678        else{
679            //行の先頭または末端へキャレットを移動
680            if(nVirtualKey==VK_HOME) MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x=0;
681            else if(nVirtualKey==VK_END){
682                //存在するキャレット位置に変換
683                CaretPos_LooseToNatural(WndNum,
684                    INT_MAX,
685                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y,
686                    &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
687            }
688        }
689
690        if(!(GetKeyState(VK_SHIFT)&0x8000)){
691            //シフトキーが押されていない、通常時
692            MdiInfo[WndNum].pMdiTextEdit->EndCaretPos=MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->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].pMdiTextEdit->buffer,
734                CharRange.cpMax,
735                &MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->buffer,
756                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
757                    MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
758                GetCaretPosFromBufferIndex(
759                    MdiInfo[WndNum].pMdiTextEdit->buffer,
760                    i-1,
761                    &MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->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].pMdiTextEdit->StartCaretPos.x,
826            MdiInfo[WndNum].pMdiTextEdit->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].pMdiTextEdit->buffer;
964
965
966
967    ///////////////////////////////
968    // コード補完
969    ///////////////////////////////
970
971    if(nVirtualKey==' '){
972 
973        i=GetBufferIndexFromCaretPos(pBuf,
974            MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.x,
975            MdiInfo[WndNum].pMdiTextEdit->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.