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

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

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

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