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

Last change on this file since 623 was 475, checked in by dai_9181, 16 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.