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

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

FileManager周りをリファクタリング

File size: 20.6 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, 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.