source: dev/trunk/ab5.0/abdev/abdev/Complement.cpp

Last change on this file was 829, checked in by イグトランス (egtra), 11 years ago

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/plain; charset=Shift_JIS
File size: 19.9 KB
Line 
1#include "stdafx.h"
2
3#include "common.h"
4
5///////////////////////////
6// コード補完機能
7///////////////////////////
8
9BOOL GetComplementClass(char *pBuf,char *ClassName,char *nest,BOOL bInherits){
10    extern HANDLE hHeap;
11    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
12    extern char *pHeaderBuf;
13    extern char *pUserSource;
14    int i,i2;
15    char temporary[8192];
16    DWORD dwClassType;
17    BOOL bRet;
18
19
20    /////////////////////////////////////////
21    // ソースコードからクラス定義位置を取得
22    /////////////////////////////////////////
23    i=GetClassPos(pBuf,ClassName,&dwClassType);
24    if(pBuf[i]=='\0') return 0;
25
26
27    if(nest[0]){
28        ////////////////////
29        // 入れ子構造の場合
30        ////////////////////
31
32        //クラス、配列の構成要素を解析する
33        char VarName[VN_SIZE];      //変数名
34        char array[VN_SIZE];        //第1次配列
35        char lpPtrOffset[VN_SIZE];  //第2次配列
36        char NestMember[VN_SIZE];   //入れ子メンバ
37        int RefType;                //"."参照のときは0、"->"参照のときは1
38        lstrcpy(VarName,nest);
39        if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)) return 0;
40
41        //メンバ変数の型であるクラスの名前を取得
42        char ClassName[VN_SIZE];
43        BOOL bArray;
44        if(!GetClassNameFromClassMember(pBuf,i,VarName,ClassName,&bArray)) return 0;
45
46        //TypeDef宣言を考慮してオリジナルなクラス名を取得
47        GetOriginalClassName(ClassName);
48
49        if(!CheckReferType(ClassName,bArray,array,RefType)) return 0;
50
51        //ユーザーのソースコードをサーチ
52        bRet=GetComplementClass(pUserSource,ClassName,NestMember,0);
53        if(!bRet){
54            //失敗したときはbasic.sbpをサーチ
55            bRet=GetComplementClass(pHeaderBuf,ClassName,NestMember,0);
56        }
57        return bRet;
58    }
59
60
61    ////////////////////////
62    // メンバ情報を取得
63    ////////////////////////
64    DWORD dwAccess;
65    DWORD dwProc;
66
67    //アクセス制限の初期値をセット
68    if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE;
69    else dwAccess=ACCESS_PUBLIC;
70
71    if(memicmp(pBuf+i,"Inherits",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){
72        i+=9;
73        while(pBuf[i]==' '||pBuf[i]=='\t') i++;
74
75        //継承を行う場合
76        for(i2=0;;i++,i2++){
77            if(!IsVariableChar(pBuf[i])){
78                temporary[i2]=0;
79                break;
80            }
81            temporary[i2]=pBuf[i];
82        }
83
84        //ユーザーのソースコードをサーチ
85        bRet=GetComplementClass(pUserSource,temporary,"",1);
86        if(!bRet){
87            //失敗したときはbasic.sbpをサーチ
88            bRet=GetComplementClass(pHeaderBuf,temporary,"",1);
89        }
90
91        for(;;i++){
92            if(pBuf[i]=='\0') break;
93            i2=IsCommandDelimitation(pBuf,i);
94            if(i2){
95                i+=i2;
96                break;
97            }
98        }
99        JumpBlank(pBuf,&i);
100    }
101
102    //メンバ変数、関数を取得
103    while(1){
104        if(pBuf[i]=='\0') break;
105        if(memicmp(pBuf+i,"End",3)==0){
106            /*  End Class
107                End Type
108                の検出 */
109            i2=i+3;
110            while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
111
112            if(memicmp(pBuf+i2,"Class",5)==0&&(!IsVariableChar(pBuf[i2+5]))||
113                memicmp(pBuf+i2,"Interface",9)==0&&(!IsVariableChar(pBuf[i2+9]))||
114                memicmp(pBuf+i2,"Type",4)==0&&(!IsVariableChar(pBuf[i2+4]))) break;
115        }
116
117        if(memicmp(pBuf+i,"Abstract",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
118            memicmp(pBuf+i,"Virtual",7)==0&&(pBuf[i+7]==' '||pBuf[i+7]=='\t')||
119            memicmp(pBuf+i,"Override",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
120            memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
121            memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){
122            //メンバ関数のとき
123            if(pBuf[i]=='a'||pBuf[i]=='A'){
124                i+=9;
125                dwProc=ESC_ABSTRACT;
126
127                while(pBuf[i]==' '||pBuf[i]=='\t') i++;
128                if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
129                else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
130            }
131            else if(pBuf[i]=='v'||pBuf[i]=='V'){
132                i+=8;
133                dwProc=ESC_VIRTUAL;
134
135                while(pBuf[i]==' '||pBuf[i]=='\t') i++;
136                if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
137                else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
138            }
139            else if(pBuf[i]=='o'||pBuf[i]=='O'){
140                i+=9;
141                dwProc=ESC_OVERRIDE;
142
143                while(pBuf[i]==' '||pBuf[i]=='\t') i++;
144                if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
145                else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
146            }
147            else if(pBuf[i]=='f'||pBuf[i]=='F'){
148                i+=9;
149                dwProc=ESC_FUNCTION;
150            }
151            else if(pBuf[i]=='s'||pBuf[i]=='S'){
152                i+=4;
153                dwProc=ESC_SUB;
154            }
155
156            while(pBuf[i]==' '||pBuf[i]=='\t') i++;
157        }
158        else{
159            //メンバ変数のとき
160            dwProc=0;
161        }
162
163        //変数名または関数名を取得
164        if(pBuf[i]=='~'){
165            temporary[0]='~';
166            i2=1;
167            i++;
168        }
169        else i2=0;
170        for(;;i++,i2++){
171            if(!IsVariableChar(pBuf[i])){
172                temporary[i2]=0;
173                break;
174            }
175            temporary[i2]=pBuf[i];
176        }
177
178        if(bInherits){
179            //継承元の場合はコンストラクタ、デストラクタを除去
180            if(temporary[0]=='~') goto next;
181            if(lstrcmp(temporary,ClassName)==0) goto next;
182        }
183
184        //次の行をサーチ
185        for(;;i++){
186            if(pBuf[i]=='\0') break;
187            if(pBuf[i]=='\''||(pBuf[i]=='/'&&pBuf[i+1]=='*')){
188                //コメント中
189                JumpBlank(pBuf,&i);
190                break;
191            }
192            i2=IsCommandDelimitation(pBuf,i);
193            if(i2){
194                i+=i2;
195                break;
196            }
197        }
198        JumpBlank(pBuf,&i);
199
200        //重複チェック(オーバーライド関数の除去)
201        for(i2=0;i2<ComplementWndInfo.MemberNum;i2++){
202            if(lstrcmp(ComplementWndInfo.pMemberInfo[i2].pName,temporary)==0) goto next;
203        }
204
205        //アクセスを変更
206        if(lstrcmpi(temporary,"Private")==0){
207            dwAccess=ACCESS_PRIVATE;
208            continue;
209        }
210        if(lstrcmpi(temporary,"Public")==0){
211            dwAccess=ACCESS_PUBLIC;
212            continue;
213        }
214        if(lstrcmpi(temporary,"Protected")==0){
215            dwAccess=ACCESS_PROTECTED;
216            continue;
217        }
218
219        ComplementWndInfo.pMemberInfo=
220            (MEMBERINFO *)HeapReAlloc(hHeap,
221                0,
222                ComplementWndInfo.pMemberInfo,
223                (ComplementWndInfo.MemberNum+1)*sizeof(MEMBERINFO));
224
225        //メンバ名
226        ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].pName=
227            (char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
228        lstrcpy(ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].pName,
229            temporary);
230
231        //メンバの種類(変数、Virtual、Sub、Function)
232        ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].dwProc=dwProc;
233
234        //アクセシビリティ
235        ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].dwAccess=dwAccess;
236
237        ComplementWndInfo.MemberNum++;
238next:
239        if(dwProc){
240            //Abstract定義以外はEnd Sub、End Functionをサーチする
241            if(dwProc==ESC_ABSTRACT) continue;
242            if(dwClassType==ESC_INTERFACE) continue;
243
244            while(1){
245                if(pBuf[i]=='\0'){
246                    i2=0;
247                    break;
248                }
249
250                if(memicmp(pBuf+i,"End",3)==0){
251                    /*  End Sub
252                        End Function
253                        の検出 */
254                    i+=3;
255                    while(pBuf[i]==' '||pBuf[i]=='\t') i++;
256
257                    if(memicmp(pBuf+i,"Sub",3)==0&&(!IsVariableChar(pBuf[i+3]))||
258                        memicmp(pBuf+i,"Function",8)==0&&(!IsVariableChar(pBuf[i+8]))){
259                        i2=1;
260                        break;
261                    }
262
263                    if(memicmp(pBuf+i,"Class",5)==0&&(!IsVariableChar(pBuf[i+5]))||
264                        memicmp(pBuf+i,"Interface",9)==0&&(!IsVariableChar(pBuf[i+9]))||
265                        memicmp(pBuf+i,"Type",4)==0&&(!IsVariableChar(pBuf[i+4]))){
266                        i2=0;
267                        break;
268                    }
269                }
270
271                //次の行をサーチ
272                for(;;i++){
273                    if(pBuf[i]=='\0') break;
274                    i2=IsCommandDelimitation(pBuf,i);
275                    if(i2){
276                        i+=i2;
277                        break;
278                    }
279                }
280                JumpBlank(pBuf,&i);
281            }
282
283            if(i2==0){
284                //コード解析が不正に終了
285                return 1;
286            }
287
288            //次の行をサーチ
289            for(;;i++){
290                if(pBuf[i]=='\0') break;
291                i2=IsCommandDelimitation(pBuf,i);
292                if(i2){
293                    i+=i2;
294                    break;
295                }
296            }
297            JumpBlank(pBuf,&i);
298        }
299    }
300
301    return 1;
302}
303
304void DeleteComplementInfo(void){
305    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
306    int i;
307
308    for(i=0;i<ComplementWndInfo.MemberNum;i++)
309        HeapDefaultFree(ComplementWndInfo.pMemberInfo[i].pName);
310
311    HeapDefaultFree(ComplementWndInfo.pMemberInfo);
312}
313BOOL GetComplementInfo(char *variable,char *pEditBuf,int iPos){
314    extern HANDLE hHeap;
315
316    //ユーザーが作成したソースコードを取得
317    extern char *pUserSource;
318    pUserSource=GetUserSourceCode();
319
320    //クラス、配列の構成要素を解析する
321    char VarName[VN_SIZE];      //変数名
322    char array[VN_SIZE];        //第1次配列
323    char lpPtrOffset[VN_SIZE];  //第2次配列
324    char NestMember[VN_SIZE];   //入れ子メンバ
325    int RefType;                //"."参照のときは0、"->"参照のときは1
326    lstrcpy(VarName,variable);
327    if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)){
328        HeapDefaultFree(pUserSource);
329        pUserSource=0;
330        return 0;
331    }
332
333
334    ////////////////////////////////
335    // オブジェクトのクラス名を取得
336    ////////////////////////////////
337    char ClassName[VN_SIZE];
338    BOOL bArray;
339    if(!GetVariableClassName(pEditBuf,iPos,VarName,ClassName,&bArray)){
340        HeapDefaultFree(pUserSource);
341        pUserSource=0;
342        return 0;
343    }
344
345    //TypeDef宣言を考慮してオリジナルなクラス名を取得
346    GetOriginalClassName(ClassName);
347
348    if(!CheckReferType(ClassName,bArray,array,RefType)){
349        HeapDefaultFree(pUserSource);
350        pUserSource=0;
351        return 0;
352    }
353
354
355    ////////////////////
356    // クラス情報を取得
357    ////////////////////
358    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
359
360    ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,1);
361    ComplementWndInfo.MemberNum=0;
362
363    //ユーザーのソースコードをサーチ
364    BOOL bRet;
365    bRet=GetComplementClass(pUserSource,ClassName,NestMember,0);
366    if(!bRet){
367        //失敗したときはbasic.sbpをサーチ
368        extern char *pHeaderBuf;
369        bRet=GetComplementClass(pHeaderBuf,ClassName,NestMember,0);
370    }
371
372    HeapDefaultFree(pUserSource);
373    pUserSource=0;
374
375    if(!bRet||ComplementWndInfo.MemberNum==0){
376        //見つからなかったとき
377        DeleteComplementInfo();
378        return 0;
379    }
380
381    return 1;
382}
383void CodeComplement(int WndNum,int iPos){
384    int i,i2;
385
386    //エディタ画面左端のコントロールタブ
387    int iControlTabSpace;
388    iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
389
390    extern int font_width,font_height;
391    POINT pos;
392    pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
393    GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y);
394
395    pos.x=(pos.x-1)*font_width    +iControlTabSpace;
396    pos.y=(pos.y+1)*font_height;
397
398    ClientToScreen(MdiInfo[WndNum]->pMdiTextEdit->hEdit,&pos);
399
400    extern HINSTANCE hInst;
401    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
402    ComplementWndInfo.hWnd=CreateWindowEx(WS_EX_DLGMODALFRAME,
403        "ComplementWindow",NULL,
404        WS_POPUP|WS_CLIPCHILDREN,
405        pos.x,pos.y,100,100,
406        hOwner,NULL,hInst,0);
407
408    ///////////////////////////
409    // リストビューの初期化
410    ///////////////////////////
411    extern METHODCHECKINFO MethodCheckInfo;
412    int height,max_width,listitem_height;
413    max_width=0;
414
415    // リストアイテムを追加
416    LV_ITEM lvItem;
417    lvItem.mask = LVIF_TEXT|LVIF_IMAGE;
418    for(i=0;i<ComplementWndInfo.MemberNum;i++){
419        lvItem.pszText=ComplementWndInfo.pMemberInfo[i].pName;
420        lvItem.iItem=0;
421        lvItem.iSubItem=0;
422
423        if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_PAIRCOMMAND){
424            //ペアステートメント補完リストアイテム
425            lvItem.iImage=4;
426        }
427        else if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_HTML_GENERAL_PARAM){
428            //HTMLタグのパラメータ
429            lvItem.iImage=5;
430        }
431        else if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_HTML_PARAM){
432            //HTMLタグのパラメータ
433            lvItem.iImage=6;
434        }
435        else if(ComplementWndInfo.pMemberInfo[i].dwProc==0){
436            //メンバ変数
437            if(ComplementWndInfo.pMemberInfo[i].dwAccess!=ACCESS_PUBLIC)
438                lvItem.iImage=0;
439            else
440                lvItem.iImage=1;
441        }
442        else{
443            //メンバ関数
444            if(ComplementWndInfo.pMemberInfo[i].dwAccess!=ACCESS_PUBLIC)
445                lvItem.iImage=2;
446            else
447                lvItem.iImage=3;
448        }
449        ListView_InsertItem(ComplementWndInfo.hList,&lvItem);
450
451        i2=ListView_GetStringWidth(ComplementWndInfo.hList,
452            ComplementWndInfo.pMemberInfo[i].pName);
453
454        if(max_width<i2) max_width=i2;
455    }
456
457    RECT rc;
458    ListView_GetItemRect(ComplementWndInfo.hList,0,&rc,LVIR_BOUNDS);
459    listitem_height=rc.bottom-rc.top;
460    height=listitem_height*ComplementWndInfo.MemberNum;
461
462    //ウィンドウサイズとクライアント領域サイズの差を計算
463    RECT rc_Window,rc_Client;
464    SIZE size;
465    int dx,dy;
466    GetWindowRect(ComplementWndInfo.hWnd, &rc_Window);
467    GetClientRect(ComplementWndInfo.hWnd, &rc_Client);
468    dx = (rc_Window.right - rc_Window.left) - (rc_Client.right - rc_Client.left);
469    dy = (rc_Window.bottom - rc_Window.top) - (rc_Client.bottom - rc_Client.top);
470
471#define MAX_COMPLEMENT_LISTNUM 15
472    size.cx=max_width+dx+30;    //※30はアイコンの幅を含む余白
473    size.cy=height+dy;
474    if(size.cy>listitem_height*MAX_COMPLEMENT_LISTNUM+dy){
475        size.cy=listitem_height*MAX_COMPLEMENT_LISTNUM+dy;
476
477        //垂直スクロールバーの幅を考慮する
478        size.cx+=GetSystemMetrics(SM_CXVSCROLL);
479    }
480    else{
481        //スクロールバーを使用しないようにする
482        i=GetWindowLongPtr(ComplementWndInfo.hList,GWL_STYLE);
483        i|=LVS_NOSCROLL;
484        i&=~(WS_VSCROLL|WS_HSCROLL);
485        SetWindowLongPtr(ComplementWndInfo.hList,GWL_STYLE,i);
486    }
487
488    if(pos.x+size.cx>ScreenX){
489        pos.x=ScreenX-size.cx;
490    }
491    if(pos.y+size.cy>ScreenY-30){
492        pos.y-=size.cy+font_height;
493    }
494
495    //サイズ変更
496    MoveWindow(ComplementWndInfo.hWnd,
497        pos.x,pos.y,
498        size.cx,size.cy,0);
499
500    //チラツキを抑えながら、補完リストを表示する
501    ShowWindow(ComplementWndInfo.hWnd,SW_SHOWNOACTIVATE);
502
503    ComplementWndInfo.iPos=iPos;
504}
505
506
507
508////////////////////////////////
509// コード補完ウィンドウ
510////////////////////////////////
511
512void DrawComplementListView(HWND hListView,HDC hdc){
513    //コード補完リストビューの独自描画
514    int i;
515    RECT rc;
516    char temporary[1024];
517
518    RECT rcClient;
519    GetClientRect(hListView,&rcClient);
520
521    HFONT hFont;
522    hFont=(HFONT)SendMessage(hListView,WM_GETFONT,0,0);
523
524    HFONT hOldFont;
525    hOldFont=(HFONT)SelectObject(hdc,hFont);
526
527    SetBkMode(hdc,OPAQUE);
528
529    for(i=0;i<ListView_GetItemCount(hListView);i++){
530        LVITEM lvItem;
531        lvItem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
532        lvItem.iItem=i;
533        lvItem.iSubItem=0;
534        lvItem.pszText=temporary;
535        lvItem.cchTextMax=1024;
536        lvItem.stateMask=LVIS_SELECTED;
537        ListView_GetItem(hListView,&lvItem);
538
539        COLORREF colorBack;
540        if(lvItem.state&LVIS_SELECTED){
541            //選択中
542            colorBack=RGB(50,80,255);
543        }
544        else{
545            //選択されていない
546            colorBack=ListView_GetBkColor(hListView);
547        }
548
549
550        /////////////////////
551        // アイコンを描画
552        /////////////////////
553        ListView_GetItemRect(hListView,i,&rc,LVIR_ICON);
554
555        HIMAGELIST hImageList;
556        hImageList=ListView_GetImageList(hListView,LVSIL_SMALL);
557
558        ImageList_Draw(hImageList,lvItem.iImage,hdc,rc.left,rc.top,ILD_NORMAL);
559
560
561        /////////////////////
562        // 文字列を描画
563        /////////////////////
564
565        //背景色で下地を準備
566        ListView_GetItemRect(hListView,i,&rc,LVIR_ICON);
567        rc.left=rc.right;
568        rc.right=rcClient.right;
569        if(lvItem.state&LVIS_SELECTED){
570            //選択されている
571
572            //グラデーションビットマップを生成
573            SIZE size;
574            GetSize(&size,&rc);
575            HBITMAP hBackBmp;
576            hBackBmp=CreateGradationBitmap(&size,RGB(130,150,210),RGB(50,80,190));
577
578            HDC memdc;
579            memdc=CreateCompatibleDC(hdc);
580            SelectObject(memdc,hBackBmp);
581
582            BitBlt(hdc,rc.left,rc.top,size.cx,size.cy,memdc,0,0,SRCCOPY);
583
584            DeleteDC(memdc);
585            DeleteObject(hBackBmp);
586
587            SetTextColor(hdc,RGB(255,255,255));
588            SetBkMode(hdc,TRANSPARENT);
589        }
590        else{
591            //選択されていない
592            HBRUSH hBrush;
593            hBrush=CreateSolidBrush(colorBack);
594            FillRect(hdc,&rc,hBrush);
595            DeleteObject(hBrush);
596
597            SetTextColor(hdc,RGB(0,0,0));
598            SetBkMode(hdc,OPAQUE);
599            SetBkColor(hdc,colorBack);
600        }
601
602        ListView_GetItemRect(hListView,i,&rc,LVIR_LABEL);
603        rc.left+=5;
604        DrawText(hdc,lvItem.pszText,lstrlen(lvItem.pszText),&rc,DT_LEFT|DT_SINGLELINE|DT_VCENTER);
605    }
606
607    SelectObject(hdc,hOldFont);
608}
609
610WNDPROC OldComplementListViewProc;
611
612LRESULT CALLBACK ComplementListViewProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
613    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
614    int i,WndNum;
615    char temporary[VN_SIZE],temp2[VN_SIZE];
616
617    switch(message){
618        case WM_SETFOCUS:
619        case WM_RBUTTONDOWN:
620        case WM_RBUTTONDBLCLK:
621            //フォーカスをエディタに戻す
622            WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
623            SetFocus(MdiInfo[WndNum]->pMdiTextEdit->hEdit);
624            return 0;
625        case WM_KEYDOWN:
626            if(LOWORD(wParam)==VK_RETURN) goto DblClk;
627            else if(LOWORD(wParam)==VK_ESCAPE){
628                DestroyWindow(ComplementWndInfo.hWnd);
629                ComplementWndInfo.hWnd=0;
630            }
631            break;
632        case WM_LBUTTONDOWN:
633            //フォーカスをエディタに戻す
634            WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
635            SetFocus(MdiInfo[WndNum]->pMdiTextEdit->hEdit);
636
637            LVHITTESTINFO lvHitTest;
638            lvHitTest.pt.x=0;
639            lvHitTest.pt.y=HIWORD(lParam);
640            ListView_HitTest(hwnd,&lvHitTest);
641
642            //アイテムを選択
643            ListView_SetItemState(hwnd,lvHitTest.iItem,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
644            return 0;
645        case WM_LBUTTONDBLCLK:
646DblClk:
647
648            //選択されたアイテムを取得
649            for(i=0;i<ComplementWndInfo.MemberNum;i++){
650                if(ListView_GetItemState(ComplementWndInfo.hList,i,LVIS_SELECTED)) break;
651            }
652            if(i!=ComplementWndInfo.MemberNum){
653                ListView_GetItemText(hwnd,i,0,temporary,VN_SIZE);
654
655                WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
656
657                if(ComplementWndInfo.pMemberInfo[0].dwAccess==ACCESS_PAIRCOMMAND){
658                    //ペアステートメント補完
659
660                    for(i=ComplementWndInfo.iPos-1;;i--){
661                        if(MdiInfo[WndNum]->pMdiTextEdit->buffer[i]!='\t'){
662                            i++;
663                            break;
664                        }
665                    }
666
667                    GetCaretPosFromBufferIndex(MdiInfo[WndNum]->pMdiTextEdit->buffer,
668                        i,
669                        &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
670
671                    //インデント
672                    lstrcpy(temp2,ComplementWndInfo.szIndent);
673                    if(IsNeedNewIndentCommand(temporary)) lstrcat(temp2,"\t");
674
675                    lstrcat(temp2,temporary);
676
677                    //リプレース前に補完機能を破棄する
678                    DestroyWindow(ComplementWndInfo.hWnd);
679                    ComplementWndInfo.hWnd=0;
680
681                    TextEdit_ReplaceUpdateUndoData(WndNum,temp2,0,1);
682                }
683                else{
684                    //クラスメンバ補完
685
686                    GetCaretPosFromBufferIndex(MdiInfo[WndNum]->pMdiTextEdit->buffer,
687                        ComplementWndInfo.iPos,
688                        &MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos);
689
690                    //リプレース前に補完機能を破棄する
691                    DestroyWindow(ComplementWndInfo.hWnd);
692                    ComplementWndInfo.hWnd=0;
693
694                    TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
695                }
696            }
697
698            return 0;
699
700        case WM_PAINT:
701            HDC hdc;
702            PAINTSTRUCT ps;
703            hdc=BeginPaint(hwnd,&ps);
704            DrawComplementListView(hwnd,hdc);
705            EndPaint(hwnd,&ps);
706            return 0;
707    }
708    return CallWindowProc(OldComplementListViewProc,hwnd,message,wParam,lParam);
709}
710
711LRESULT CALLBACK ComplementWindow(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
712    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
713    static HWND hListView;
714    static HIMAGELIST hImageList;
715
716    switch(message){
717        case WM_CREATE:
718
719            ////////////////////////
720            // リストビューを作成
721            ////////////////////////
722
723            hListView=CreateWindow(WC_LISTVIEW,0,
724                WS_CHILD|WS_VISIBLE|WS_VSCROLL|     LVS_SMALLICON|LVS_SINGLESEL|LVS_SORTASCENDING|LVS_SHOWSELALWAYS,
725                0,0,0,0,
726                hwnd,NULL,hInst,0);
727            OldComplementListViewProc=(WNDPROC)GetWindowLongPtr(hListView,GWLP_WNDPROC);
728            SetWindowLongPtr(hListView,GWLP_WNDPROC,(long)ComplementListViewProc);
729
730            //フォントをセット
731            extern METHODCHECKINFO MethodCheckInfo;
732            SendMessage(hListView,WM_SETFONT,(long)MethodCheckInfo.hFont,0);
733
734            ComplementWndInfo.hList=hListView;
735
736            //背景色をセット
737            COLORREF rgb;
738            if(ComplementWndInfo.pMemberInfo[0].dwAccess==ACCESS_PAIRCOMMAND){
739                //ペアステートメント補完
740                rgb=RGB(245,245,255);
741            }
742            else{
743                //クラスメンバ補完
744                rgb=RGB(255,245,240);
745            }
746            ListView_SetBkColor(hListView,rgb);
747            ListView_SetTextBkColor(hListView,rgb);
748
749
750            ////////////////////////
751            // イメージリストを作成
752            ////////////////////////
753
754            hImageList=ImageList_Create(16, 16, ILC_COLOR24, 7, 0);
755            ListView_SetImageList(hListView, hImageList, LVSIL_SMALL);
756            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_MEMBER_PRIVATE_VARIABLE));
757            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_MEMBER_PUBLIC_VARIABLE));
758            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_MEMBER_PRIVATE_FUNCTION));
759            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_MEMBER_PUBLIC_FUNCTION));
760            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_PAIRSTATEMENT));
761            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_HTML_GENERAL_PARAMETER));
762            ImageList_AddIcon(hImageList, ActiveBasic::Resource::LoadIconAlt(hResInst, IDI_HTML_PARAMETER));
763
764            return 0;
765        case WM_SIZE:
766            MoveWindow(hListView,0,0,LOWORD(lParam),HIWORD(lParam),0);
767            return 0;
768        case WM_DESTROY:
769            DeleteComplementInfo();
770            ImageList_Destroy(hImageList);
771            return 0;
772
773        case WM_NOTIFY:
774            NMLISTVIEW *nmListView;
775            nmListView=(NMLISTVIEW *)lParam;
776            if(nmListView->hdr.hwndFrom==hListView){
777                if(nmListView->hdr.code==LVN_ITEMCHANGED){
778                    InvalidateRect(hListView,NULL,0);
779                    return 1;
780                }
781            }
782            break;
783    }
784    return DefWindowProc(hwnd,message,wParam,lParam);
785}
Note: See TracBrowser for help on using the repository browser.