source: dev/trunk/ab5.0/abdev/ProjectEditor/menu.cpp@ 455

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

・コンパイルビューへの出力を標準出力にも行うようにした。
#164への対応。コンパイルを中断すると高確率で強制終了してしまうバグを修正。
・ProjectEditorをVista用Microsoft SDKにてビルドできるようにした(WINVER定数を0x0501に指定した)。
#168への対応。エディタ上のDelegateキーワードを青色で表示するようにした。

File size: 13.5 KB
Line 
1#include "common.h"
2
3HFONT hMenuFont;
4
5
6
7CMenuItemData::CMenuItemData(int item_index,int itemID,char *str,CMenuEx *pobj_ThisMenu,CSubMenuEx *pobj_SubMenu){
8 this->item_index=item_index;
9 this->itemID=itemID;
10 if(str){
11 this->str=(char *)HeapAlloc(hHeap,0,lstrlen(str)+1);
12 lstrcpy(this->str,str);
13 }
14 else this->str=0;
15 this->pobj_ThisMenu=pobj_ThisMenu;
16 this->pobj_SubMenu=pobj_SubMenu;
17
18
19 hIcon=0;
20 hGrayIcon=0;
21}
22CMenuItemData::~CMenuItemData(){
23 //メニュー文字列
24 if(str)
25 HeapDefaultFree(str);
26
27 //サブメニュー オブジェクトを破棄
28 if(pobj_SubMenu)
29 delete pobj_SubMenu;
30
31 //アイコン
32 if(hIcon) DestroyIcon(hIcon);
33
34 //淡色アイコン
35 if(hGrayIcon) DestroyIcon(hGrayIcon);
36}
37
38
39
40CMenuEx *pobj_MainMenu;
41
42CMenuEx::CMenuEx(HMENU hmenu){
43 hMenu=hmenu;
44
45 ppobj_MenuItemData=(CMenuItemData **)HeapAlloc(hHeap,0,1);
46 iMenuItemNum=0;
47}
48CMenuEx::~CMenuEx(){
49 int i;
50
51 //itemDataを解放
52 for(i=0;i<iMenuItemNum;i++){
53 delete ppobj_MenuItemData[i];
54 }
55 HeapDefaultFree(ppobj_MenuItemData);
56
57 DestroyMenu(hMenu);
58}
59
60void CMenuEx::EnableItem(UINT uIDEnableItem,UINT uEnable){
61 //メニューアイテムの有効化/無効化
62 EnableMenuItem(hMenu,uIDEnableItem,uEnable);
63}
64void CMenuEx::CheckMenu(UINT idItem,BOOL bChecked){
65 //メニューアイテムのチェックマークON/OFF
66 MENUITEMINFO MenuItemInfo;
67 MenuItemInfo.cbSize=sizeof(MENUITEMINFO);
68 MenuItemInfo.fMask=MIIM_STATE;
69 if(bChecked) MenuItemInfo.fState=MFS_CHECKED;
70 else MenuItemInfo.fState=MFS_UNCHECKED;
71
72 SetMenuItemInfo(hMenu,idItem,0,&MenuItemInfo);
73}
74BOOL CMenuEx::IsCheck(UINT idItem){
75 MENUITEMINFO MenuItemInfo;
76 MenuItemInfo.cbSize=sizeof(MENUITEMINFO);
77 MenuItemInfo.fMask=MIIM_STATE;
78 GetMenuItemInfo(hMenu,idItem,0,&MenuItemInfo);
79 if(MenuItemInfo.fState&MFS_CHECKED) return 1;
80 return 0;
81}
82void CMenuEx::RenameMenuItem(int item_index,char *str){
83 ppobj_MenuItemData[item_index]->str=(char *)HeapReAlloc(hHeap,0,ppobj_MenuItemData[item_index]->str,lstrlen(str)+1);
84 lstrcpy(ppobj_MenuItemData[item_index]->str,str);
85}
86void CMenuEx::RenameMenuItemByID(int itemID,char *str){
87 int i;
88 for(i=0;i<iMenuItemNum;i++){
89 if(ppobj_MenuItemData[i]->itemID==itemID){
90 RenameMenuItem(i,str);
91 return;
92 }
93 }
94}
95void CMenuEx::RemoveItem(int item_index){
96 //メニューアイテムの消去
97 //※ポップアップメニューの消去には対応していない
98
99 ::RemoveMenu(hMenu,item_index,MF_BYPOSITION);
100
101 //メニューアイテム拡張データオブジェクトを破棄
102 delete ppobj_MenuItemData[item_index];
103
104
105 iMenuItemNum--;
106
107 int i;
108 for(i=item_index;i<iMenuItemNum;i++){
109 ppobj_MenuItemData[i]=ppobj_MenuItemData[i+1];
110 }
111}
112void CMenuEx::InsertItem(int item_index,int itemID,char *str){
113 //メニューアイテムの挿入
114
115 CMenuItemData *pobj_MenuItemData;
116 pobj_MenuItemData=AddMenuExItemData(item_index,itemID,str,this,0);
117
118 MENUITEMINFO mii;
119 memset(&mii,0,sizeof(MENUITEMINFO));
120 mii.cbSize=sizeof(MENUITEMINFO);
121 mii.fMask=MIIM_TYPE|MIIM_ID|MIIM_DATA;
122 mii.fType=MFT_OWNERDRAW;
123 mii.wID=itemID;
124 mii.dwTypeData=str;
125 mii.dwItemData=(ULONG_PTR)pobj_MenuItemData;
126 InsertMenuItem(hMenu,item_index,1,&mii);
127}
128
129BOOL CMenuEx::SetIcon(int itemID,HICON hIcon){
130 //アイコンをセット
131 int i;
132 for(i=0;i<iMenuItemNum;i++){
133 if(ppobj_MenuItemData[i]->itemID==itemID){
134 ppobj_MenuItemData[i]->hIcon=hIcon;
135
136
137 /////////////////////////
138 // 淡色アイコンを作成
139 /////////////////////////
140
141 ppobj_MenuItemData[i]->hGrayIcon=CreateGrayIcon(hIcon);
142 return 1;
143 }
144 if(ppobj_MenuItemData[i]->pobj_SubMenu){
145 BOOL bResult;
146 bResult=ppobj_MenuItemData[i]->pobj_SubMenu->SetIcon(itemID,hIcon);
147 if(bResult) return 1;
148 }
149 }
150 return 0;
151}
152
153CMenuItemData *CMenuEx::AddMenuExItemData(int item_index,int itemID,char *str,CMenuEx *pobj_ThisMenu,CSubMenuEx *pobj_SubMenu){
154 CMenuItemData *pobj_MenuItemData;
155 pobj_MenuItemData=new CMenuItemData(item_index,itemID,str,pobj_ThisMenu,pobj_SubMenu);
156
157
158 ppobj_MenuItemData=(CMenuItemData **)HeapReAlloc(hHeap,0,ppobj_MenuItemData,(iMenuItemNum+1)*sizeof(CMenuItemData *));
159
160 int i;
161 for(i=iMenuItemNum;i>item_index;i--){
162 ppobj_MenuItemData[i]=ppobj_MenuItemData[i-1];
163 }
164
165 ppobj_MenuItemData[item_index]=pobj_MenuItemData;
166
167 iMenuItemNum++;
168
169 return pobj_MenuItemData;
170}
171void CMenuEx::InitOwnerDraw(BOOL bParent){
172 char temporary[MAX_PATH];
173 MENUITEMINFO mii;
174 memset(&mii,0,sizeof(MENUITEMINFO));
175 mii.cbSize=sizeof(MENUITEMINFO);
176 mii.fMask=MIIM_TYPE|MIIM_ID|MIIM_SUBMENU|MIIM_DATA;
177
178 int nCount;
179 nCount=GetMenuItemCount(hMenu);
180
181 int i;
182 for(i=0;i<nCount;i++){
183 mii.dwTypeData=temporary;
184 mii.cch=MAX_PATH;
185 GetMenuItemInfo(hMenu,i,1,&mii);
186
187 char *temp2=0;
188 if(mii.fType==MFT_STRING) temp2=temporary;
189
190 int fType_Separator;
191 if(mii.fType==MFT_SEPARATOR) fType_Separator=MFT_SEPARATOR;
192 else fType_Separator=0;
193
194 CSubMenuEx *pobj_SubMenu;
195 if(mii.hSubMenu){
196 pobj_SubMenu=new CSubMenuEx(mii.hSubMenu);
197 pobj_SubMenu->InitOwnerDraw(0);
198 }
199 else pobj_SubMenu=0;
200
201 //拡張データをメモリに退避
202 CMenuItemData *pobj_MenuItemData;
203 pobj_MenuItemData=AddMenuExItemData(i,mii.wID,temp2,this,pobj_SubMenu);
204
205 mii.fType=MFT_OWNERDRAW | fType_Separator;
206 mii.dwItemData=(ULONG_PTR)pobj_MenuItemData;
207 SetMenuItemInfo(hMenu,i,1,&mii);
208 }
209}
210void CMenuEx::GetItemSize(int item_index,SIZE *pSize){
211 if(ppobj_MenuItemData[item_index]->str){
212 HDC hdc;
213 hdc = GetDC(GetDesktopWindow());
214 HFONT hOldFont;
215 hOldFont = (HFONT)SelectObject(hdc, hMenuFont);
216
217 GetTextExtentPoint32(hdc,
218 ppobj_MenuItemData[item_index]->str,
219 lstrlen(ppobj_MenuItemData[item_index]->str),
220 pSize);
221
222 SelectObject(hdc,hOldFont);
223 ReleaseDC(GetDesktopWindow(),hdc);
224 }
225 else{
226 //セパレータのとき
227 pSize->cx=50;
228 pSize->cy=10;
229 }
230}
231
232BOOL CMenuEx::OwnerDrawSubMenu(HMENU hSubMenu,HDC hdc,RECT *pRect,BOOL bSelect,int item_index){
233 int i;
234 for(i=0;i<iMenuItemNum;i++){
235 if(ppobj_MenuItemData[i]->pobj_SubMenu){
236 if(hSubMenu==ppobj_MenuItemData[i]->pobj_SubMenu->hMenu){
237 ppobj_MenuItemData[i]->pobj_SubMenu->OwnerDrawMenu(hdc,pRect,bSelect,item_index);
238 return 1;
239 }
240 else{
241 BOOL bResult;
242 bResult=ppobj_MenuItemData[i]->pobj_SubMenu->OwnerDrawSubMenu(hSubMenu,hdc,pRect,bSelect,item_index);
243 if(bResult) return 1;
244 }
245 }
246 }
247 return 0;
248}
249void CMenuEx::OwnerDrawMenu(HDC hdc,RECT *pRect,BOOL bSelect,int item_index){
250 /////////////////////////////////
251 // 親メニューのオーナー描画
252 /////////////////////////////////
253
254
255 COLORREF BackColor,TextColor;
256
257 RECT rc;
258
259 if(bSelect){
260 //選択状態にある場合
261 HPEN hPen,hOldPen;
262 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_SELECT_LINE);
263 hOldPen=(HPEN)SelectObject(hdc,hPen);
264
265 HBRUSH hBrush,hOldBrush;
266 hBrush=CreateSolidBrush(MENUCOLOR_SELECT_BACK);
267 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
268
269 pRect->left++;
270 pRect->top++;
271 Rectangle(hdc,pRect);
272 pRect->left--;
273
274 SelectObject(hdc,hOldPen);
275 SelectObject(hdc,hOldBrush);
276
277 DeleteObject(hPen);
278 DeleteObject(hBrush);
279
280 TextColor=MENUCOLOR_TEXT;
281 }
282 else{
283 POINT pos;
284 GetCursorPos(&pos);
285 GetWindowRect(hOwner,&rc);
286 pos.x-=rc.left;
287 pos.y-=rc.top;
288 if(HitTest(pRect,&pos)){
289 //ホットイメージで表示
290 HPEN hPen,hOldPen;
291 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_HOT_LINE);
292 hOldPen=(HPEN)SelectObject(hdc,hPen);
293
294 HBRUSH hBrush,hOldBrush;
295 hBrush=CreateSolidBrush(MENUCOLOR_HOT_BACK);
296 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
297
298 pRect->left++;
299 pRect->top++;
300 Rectangle(hdc,pRect);
301 pRect->left--;
302 pRect->top--;
303
304 SelectObject(hdc,hOldPen);
305 SelectObject(hdc,hOldBrush);
306
307 DeleteObject(hPen);
308 DeleteObject(hBrush);
309
310 TextColor=MENUCOLOR_TEXT;
311 }
312 else{
313 BackColor=MENUCOLOR_DEFAULT_BACK;
314 TextColor=MENUCOLOR_TEXT;
315
316 //背景を塗りつぶす
317 HBRUSH hBrush;
318 hBrush=CreateSolidBrush(BackColor);
319 FillRect(hdc,pRect,hBrush);
320 DeleteObject(hBrush);
321 }
322 }
323
324
325 if(ppobj_MenuItemData[item_index]->str){
326 rc=*pRect;
327 rc.top+=1;
328
329 SetBkMode(hdc, TRANSPARENT);
330 SetTextColor(hdc, TextColor);
331
332 HFONT hOldFont;
333 hOldFont=(HFONT)SelectObject(hdc,hMenuFont);
334
335 DrawText(hdc,ppobj_MenuItemData[item_index]->str,-1,&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
336
337 SelectObject(hdc,hOldFont);
338 }
339 else{
340 //セパレータのとき
341 }
342}
343
344
345CSubMenuEx::CSubMenuEx(HMENU hMenu):CMenuEx(hMenu){
346}
347void CSubMenuEx::GetItemSize(int item_index,SIZE *pSize){
348 if(ppobj_MenuItemData[item_index]->str){
349 HDC hdc;
350 hdc = GetDC(GetDesktopWindow());
351 HFONT hOldFont;
352 hOldFont = (HFONT)SelectObject(hdc, hMenuFont);
353
354 GetTextExtentPoint32(hdc,
355 ppobj_MenuItemData[item_index]->str,
356 lstrlen(ppobj_MenuItemData[item_index]->str),
357 pSize);
358
359 SelectObject(hdc,hOldFont);
360 ReleaseDC(GetDesktopWindow(),hdc);
361
362 pSize->cx+=50;
363 if(pSize->cy<22) pSize->cy=22;
364 }
365 else{
366 //セパレータのとき
367 pSize->cx=50;
368 pSize->cy=10;
369 }
370}
371
372void CSubMenuEx::OwnerDrawMenu(HDC hdc,RECT *pRect,BOOL bSelect,int item_index){
373 //////////////////////////////////
374 // サブメニューのオーナー描画
375 //////////////////////////////////
376
377 RECT rc;
378 COLORREF BackColor,TextColor;
379 int i;
380
381 ///////////////////////////////
382 // 左側のグラデーションを描画
383 ///////////////////////////////
384
385 SIZE size;
386 size.cx=22;
387 size.cy=pRect->bottom-pRect->top;
388 HBITMAP hBmp;
389 hBmp=CreateHorzGradationBitmap(&size,RGB(254,254,251),RGB(196,196,173));
390
391 HDC memdc;
392 memdc=CreateCompatibleDC(hdc);
393 SelectObject(memdc,hBmp);
394 BitBlt(hdc,pRect->left,pRect->top,size.cx,size.cy,memdc,0,0,SRCCOPY);
395 DeleteDC(memdc);
396 DeleteObject(hBmp);
397
398
399 if(ppobj_MenuItemData[item_index]->str==0){
400 //セパレータのとき
401 HPEN hPen,hOldPen;
402 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_DEFAULT_LINE);
403 hOldPen=(HPEN)SelectObject(hdc,hPen);
404
405 MoveToEx(hdc,pRect->left+24,pRect->top+(pRect->bottom-pRect->top)/2,NULL);
406 LineTo(hdc,pRect->right,pRect->top+(pRect->bottom-pRect->top)/2);
407
408 SelectObject(hdc,hOldPen);
409 DeleteObject(hPen);
410 return;
411 }
412
413
414 //アイテムの状態を取得
415 MENUITEMINFO mii;
416 mii.cbSize=sizeof(MENUITEMINFO);
417 mii.fMask=MIIM_STATE;
418 GetMenuItemInfo(hMenu,item_index,1,&mii);
419
420
421 if(bSelect&&(mii.fState&MFS_DISABLED)==0){
422 //ホットイメージで表示
423 BackColor=MENUCOLOR_HOT_BACK;
424
425 HPEN hPen,hOldPen;
426 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_HOT_LINE);
427 hOldPen=(HPEN)SelectObject(hdc,hPen);
428
429 HBRUSH hBrush,hOldBrush;
430 hBrush=CreateSolidBrush(BackColor);
431 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
432
433 Rectangle(hdc,pRect);
434
435 SelectObject(hdc,hOldPen);
436 SelectObject(hdc,hOldBrush);
437
438 DeleteObject(hPen);
439 DeleteObject(hBrush);
440 }
441 else{
442 //マウスカーソルの座標を取得
443 POINT pos;
444 GetCursorPos(&pos);
445
446 //親ウィンドウのウィンドウ左上からの相対座標に変換
447 //(クライアント座標ではないところに注意)
448 GetWindowRect(WindowFromDC(hdc),&rc);
449 ScreenToClient(WindowFromDC(hdc),&pos);
450
451 if(bSelect&&HitTest(pRect,&pos)==0){
452 //淡色状態
453 BackColor=MENUCOLOR_SELECT_BACK;
454
455 HPEN hPen,hOldPen;
456 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_SELECT_LINE);
457 hOldPen=(HPEN)SelectObject(hdc,hPen);
458
459 HBRUSH hBrush,hOldBrush;
460 hBrush=CreateSolidBrush(BackColor);
461 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
462
463 Rectangle(hdc,pRect);
464
465 SelectObject(hdc,hOldPen);
466 SelectObject(hdc,hOldBrush);
467
468 DeleteObject(hPen);
469 DeleteObject(hBrush);
470 }
471 else{
472 BackColor=GetSysColor(COLOR_MENU);
473
474 rc=*pRect;
475 rc.left=pRect->left+22;
476 rc.right=pRect->right;
477
478 //背景を塗りつぶす
479 HBRUSH hBrush;
480 hBrush=CreateSolidBrush(BackColor);
481 FillRect(hdc,&rc,hBrush);
482 DeleteObject(hBrush);
483 }
484 }
485
486
487 if(mii.fState&MFS_CHECKED){
488 //チェックマークの外枠を描画
489 rc=*pRect;
490 rc.top++;
491 rc.right=rc.left+20;
492 rc.bottom--;
493
494 HPEN hPen,hOldPen;
495 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_HOT_LINE);
496 hOldPen=(HPEN)SelectObject(hdc,hPen);
497
498 HBRUSH hBrush,hOldBrush;
499 hBrush=CreateSolidBrush(BackColor);
500 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
501
502 Rectangle(hdc,&rc);
503
504 SelectObject(hdc,hOldPen);
505 SelectObject(hdc,hOldBrush);
506
507 DeleteObject(hPen);
508 DeleteObject(hBrush);
509
510
511 //チェックマークを描画
512 int BaseX=rc.left,BaseY=rc.top;
513 for(i=0;i<3;i++){
514 SetPixel(hdc,BaseX+6+i,BaseY+9+i,MENUCOLOR_TEXT);
515 SetPixel(hdc,BaseX+6+i,BaseY+10+i,MENUCOLOR_TEXT);
516 }
517 for(i=0;i<4;i++){
518 SetPixel(hdc,BaseX+9+i,BaseY+10-i,MENUCOLOR_TEXT);
519 SetPixel(hdc,BaseX+9+i,BaseY+11-i,MENUCOLOR_TEXT);
520 }
521 }
522 else{
523 if(ppobj_MenuItemData[item_index]->hIcon){
524 //アイコンを描画
525 HICON hIcon;
526 if(mii.fState&MFS_DISABLED) hIcon=ppobj_MenuItemData[item_index]->hGrayIcon;
527 else hIcon=ppobj_MenuItemData[item_index]->hIcon;
528
529 DrawIconEx(hdc,pRect->left+1,pRect->top+3,hIcon,16,16,0,NULL,DI_NORMAL);
530 }
531 }
532
533
534
535 //メイン文字列とショートカットキー文字列を分別
536 char szMain[255],szShortcut[255];
537 for(i=0;;i++){
538 if(ppobj_MenuItemData[item_index]->str[i]=='\t'){
539 szMain[i]=0;
540
541 lstrcpy(szShortcut,ppobj_MenuItemData[item_index]->str+i+1);
542 break;
543 }
544 szMain[i]=ppobj_MenuItemData[item_index]->str[i];
545 if(ppobj_MenuItemData[item_index]->str[i]=='\0'){
546 szShortcut[0]=0;
547 break;
548 }
549 }
550
551 rc=*pRect;
552 rc.left=pRect->left+26;
553 rc.right=pRect->right;
554
555 HFONT hOldFont;
556 hOldFont=(HFONT)SelectObject(hdc,hMenuFont);
557
558 if(mii.fState&MFS_DISABLED){
559 //淡色カラー
560 TextColor=MENUCOLOR_GRAY_TEXT;
561 }
562 else{
563 //通常カラー
564 TextColor=MENUCOLOR_TEXT;
565 }
566
567 SetBkMode(hdc, TRANSPARENT);
568 SetTextColor(hdc, TextColor);
569
570 DrawText(hdc,szMain,-1,&rc,DT_VCENTER|DT_LEFT|DT_SINGLELINE);
571
572 if(szShortcut[0]){
573 rc.left=rc.right-45;
574 DrawText(hdc,szShortcut,-1,&rc,DT_VCENTER|DT_LEFT|DT_SINGLELINE);
575 }
576
577 SelectObject(hdc,hOldFont);
578}
Note: See TracBrowser for help on using the repository browser.