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

Last change on this file since 447 was 302, checked in by dai_9181, 17 years ago
File size: 20.6 KB
Line 
1#include "common.h"
2
3///////////////////////////
4// コード補完機能
5///////////////////////////
6
7BOOL GetComplementClass(char *pBuf,char *ClassName,char *nest,BOOL bInherits){
8 extern HANDLE hHeap;
9 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
10 extern char *pHeaderBuf;
11 extern char *pUserSource;
12 int i,i2;
13 char temporary[8192];
14 DWORD dwClassType;
15 BOOL bRet;
16
17
18 /////////////////////////////////////////
19 // ソースコードからクラス定義位置を取得
20 /////////////////////////////////////////
21 i=GetClassPos(pBuf,ClassName,&dwClassType);
22 if(pBuf[i]=='\0') return 0;
23
24
25 if(nest[0]){
26 ////////////////////
27 // 入れ子構造の場合
28 ////////////////////
29
30 //クラス、配列の構成要素を解析する
31 char VarName[VN_SIZE]; //変数名
32 char array[VN_SIZE]; //第1次配列
33 char lpPtrOffset[VN_SIZE]; //第2次配列
34 char NestMember[VN_SIZE]; //入れ子メンバ
35 int RefType; //"."参照のときは0、"->"参照のときは1
36 lstrcpy(VarName,nest);
37 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)) return 0;
38
39 //メンバ変数の型であるクラスの名前を取得
40 char ClassName[VN_SIZE];
41 BOOL bArray;
42 if(!GetClassNameFromClassMember(pBuf,i,VarName,ClassName,&bArray)) return 0;
43
44 //TypeDef宣言を考慮してオリジナルなクラス名を取得
45 GetOriginalClassName(ClassName);
46
47 if(!CheckReferType(ClassName,bArray,array,RefType)) return 0;
48
49 //ユーザーのソースコードをサーチ
50 bRet=GetComplementClass(pUserSource,ClassName,NestMember,0);
51 if(!bRet){
52 //失敗したときはbasic.sbpをサーチ
53 bRet=GetComplementClass(pHeaderBuf,ClassName,NestMember,0);
54 }
55 return bRet;
56 }
57
58
59 ////////////////////////
60 // メンバ情報を取得
61 ////////////////////////
62 DWORD dwAccess;
63 DWORD dwProc;
64
65 //アクセス制限の初期値をセット
66 if(dwClassType==ESC_CLASS) dwAccess=ACCESS_PRIVATE;
67 else dwAccess=ACCESS_PUBLIC;
68
69 if(memicmp(pBuf+i,"Inherits",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')){
70 i+=9;
71 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
72
73 //継承を行う場合
74 for(i2=0;;i++,i2++){
75 if(!IsVariableChar(pBuf[i])){
76 temporary[i2]=0;
77 break;
78 }
79 temporary[i2]=pBuf[i];
80 }
81
82 //ユーザーのソースコードをサーチ
83 bRet=GetComplementClass(pUserSource,temporary,"",1);
84 if(!bRet){
85 //失敗したときはbasic.sbpをサーチ
86 bRet=GetComplementClass(pHeaderBuf,temporary,"",1);
87 }
88
89 for(;;i++){
90 if(pBuf[i]=='\0') break;
91 i2=IsCommandDelimitation(pBuf,i);
92 if(i2){
93 i+=i2;
94 break;
95 }
96 }
97 JumpBlank(pBuf,&i);
98 }
99
100 //メンバ変数、関数を取得
101 while(1){
102 if(pBuf[i]=='\0') break;
103 if(memicmp(pBuf+i,"End",3)==0){
104 /* End Class
105 End Type
106 の検出 */
107 i2=i+3;
108 while(pBuf[i2]==' '||pBuf[i2]=='\t') i2++;
109
110 if(memicmp(pBuf+i2,"Class",5)==0&&(!IsVariableChar(pBuf[i2+5]))||
111 memicmp(pBuf+i2,"Interface",9)==0&&(!IsVariableChar(pBuf[i2+9]))||
112 memicmp(pBuf+i2,"Type",4)==0&&(!IsVariableChar(pBuf[i2+4]))) break;
113 }
114
115 if(memicmp(pBuf+i,"Abstract",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
116 memicmp(pBuf+i,"Virtual",7)==0&&(pBuf[i+7]==' '||pBuf[i+7]=='\t')||
117 memicmp(pBuf+i,"Override",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
118 memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')||
119 memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')){
120 //メンバ関数のとき
121 if(pBuf[i]=='a'||pBuf[i]=='A'){
122 i+=9;
123 dwProc=ESC_ABSTRACT;
124
125 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
126 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
127 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
128 }
129 else if(pBuf[i]=='v'||pBuf[i]=='V'){
130 i+=8;
131 dwProc=ESC_VIRTUAL;
132
133 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
134 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
135 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
136 }
137 else if(pBuf[i]=='o'||pBuf[i]=='O'){
138 i+=9;
139 dwProc=ESC_OVERRIDE;
140
141 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
142 if(memicmp(pBuf+i,"Function",8)==0&&(pBuf[i+8]==' '||pBuf[i+8]=='\t')) i+=9;
143 else if(memicmp(pBuf+i,"Sub",3)==0&&(pBuf[i+3]==' '||pBuf[i+3]=='\t')) i+=4;
144 }
145 else if(pBuf[i]=='f'||pBuf[i]=='F'){
146 i+=9;
147 dwProc=ESC_FUNCTION;
148 }
149 else if(pBuf[i]=='s'||pBuf[i]=='S'){
150 i+=4;
151 dwProc=ESC_SUB;
152 }
153
154 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
155 }
156 else{
157 //メンバ変数のとき
158 dwProc=0;
159 }
160
161 //変数名または関数名を取得
162 if(pBuf[i]=='~'){
163 temporary[0]='~';
164 i2=1;
165 i++;
166 }
167 else i2=0;
168 for(;;i++,i2++){
169 if(!IsVariableChar(pBuf[i])){
170 temporary[i2]=0;
171 break;
172 }
173 temporary[i2]=pBuf[i];
174 }
175
176 if(bInherits){
177 //継承元の場合はコンストラクタ、デストラクタを除去
178 if(temporary[0]=='~') goto next;
179 if(lstrcmp(temporary,ClassName)==0) goto next;
180 }
181
182 //次の行をサーチ
183 for(;;i++){
184 if(pBuf[i]=='\0') break;
185 if(pBuf[i]=='\''||(pBuf[i]=='/'&&pBuf[i+1]=='*')){
186 //コメント中
187 JumpBlank(pBuf,&i);
188 break;
189 }
190 i2=IsCommandDelimitation(pBuf,i);
191 if(i2){
192 i+=i2;
193 break;
194 }
195 }
196 JumpBlank(pBuf,&i);
197
198 //重複チェック(オーバーライド関数の除去)
199 for(i2=0;i2<ComplementWndInfo.MemberNum;i2++){
200 if(lstrcmp(ComplementWndInfo.pMemberInfo[i2].pName,temporary)==0) goto next;
201 }
202
203 //アクセスを変更
204 if(lstrcmpi(temporary,"Private")==0){
205 dwAccess=ACCESS_PRIVATE;
206 continue;
207 }
208 if(lstrcmpi(temporary,"Public")==0){
209 dwAccess=ACCESS_PUBLIC;
210 continue;
211 }
212 if(lstrcmpi(temporary,"Protected")==0){
213 dwAccess=ACCESS_PROTECTED;
214 continue;
215 }
216
217 ComplementWndInfo.pMemberInfo=
218 (MEMBERINFO *)HeapReAlloc(hHeap,
219 0,
220 ComplementWndInfo.pMemberInfo,
221 (ComplementWndInfo.MemberNum+1)*sizeof(MEMBERINFO));
222
223 //メンバ名
224 ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].pName=
225 (char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
226 lstrcpy(ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].pName,
227 temporary);
228
229 //メンバの種類(変数、Virtual、Sub、Function)
230 ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].dwProc=dwProc;
231
232 //アクセシビリティ
233 ComplementWndInfo.pMemberInfo[ComplementWndInfo.MemberNum].dwAccess=dwAccess;
234
235 ComplementWndInfo.MemberNum++;
236next:
237 if(dwProc){
238 //Abstract定義以外はEnd Sub、End Functionをサーチする
239 if(dwProc==ESC_ABSTRACT) continue;
240 if(dwClassType==ESC_INTERFACE) continue;
241
242 while(1){
243 if(pBuf[i]=='\0'){
244 i2=0;
245 break;
246 }
247
248 if(memicmp(pBuf+i,"End",3)==0){
249 /* End Sub
250 End Function
251 の検出 */
252 i+=3;
253 while(pBuf[i]==' '||pBuf[i]=='\t') i++;
254
255 if(memicmp(pBuf+i,"Sub",3)==0&&(!IsVariableChar(pBuf[i+3]))||
256 memicmp(pBuf+i,"Function",8)==0&&(!IsVariableChar(pBuf[i+8]))){
257 i2=1;
258 break;
259 }
260
261 if(memicmp(pBuf+i,"Class",5)==0&&(!IsVariableChar(pBuf[i+5]))||
262 memicmp(pBuf+i,"Interface",9)==0&&(!IsVariableChar(pBuf[i+9]))||
263 memicmp(pBuf+i,"Type",4)==0&&(!IsVariableChar(pBuf[i+4]))){
264 i2=0;
265 break;
266 }
267 }
268
269 //次の行をサーチ
270 for(;;i++){
271 if(pBuf[i]=='\0') break;
272 i2=IsCommandDelimitation(pBuf,i);
273 if(i2){
274 i+=i2;
275 break;
276 }
277 }
278 JumpBlank(pBuf,&i);
279 }
280
281 if(i2==0){
282 //コード解析が不正に終了
283 return 1;
284 }
285
286 //次の行をサーチ
287 for(;;i++){
288 if(pBuf[i]=='\0') break;
289 i2=IsCommandDelimitation(pBuf,i);
290 if(i2){
291 i+=i2;
292 break;
293 }
294 }
295 JumpBlank(pBuf,&i);
296 }
297 }
298
299 return 1;
300}
301
302void DeleteComplementInfo(void){
303 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
304 int i;
305
306 for(i=0;i<ComplementWndInfo.MemberNum;i++)
307 HeapDefaultFree(ComplementWndInfo.pMemberInfo[i].pName);
308
309 HeapDefaultFree(ComplementWndInfo.pMemberInfo);
310}
311BOOL GetComplementInfo(char *variable,char *pEditBuf,int iPos){
312 extern HANDLE hHeap;
313
314 //ユーザーが作成したソースコードを取得
315 extern char *pUserSource;
316 pUserSource=GetUserSourceCode();
317
318 //クラス、配列の構成要素を解析する
319 char VarName[VN_SIZE]; //変数名
320 char array[VN_SIZE]; //第1次配列
321 char lpPtrOffset[VN_SIZE]; //第2次配列
322 char NestMember[VN_SIZE]; //入れ子メンバ
323 int RefType; //"."参照のときは0、"->"参照のときは1
324 lstrcpy(VarName,variable);
325 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember,&RefType)){
326 HeapDefaultFree(pUserSource);
327 pUserSource=0;
328 return 0;
329 }
330
331
332 ////////////////////////////////
333 // オブジェクトのクラス名を取得
334 ////////////////////////////////
335 char ClassName[VN_SIZE];
336 BOOL bArray;
337 if(!GetVariableClassName(pEditBuf,iPos,VarName,ClassName,&bArray)){
338 HeapDefaultFree(pUserSource);
339 pUserSource=0;
340 return 0;
341 }
342
343 //TypeDef宣言を考慮してオリジナルなクラス名を取得
344 GetOriginalClassName(ClassName);
345
346 if(!CheckReferType(ClassName,bArray,array,RefType)){
347 HeapDefaultFree(pUserSource);
348 pUserSource=0;
349 return 0;
350 }
351
352
353 ////////////////////
354 // クラス情報を取得
355 ////////////////////
356 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
357
358 ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,1);
359 ComplementWndInfo.MemberNum=0;
360
361 //ユーザーのソースコードをサーチ
362 BOOL bRet;
363 bRet=GetComplementClass(pUserSource,ClassName,NestMember,0);
364 if(!bRet){
365 //失敗したときはbasic.sbpをサーチ
366 extern char *pHeaderBuf;
367 bRet=GetComplementClass(pHeaderBuf,ClassName,NestMember,0);
368 }
369
370 HeapDefaultFree(pUserSource);
371 pUserSource=0;
372
373 if(!bRet||ComplementWndInfo.MemberNum==0){
374 //見つからなかったとき
375 DeleteComplementInfo();
376 return 0;
377 }
378
379 return 1;
380}
381void CodeComplement(int WndNum,int iPos){
382 int i,i2;
383
384 //エディタ画面左端のコントロールタブ
385 int iControlTabSpace;
386 iControlTabSpace=MdiInfo[WndNum].pMdiTextEdit->iWidth_ControlTabSpace;
387
388 extern MDIINFO MdiInfo[MAX_WNDNUM];
389 extern int font_width,font_height;
390 POINT pos;
391 pos=MdiInfo[WndNum].pMdiTextEdit->StartCaretPos;
392 GetScrollBaseCaretPos(WndNum,(int *)&pos.x,(int *)&pos.y);
393
394 pos.x=(pos.x-1)*font_width +iControlTabSpace;
395 pos.y=(pos.y+1)*font_height;
396
397 ClientToScreen(MdiInfo[WndNum].pMdiTextEdit->hEdit,&pos);
398
399 extern HINSTANCE hInst;
400 extern COMPLEMENT_WINDOW_INFO ComplementWndInfo;
401 ComplementWndInfo.hWnd=CreateWindowEx(WS_EX_DLGMODALFRAME,
402 "ComplementWindow",NULL,
403 WS_POPUP|WS_CLIPCHILDREN,
404 pos.x,pos.y,100,100,
405 hOwner,NULL,hInst,0);
406
407 ///////////////////////////
408 // リストビューの初期化
409 ///////////////////////////
410 extern METHODCHECKINFO MethodCheckInfo;
411 int height,max_width,listitem_height;
412 max_width=0;
413
414 // リストアイテムを追加
415 LV_ITEM lvItem;
416 lvItem.mask = LVIF_TEXT|LVIF_IMAGE;
417 for(i=0;i<ComplementWndInfo.MemberNum;i++){
418 lvItem.pszText=ComplementWndInfo.pMemberInfo[i].pName;
419 lvItem.iItem=0;
420 lvItem.iSubItem=0;
421
422 if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_PAIRCOMMAND){
423 //ペアステートメント補完リストアイテム
424 lvItem.iImage=4;
425 }
426 else if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_HTML_GENERAL_PARAM){
427 //HTMLタグのパラメータ
428 lvItem.iImage=5;
429 }
430 else if(ComplementWndInfo.pMemberInfo[i].dwAccess==ACCESS_HTML_PARAM){
431 //HTMLタグのパラメータ
432 lvItem.iImage=6;
433 }
434 else if(ComplementWndInfo.pMemberInfo[i].dwProc==0){
435 //メンバ変数
436 if(ComplementWndInfo.pMemberInfo[i].dwAccess!=ACCESS_PUBLIC)
437 lvItem.iImage=0;
438 else
439 lvItem.iImage=1;
440 }
441 else{
442 //メンバ関数
443 if(ComplementWndInfo.pMemberInfo[i].dwAccess!=ACCESS_PUBLIC)
444 lvItem.iImage=2;
445 else
446 lvItem.iImage=3;
447 }
448 ListView_InsertItem(ComplementWndInfo.hList,&lvItem);
449
450 i2=ListView_GetStringWidth(ComplementWndInfo.hList,
451 ComplementWndInfo.pMemberInfo[i].pName);
452
453 if(max_width<i2) max_width=i2;
454 }
455
456 RECT rc;
457 ListView_GetItemRect(ComplementWndInfo.hList,0,&rc,LVIR_BOUNDS);
458 listitem_height=rc.bottom-rc.top;
459 height=listitem_height*ComplementWndInfo.MemberNum;
460
461 //ウィンドウサイズとクライアント領域サイズの差を計算
462 RECT rc_Window,rc_Client;
463 SIZE size;
464 int dx,dy;
465 GetWindowRect(ComplementWndInfo.hWnd, &rc_Window);
466 GetClientRect(ComplementWndInfo.hWnd, &rc_Client);
467 dx = (rc_Window.right - rc_Window.left) - (rc_Client.right - rc_Client.left);
468 dy = (rc_Window.bottom - rc_Window.top) - (rc_Client.bottom - rc_Client.top);
469
470#define MAX_COMPLEMENT_LISTNUM 15
471 size.cx=max_width+dx+30; //※30はアイコンの幅を含む余白
472 size.cy=height+dy;
473 if(size.cy>listitem_height*MAX_COMPLEMENT_LISTNUM+dy){
474 size.cy=listitem_height*MAX_COMPLEMENT_LISTNUM+dy;
475
476 //垂直スクロールバーの幅を考慮する
477 size.cx+=GetSystemMetrics(SM_CXVSCROLL);
478 }
479 else{
480 //スクロールバーを使用しないようにする
481 i=GetWindowLongPtr(ComplementWndInfo.hList,GWL_STYLE);
482 i|=LVS_NOSCROLL;
483 i&=~(WS_VSCROLL|WS_HSCROLL);
484 SetWindowLongPtr(ComplementWndInfo.hList,GWL_STYLE,i);
485 }
486
487 if(pos.x+size.cx>ScreenX){
488 pos.x=ScreenX-size.cx;
489 }
490 if(pos.y+size.cy>ScreenY-30){
491 pos.y-=size.cy+font_height;
492 }
493
494 //サイズ変更
495 MoveWindow(ComplementWndInfo.hWnd,
496 pos.x,pos.y,
497 size.cx,size.cy,0);
498
499 //チラツキを抑えながら、補完リストを表示する
500 ShowWindow(ComplementWndInfo.hWnd,SW_SHOWNOACTIVATE);
501
502 ComplementWndInfo.iPos=iPos;
503}
504
505
506
507////////////////////////////////
508// コード補完ウィンドウ
509////////////////////////////////
510
511void DrawComplementListView(HWND hListView,HDC hdc){
512 //コード補完リストビューの独自描画
513 int i;
514 RECT rc;
515 char temporary[1024];
516
517 RECT rcClient;
518 GetClientRect(hListView,&rcClient);
519
520 HFONT hFont;
521 hFont=(HFONT)SendMessage(hListView,WM_GETFONT,0,0);
522
523 HFONT hOldFont;
524 hOldFont=(HFONT)SelectObject(hdc,hFont);
525
526 SetBkMode(hdc,OPAQUE);
527
528 for(i=0;i<ListView_GetItemCount(hListView);i++){
529 LVITEM lvItem;
530 lvItem.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
531 lvItem.iItem=i;
532 lvItem.iSubItem=0;
533 lvItem.pszText=temporary;
534 lvItem.cchTextMax=1024;
535 lvItem.stateMask=LVIS_SELECTED;
536 ListView_GetItem(hListView,&lvItem);
537
538 COLORREF colorBack;
539 if(lvItem.state&LVIS_SELECTED){
540 //選択中
541 colorBack=RGB(50,80,255);
542 }
543 else{
544 //選択されていない
545 colorBack=ListView_GetBkColor(hListView);
546 }
547
548
549 /////////////////////
550 // アイコンを描画
551 /////////////////////
552 ListView_GetItemRect(hListView,i,&rc,LVIR_ICON);
553
554 HIMAGELIST hImageList;
555 hImageList=ListView_GetImageList(hListView,LVSIL_SMALL);
556
557 ImageList_Draw(hImageList,lvItem.iImage,hdc,rc.left,rc.top,ILD_NORMAL);
558
559
560 /////////////////////
561 // 文字列を描画
562 /////////////////////
563
564 //背景色で下地を準備
565 ListView_GetItemRect(hListView,i,&rc,LVIR_ICON);
566 rc.left=rc.right;
567 rc.right=rcClient.right;
568 if(lvItem.state&LVIS_SELECTED){
569 //選択されている
570
571 //グラデーションビットマップを生成
572 SIZE size;
573 GetSize(&size,&rc);
574 HBITMAP hBackBmp;
575 hBackBmp=CreateGradationBitmap(&size,RGB(130,150,210),RGB(50,80,190));
576
577 HDC memdc;
578 memdc=CreateCompatibleDC(hdc);
579 SelectObject(memdc,hBackBmp);
580
581 BitBlt(hdc,rc.left,rc.top,size.cx,size.cy,memdc,0,0,SRCCOPY);
582
583 DeleteDC(memdc);
584 DeleteObject(hBackBmp);
585
586 SetTextColor(hdc,RGB(255,255,255));
587 SetBkMode(hdc,TRANSPARENT);
588 }
589 else{
590 //選択されていない
591 HBRUSH hBrush;
592 hBrush=CreateSolidBrush(colorBack);
593 FillRect(hdc,&rc,hBrush);
594 DeleteObject(hBrush);
595
596 SetTextColor(hdc,RGB(0,0,0));
597 SetBkMode(hdc,OPAQUE);
598 SetBkColor(hdc,colorBack);
599 }
600
601 ListView_GetItemRect(hListView,i,&rc,LVIR_LABEL);
602 rc.left+=5;
603 DrawText(hdc,lvItem.pszText,lstrlen(lvItem.pszText),&rc,DT_LEFT|DT_SINGLELINE|DT_VCENTER);
604 }
605
606 SelectObject(hdc,hOldFont);
607}
608
609WNDPROC OldComplementListViewProc;
610
611LRESULT CALLBACK ComplementListViewProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
612 extern MDIINFO MdiInfo[MAX_WNDNUM];
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, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PRIVATE_VARIABLE)));
757 ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PUBLIC_VARIABLE)));
758 ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PRIVATE_FUNCTION)));
759 ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_MEMBER_PUBLIC_FUNCTION)));
760 ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_PAIRSTATEMENT)));
761 ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(IDI_HTML_GENERAL_PARAMETER)));
762 ImageList_AddIcon(hImageList, LoadIcon(hResInst, MAKEINTRESOURCE(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.