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

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

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

File size: 20.7 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 MDIINFO MdiInfo[MAX_WNDNUM];
391    extern int font_width,font_height;
392    POINT pos;
393    pos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
394    GetScrollBaseCaretPos(WndNum,(int *)&pos.x,(int *)&pos.y);
395
396    pos.x=(pos.x-1)*font_width    +iControlTabSpace;
397    pos.y=(pos.y+1)*font_height;
398
399    ClientToScreen(MdiInfo[WndNum].pMdiTextEdit->hEdit,&pos);
400
401    extern HINSTANCE hInst;
402    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
403    ComplementWndInfo.hWnd=CreateWindowEx(WS_EX_DLGMODALFRAME,
404        "ComplementWindow",NULL,
405        WS_POPUP|WS_CLIPCHILDREN,
406        pos.x,pos.y,100,100,
407        hOwner,NULL,hInst,0);
408
409    ///////////////////////////
410    // リストビューの初期化
411    ///////////////////////////
412    extern METHODCHECKINFO MethodCheckInfo;
413    int height,max_width,listitem_height;
414    max_width=0;
415
416    // リストアイテムを追加
417    LV_ITEM lvItem;
418    lvItem.mask = LVIF_TEXT|LVIF_IMAGE;
419    for(i=0;i<ComplementWndInfo.MemberNum;i++){
420        lvItem.pszText=ComplementWndInfo.pMemberInfo[i].pName;
421        lvItem.iItem=0;
422        lvItem.iSubItem=0;
423
424        if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_PAIRCOMMAND){
425            //ペアステートメント補完リストアイテム
426            lvItem.iImage=4;
427        }
428        else if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_HTML_GENERAL_PARAM){
429            //HTMLタグのパラメータ
430            lvItem.iImage=5;
431        }
432        else if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_HTML_PARAM){
433            //HTMLタグのパラメータ
434            lvItem.iImage=6;
435        }
436        else if(ComplementWndInfo.pMemberInfo[i].dwProc==0){
437            //メンバ変数
438            if(ComplementWndInfo.pMemberInfo[i].dwAccess!=ACCESS_PUBLIC)
439                lvItem.iImage=0;
440            else
441                lvItem.iImage=1;
442        }
443        else{
444            //メンバ関数
445            if(ComplementWndInfo.pMemberInfo[i].dwAccess!=ACCESS_PUBLIC)
446                lvItem.iImage=2;
447            else
448                lvItem.iImage=3;
449        }
450        ListView_InsertItem(ComplementWndInfo.hList,&lvItem);
451
452        i2=ListView_GetStringWidth(ComplementWndInfo.hList,
453            ComplementWndInfo.pMemberInfo[i].pName);
454
455        if(max_width<i2) max_width=i2;
456    }
457
458    RECT rc;
459    ListView_GetItemRect(ComplementWndInfo.hList,0,&rc,LVIR_BOUNDS);
460    listitem_height=rc.bottom-rc.top;
461    height=listitem_height*ComplementWndInfo.MemberNum;
462
463    //ウィンドウサイズとクライアント領域サイズの差を計算
464    RECT rc_Window,rc_Client;
465    SIZE size;
466    int dx,dy;
467    GetWindowRect(ComplementWndInfo.hWnd, &rc_Window);
468    GetClientRect(ComplementWndInfo.hWnd, &rc_Client);
469    dx = (rc_Window.right - rc_Window.left) - (rc_Client.right - rc_Client.left);
470    dy = (rc_Window.bottom - rc_Window.top) - (rc_Client.bottom - rc_Client.top);
471
472#define MAX_COMPLEMENT_LISTNUM 15
473    size.cx=max_width+dx+30;    //※30はアイコンの幅を含む余白
474    size.cy=height+dy;
475    if(size.cy>listitem_height*MAX_COMPLEMENT_LISTNUM+dy){
476        size.cy=listitem_height*MAX_COMPLEMENT_LISTNUM+dy;
477
478        //垂直スクロールバーの幅を考慮する
479        size.cx+=GetSystemMetrics(SM_CXVSCROLL);
480    }
481    else{
482        //スクロールバーを使用しないようにする
483        i=GetWindowLongPtr(ComplementWndInfo.hList,GWL_STYLE);
484        i|=LVS_NOSCROLL;
485        i&=~(WS_VSCROLL|WS_HSCROLL);
486        SetWindowLongPtr(ComplementWndInfo.hList,GWL_STYLE,i);
487    }
488
489    if(pos.x+size.cx>ScreenX){
490        pos.x=ScreenX-size.cx;
491    }
492    if(pos.y+size.cy>ScreenY-30){
493        pos.y-=size.cy+font_height;
494    }
495
496    //サイズ変更
497    MoveWindow(ComplementWndInfo.hWnd,
498        pos.x,pos.y,
499        size.cx,size.cy,0);
500
501    //チラツキを抑えながら、補完リストを表示する
502    ShowWindow(ComplementWndInfo.hWnd,SW_SHOWNOACTIVATE);
503
504    ComplementWndInfo.iPos=iPos;
505}
506
507
508
509////////////////////////////////
510// コード補完ウィンドウ
511////////////////////////////////
512
513void DrawComplementListView(HWND hListView,HDC hdc){
514    //コード補完リストビューの独自描画
515    int i;
516    RECT rc;
517    char temporary[1024];
518
519    RECT rcClient;
520    GetClientRect(hListView,&rcClient);
521
522    HFONT hFont;
523    hFont=(HFONT)SendMessage(hListView,WM_GETFONT,0,0);
524
525    HFONT hOldFont;
526    hOldFont=(HFONT)SelectObject(hdc,hFont);
527
528    SetBkMode(hdc,OPAQUE);
529
530    for(i=0;i<ListView_GetItemCount(hListView);i++){
531        LVITEM lvItem;
532        lvItem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
533        lvItem.iItem=i;
534        lvItem.iSubItem=0;
535        lvItem.pszText=temporary;
536        lvItem.cchTextMax=1024;
537        lvItem.stateMask=LVIS_SELECTED;
538        ListView_GetItem(hListView,&lvItem);
539
540        COLORREF colorBack;
541        if(lvItem.state&LVIS_SELECTED){
542            //選択中
543            colorBack=RGB(50,80,255);
544        }
545        else{
546            //選択されていない
547            colorBack=ListView_GetBkColor(hListView);
548        }
549
550
551        /////////////////////
552        // アイコンを描画
553        /////////////////////
554        ListView_GetItemRect(hListView,i,&rc,LVIR_ICON);
555
556        HIMAGELIST hImageList;
557        hImageList=ListView_GetImageList(hListView,LVSIL_SMALL);
558
559        ImageList_Draw(hImageList,lvItem.iImage,hdc,rc.left,rc.top,ILD_NORMAL);
560
561
562        /////////////////////
563        // 文字列を描画
564        /////////////////////
565
566        //背景色で下地を準備
567        ListView_GetItemRect(hListView,i,&rc,LVIR_ICON);
568        rc.left=rc.right;
569        rc.right=rcClient.right;
570        if(lvItem.state&LVIS_SELECTED){
571            //選択されている
572
573            //グラデーションビットマップを生成
574            SIZE size;
575            GetSize(&size,&rc);
576            HBITMAP hBackBmp;
577            hBackBmp=CreateGradationBitmap(&size,RGB(130,150,210),RGB(50,80,190));
578
579            HDC memdc;
580            memdc=CreateCompatibleDC(hdc);
581            SelectObject(memdc,hBackBmp);
582
583            BitBlt(hdc,rc.left,rc.top,size.cx,size.cy,memdc,0,0,SRCCOPY);
584
585            DeleteDC(memdc);
586            DeleteObject(hBackBmp);
587
588            SetTextColor(hdc,RGB(255,255,255));
589            SetBkMode(hdc,TRANSPARENT);
590        }
591        else{
592            //選択されていない
593            HBRUSH hBrush;
594            hBrush=CreateSolidBrush(colorBack);
595            FillRect(hdc,&rc,hBrush);
596            DeleteObject(hBrush);
597
598            SetTextColor(hdc,RGB(0,0,0));
599            SetBkMode(hdc,OPAQUE);
600            SetBkColor(hdc,colorBack);
601        }
602
603        ListView_GetItemRect(hListView,i,&rc,LVIR_LABEL);
604        rc.left+=5;
605        DrawText(hdc,lvItem.pszText,lstrlen(lvItem.pszText),&rc,DT_LEFT|DT_SINGLELINE|DT_VCENTER);
606    }
607
608    SelectObject(hdc,hOldFont);
609}
610
611WNDPROC OldComplementListViewProc;
612
613LRESULT CALLBACK ComplementListViewProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
614    extern MDIINFO MdiInfo[MAX_WNDNUM];
615    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
616    int i,WndNum;
617    char temporary[VN_SIZE],temp2[VN_SIZE];
618
619    switch(message){
620        case WM_SETFOCUS:
621        case WM_RBUTTONDOWN:
622        case WM_RBUTTONDBLCLK:
623            //フォーカスをエディタに戻す
624            WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
625            SetFocus(MdiInfo[WndNum].pMdiTextEdit->hEdit);
626            return 0;
627        case WM_KEYDOWN:
628            if(LOWORD(wParam)==VK_RETURN) goto DblClk;
629            else if(LOWORD(wParam)==VK_ESCAPE){
630                DestroyWindow(ComplementWndInfo.hWnd);
631                ComplementWndInfo.hWnd=0;
632            }
633            break;
634        case WM_LBUTTONDOWN:
635            //フォーカスをエディタに戻す
636            WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
637            SetFocus(MdiInfo[WndNum].pMdiTextEdit->hEdit);
638
639            LVHITTESTINFO lvHitTest;
640            lvHitTest.pt.x=0;
641            lvHitTest.pt.y=HIWORD(lParam);
642            ListView_HitTest(hwnd,&lvHitTest);
643
644            //アイテムを選択
645            ListView_SetItemState(hwnd,lvHitTest.iItem,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
646            return 0;
647        case WM_LBUTTONDBLCLK:
648DblClk:
649
650            //選択されたアイテムを取得
651            for(i=0;i<ComplementWndInfo.MemberNum;i++){
652                if(ListView_GetItemState(ComplementWndInfo.hList,i,LVIS_SELECTED)) break;
653            }
654            if(i!=ComplementWndInfo.MemberNum){
655                ListView_GetItemText(hwnd,i,0,temporary,VN_SIZE);
656
657                WndNum=GetWndNum(GetWindow(hClient,GW_CHILD));
658
659                if(ComplementWndInfo.pMemberInfo[0].dwAccess==ACCESS_PAIRCOMMAND){
660                    //ペアステートメント補完
661
662                    for(i=ComplementWndInfo.iPos-1;;i--){
663                        if(MdiInfo[WndNum].pMdiTextEdit->buffer[i]!='\t'){
664                            i++;
665                            break;
666                        }
667                    }
668
669                    GetCaretPosFromBufferIndex(MdiInfo[WndNum].pMdiTextEdit->buffer,
670                        i,
671                        &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
672
673                    //インデント
674                    lstrcpy(temp2,ComplementWndInfo.szIndent);
675                    if(IsNeedNewIndentCommand(temporary)) lstrcat(temp2,"\t");
676
677                    lstrcat(temp2,temporary);
678
679                    //リプレース前に補完機能を破棄する
680                    DestroyWindow(ComplementWndInfo.hWnd);
681                    ComplementWndInfo.hWnd=0;
682
683                    TextEdit_ReplaceUpdateUndoData(WndNum,temp2,0,1);
684                }
685                else{
686                    //クラスメンバ補完
687
688                    GetCaretPosFromBufferIndex(MdiInfo[WndNum].pMdiTextEdit->buffer,
689                        ComplementWndInfo.iPos,
690                        &MdiInfo[WndNum].pMdiTextEdit->StartCaretPos);
691
692                    //リプレース前に補完機能を破棄する
693                    DestroyWindow(ComplementWndInfo.hWnd);
694                    ComplementWndInfo.hWnd=0;
695
696                    TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
697                }
698            }
699
700            return 0;
701
702        case WM_PAINT:
703            HDC hdc;
704            PAINTSTRUCT ps;
705            hdc=BeginPaint(hwnd,&ps);
706            DrawComplementListView(hwnd,hdc);
707            EndPaint(hwnd,&ps);
708            return 0;
709    }
710    return CallWindowProc(OldComplementListViewProc,hwnd,message,wParam,lParam);
711}
712
713LRESULT CALLBACK ComplementWindow(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
714    extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
715    static HWND hListView;
716    static HIMAGELIST hImageList;
717
718    switch(message){
719        case WM_CREATE:
720
721            ////////////////////////
722            // リストビューを作成
723            ////////////////////////
724
725            hListView=CreateWindow(WC_LISTVIEW,0,
726                WS_CHILD|WS_VISIBLE|WS_VSCROLL|     LVS_SMALLICON|LVS_SINGLESEL|LVS_SORTASCENDING|LVS_SHOWSELALWAYS,
727                0,0,0,0,
728                hwnd,NULL,hInst,0);
729            OldComplementListViewProc=(WNDPROC)GetWindowLongPtr(hListView,GWLP_WNDPROC);
730            SetWindowLongPtr(hListView,GWLP_WNDPROC,(long)ComplementListViewProc);
731
732            //フォントをセット
733            extern METHODCHECKINFO MethodCheckInfo;
734            SendMessage(hListView,WM_SETFONT,(long)MethodCheckInfo.hFont,0);
735
736            ComplementWndInfo.hList=hListView;
737
738            //背景色をセット
739            COLORREF rgb;
740            if(ComplementWndInfo.pMemberInfo[0].dwAccess==ACCESS_PAIRCOMMAND){
741                //ペアステートメント補完
742                rgb=RGB(245,245,255);
743            }
744            else{
745                //クラスメンバ補完
746                rgb=RGB(255,245,240);
747            }
748            ListView_SetBkColor(hListView,rgb);
749            ListView_SetTextBkColor(hListView,rgb);
750
751
752            ////////////////////////
753            // イメージリストを作成
754            ////////////////////////
755
756            hImageList=ImageList_Create(16, 16, ILC_COLOR24, 7, 0);
757            ListView_SetImageList(hListView, hImageList, LVSIL_SMALL);
758            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PRIVATE_VARIABLE)));
759            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PUBLIC_VARIABLE)));
760            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PRIVATE_FUNCTION)));
761            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PUBLIC_FUNCTION)));
762            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_PAIRSTATEMENT)));
763            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_HTML_GENERAL_PARAMETER)));
764            ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_HTML_PARAMETER)));
765
766            return 0;
767        case WM_SIZE:
768            MoveWindow(hListView,0,0,LOWORD(lParam),HIWORD(lParam),0);
769            return 0;
770        case WM_DESTROY:
771            DeleteComplementInfo();
772            ImageList_Destroy(hImageList);
773            return 0;
774
775        case WM_NOTIFY:
776            NMLISTVIEW *nmListView;
777            nmListView=(NMLISTVIEW *)lParam;
778            if(nmListView->hdr.hwndFrom==hListView){
779                if(nmListView->hdr.code==LVN_ITEMCHANGED){
780                    InvalidateRect(hListView,NULL,0);
781                    return 1;
782                }
783            }
784            break;
785    }
786    return DefWindowProc(hwnd,message,wParam,lParam);
787}
Note: See TracBrowser for help on using the repository browser.