source: dev/trunk/ab5.0/abdev/abdev/menu.cpp

Last change on this file was 829, checked in by イグトランス (egtra), 12 years ago

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/plain; charset=Shift_JIS
File size: 13.2 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
134 for( int i=0; i<iMenuItemNum; i++ )
135 {
136 if(ppobj_MenuItemData[i]->itemID==itemID){
137 ppobj_MenuItemData[i]->hIcon=hIcon;
138
139
140 /////////////////////////
141 // 淡色アイコンを作成
142 /////////////////////////
143
144 ppobj_MenuItemData[i]->hGrayIcon=CreateGrayIcon(hIcon);
145 return 1;
146 }
147 if(ppobj_MenuItemData[i]->pobj_SubMenu){
148 BOOL bResult;
149 bResult=ppobj_MenuItemData[i]->pobj_SubMenu->SetIcon(itemID,hIcon);
150 if(bResult) return 1;
151 }
152 }
153 return 0;
154}
155
156int CMenuEx::FindSubMenuIndex( const std::string &itemStr )
157{
158 for( int i=0; i<iMenuItemNum; i++ )
159 {
160 if( itemStr == ppobj_MenuItemData[i]->str )
161 {
162 return i;
163 }
164 }
165 return -1;
166}
167
168CMenuItemData *CMenuEx::AddMenuExItemData(int item_index,int itemID,char *str,CMenuEx *pobj_ThisMenu,CSubMenuEx *pobj_SubMenu){
169 CMenuItemData *pobj_MenuItemData;
170 pobj_MenuItemData=new CMenuItemData(item_index,itemID,str,pobj_ThisMenu,pobj_SubMenu);
171
172
173 ppobj_MenuItemData=(CMenuItemData **)HeapReAlloc(hHeap,0,ppobj_MenuItemData,(iMenuItemNum+1)*sizeof(CMenuItemData *));
174
175 int i;
176 for(i=iMenuItemNum;i>item_index;i--){
177 ppobj_MenuItemData[i]=ppobj_MenuItemData[i-1];
178 }
179
180 ppobj_MenuItemData[item_index]=pobj_MenuItemData;
181
182 iMenuItemNum++;
183
184 return pobj_MenuItemData;
185}
186void CMenuEx::InitOwnerDraw(BOOL bParent){
187 char temporary[MAX_PATH];
188 MENUITEMINFO mii;
189 memset(&mii,0,sizeof(MENUITEMINFO));
190 mii.cbSize=sizeof(MENUITEMINFO);
191 mii.fMask=MIIM_TYPE|MIIM_ID|MIIM_SUBMENU|MIIM_DATA;
192
193 int nCount;
194 nCount=GetMenuItemCount(hMenu);
195
196 int i;
197 for(i=0;i<nCount;i++){
198 mii.dwTypeData=temporary;
199 mii.cch=MAX_PATH;
200 GetMenuItemInfo(hMenu,i,1,&mii);
201
202 char *temp2=0;
203 if(mii.fType==MFT_STRING) temp2=temporary;
204
205 int fType_Separator;
206 if(mii.fType==MFT_SEPARATOR) fType_Separator=MFT_SEPARATOR;
207 else fType_Separator=0;
208
209 CSubMenuEx *pobj_SubMenu;
210 if(mii.hSubMenu){
211 pobj_SubMenu=new CSubMenuEx(mii.hSubMenu);
212 pobj_SubMenu->InitOwnerDraw(0);
213 }
214 else pobj_SubMenu=0;
215
216 //拡張データをメモリに退避
217 CMenuItemData *pobj_MenuItemData;
218 pobj_MenuItemData=AddMenuExItemData(i,mii.wID,temp2,this,pobj_SubMenu);
219
220 mii.fType=MFT_OWNERDRAW | fType_Separator;
221 mii.dwItemData=(ULONG_PTR)pobj_MenuItemData;
222 SetMenuItemInfo(hMenu,i,1,&mii);
223 }
224}
225void CMenuEx::GetItemSize(int item_index,SIZE *pSize){
226 if(ppobj_MenuItemData[item_index]->str){
227 HDC hdc;
228 hdc = GetDC(GetDesktopWindow());
229 HFONT hOldFont;
230 hOldFont = (HFONT)SelectObject(hdc, hMenuFont);
231
232 GetTextExtentPoint32(hdc,
233 ppobj_MenuItemData[item_index]->str,
234 lstrlen(ppobj_MenuItemData[item_index]->str),
235 pSize);
236
237 SelectObject(hdc,hOldFont);
238 ReleaseDC(GetDesktopWindow(),hdc);
239 }
240 else{
241 //セパレータのとき
242 pSize->cx=50;
243 pSize->cy=10;
244 }
245}
246
247BOOL CMenuEx::OwnerDrawSubMenu(HMENU hSubMenu,HDC hdc,RECT *pRect,BOOL bSelect,int item_index){
248 int i;
249 for(i=0;i<iMenuItemNum;i++){
250 if(ppobj_MenuItemData[i]->pobj_SubMenu){
251 if(hSubMenu==ppobj_MenuItemData[i]->pobj_SubMenu->hMenu){
252 ppobj_MenuItemData[i]->pobj_SubMenu->OwnerDrawMenu(hdc,pRect,bSelect,item_index);
253 return 1;
254 }
255 else{
256 BOOL bResult;
257 bResult=ppobj_MenuItemData[i]->pobj_SubMenu->OwnerDrawSubMenu(hSubMenu,hdc,pRect,bSelect,item_index);
258 if(bResult) return 1;
259 }
260 }
261 }
262 return 0;
263}
264void CMenuEx::OwnerDrawMenu(HDC hdc,RECT *pRect,BOOL bSelect,int item_index){
265 /////////////////////////////////
266 // 親メニューのオーナー描画
267 /////////////////////////////////
268
269
270 COLORREF BackColor,TextColor;
271
272 RECT rc;
273
274 if(bSelect){
275 //選択状態にある場合
276 HPEN hPen,hOldPen;
277 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_SELECT_LINE);
278 hOldPen=(HPEN)SelectObject(hdc,hPen);
279
280 HBRUSH hBrush,hOldBrush;
281 hBrush=CreateSolidBrush(MENUCOLOR_SELECT_BACK);
282 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
283
284 pRect->left++;
285 pRect->top++;
286 Rectangle(hdc,pRect);
287 pRect->left--;
288
289 SelectObject(hdc,hOldPen);
290 SelectObject(hdc,hOldBrush);
291
292 DeleteObject(hPen);
293 DeleteObject(hBrush);
294
295 TextColor=MENUCOLOR_TEXT;
296 }
297 else{
298 POINT pos;
299 GetCursorPos(&pos);
300 GetWindowRect(hOwner,&rc);
301 pos.x-=rc.left;
302 pos.y-=rc.top;
303 if(HitTest(pRect,&pos)){
304 //ホットイメージで表示
305 HPEN hPen,hOldPen;
306 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_HOT_LINE);
307 hOldPen=(HPEN)SelectObject(hdc,hPen);
308
309 HBRUSH hBrush,hOldBrush;
310 hBrush=CreateSolidBrush(MENUCOLOR_HOT_BACK);
311 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
312
313 pRect->left++;
314 pRect->top++;
315 Rectangle(hdc,pRect);
316 pRect->left--;
317 pRect->top--;
318
319 SelectObject(hdc,hOldPen);
320 SelectObject(hdc,hOldBrush);
321
322 DeleteObject(hPen);
323 DeleteObject(hBrush);
324
325 TextColor=MENUCOLOR_TEXT;
326 }
327 else{
328 BackColor=MENUCOLOR_DEFAULT_BACK;
329 TextColor=MENUCOLOR_TEXT;
330
331 //背景を塗りつぶす
332 HBRUSH hBrush;
333 hBrush=CreateSolidBrush(BackColor);
334 FillRect(hdc,pRect,hBrush);
335 DeleteObject(hBrush);
336 }
337 }
338
339
340 if(ppobj_MenuItemData[item_index]->str){
341 rc=*pRect;
342 rc.top+=1;
343
344 SetBkMode(hdc, TRANSPARENT);
345 SetTextColor(hdc, TextColor);
346
347 HFONT hOldFont;
348 hOldFont=(HFONT)SelectObject(hdc,hMenuFont);
349
350 DrawText(hdc,ppobj_MenuItemData[item_index]->str,-1,&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
351
352 SelectObject(hdc,hOldFont);
353 }
354 else{
355 //セパレータのとき
356 }
357}
358
359
360CSubMenuEx::CSubMenuEx(HMENU hMenu):CMenuEx(hMenu){
361}
362void CSubMenuEx::GetItemSize(int item_index,SIZE *pSize){
363 if(ppobj_MenuItemData[item_index]->str){
364 HDC hdc;
365 hdc = GetDC(GetDesktopWindow());
366 HFONT hOldFont;
367 hOldFont = (HFONT)SelectObject(hdc, hMenuFont);
368
369 GetTextExtentPoint32(hdc,
370 ppobj_MenuItemData[item_index]->str,
371 lstrlen(ppobj_MenuItemData[item_index]->str),
372 pSize);
373
374 SelectObject(hdc,hOldFont);
375 ReleaseDC(GetDesktopWindow(),hdc);
376
377 pSize->cx+=50;
378 if(pSize->cy<22) pSize->cy=22;
379 }
380 else{
381 //セパレータのとき
382 pSize->cx=50;
383 pSize->cy=10;
384 }
385}
386
387void CSubMenuEx::OwnerDrawMenu(HDC hdc,RECT *pRect,BOOL bSelect,int item_index){
388 //////////////////////////////////
389 // サブメニューのオーナー描画
390 //////////////////////////////////
391
392 RECT rc;
393 COLORREF BackColor,TextColor;
394 int i;
395
396 ///////////////////////////////
397 // 左側のグラデーションを描画
398 ///////////////////////////////
399
400 SIZE size;
401 size.cx=22;
402 size.cy=pRect->bottom-pRect->top;
403 HBITMAP hBmp;
404 hBmp=CreateHorzGradationBitmap(&size,RGB(254,254,251),RGB(196,196,173));
405
406 HDC memdc;
407 memdc=CreateCompatibleDC(hdc);
408 SelectObject(memdc,hBmp);
409 BitBlt(hdc,pRect->left,pRect->top,size.cx,size.cy,memdc,0,0,SRCCOPY);
410 DeleteDC(memdc);
411 DeleteObject(hBmp);
412
413
414 if(ppobj_MenuItemData[item_index]->str==0){
415 //セパレータのとき
416 HPEN hPen,hOldPen;
417 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_DEFAULT_LINE);
418 hOldPen=(HPEN)SelectObject(hdc,hPen);
419
420 MoveToEx(hdc,pRect->left+24,pRect->top+(pRect->bottom-pRect->top)/2,NULL);
421 LineTo(hdc,pRect->right,pRect->top+(pRect->bottom-pRect->top)/2);
422
423 SelectObject(hdc,hOldPen);
424 DeleteObject(hPen);
425 return;
426 }
427
428
429 //アイテムの状態を取得
430 MENUITEMINFO mii;
431 mii.cbSize=sizeof(MENUITEMINFO);
432 mii.fMask=MIIM_STATE;
433 GetMenuItemInfo(hMenu,item_index,1,&mii);
434
435
436 if(bSelect&&(mii.fState&MFS_DISABLED)==0){
437 //ホットイメージで表示
438 BackColor=MENUCOLOR_HOT_BACK;
439
440 HPEN hPen,hOldPen;
441 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_HOT_LINE);
442 hOldPen=(HPEN)SelectObject(hdc,hPen);
443
444 HBRUSH hBrush,hOldBrush;
445 hBrush=CreateSolidBrush(BackColor);
446 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
447
448 Rectangle(hdc,pRect);
449
450 SelectObject(hdc,hOldPen);
451 SelectObject(hdc,hOldBrush);
452
453 DeleteObject(hPen);
454 DeleteObject(hBrush);
455 }
456 else{
457 //マウスカーソルの座標を取得
458 POINT pos;
459 GetCursorPos(&pos);
460
461 //親ウィンドウのウィンドウ左上からの相対座標に変換
462 //(クライアント座標ではないところに注意)
463 GetWindowRect(WindowFromDC(hdc),&rc);
464 ScreenToClient(WindowFromDC(hdc),&pos);
465
466 if(bSelect&&HitTest(pRect,&pos)==0){
467 //淡色状態
468 BackColor=MENUCOLOR_SELECT_BACK;
469
470 HPEN hPen,hOldPen;
471 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_SELECT_LINE);
472 hOldPen=(HPEN)SelectObject(hdc,hPen);
473
474 HBRUSH hBrush,hOldBrush;
475 hBrush=CreateSolidBrush(BackColor);
476 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
477
478 Rectangle(hdc,pRect);
479
480 SelectObject(hdc,hOldPen);
481 SelectObject(hdc,hOldBrush);
482
483 DeleteObject(hPen);
484 DeleteObject(hBrush);
485 }
486 else{
487 BackColor=GetSysColor(COLOR_MENU);
488
489 rc=*pRect;
490 rc.left=pRect->left+22;
491 rc.right=pRect->right;
492
493 //背景を塗りつぶす
494 HBRUSH hBrush;
495 hBrush=CreateSolidBrush(BackColor);
496 FillRect(hdc,&rc,hBrush);
497 DeleteObject(hBrush);
498 }
499 }
500
501
502 if(mii.fState&MFS_CHECKED){
503 //チェックマークの外枠を描画
504 rc=*pRect;
505 rc.top++;
506 rc.right=rc.left+20;
507 rc.bottom--;
508
509 HPEN hPen,hOldPen;
510 hPen=CreatePen(PS_SOLID,0,MENUCOLOR_HOT_LINE);
511 hOldPen=(HPEN)SelectObject(hdc,hPen);
512
513 HBRUSH hBrush,hOldBrush;
514 hBrush=CreateSolidBrush(BackColor);
515 hOldBrush=(HBRUSH)SelectObject(hdc,hBrush);
516
517 Rectangle(hdc,&rc);
518
519 SelectObject(hdc,hOldPen);
520 SelectObject(hdc,hOldBrush);
521
522 DeleteObject(hPen);
523 DeleteObject(hBrush);
524
525
526 //チェックマークを描画
527 int BaseX=rc.left,BaseY=rc.top;
528 for(i=0;i<3;i++){
529 SetPixel(hdc,BaseX+6+i,BaseY+9+i,MENUCOLOR_TEXT);
530 SetPixel(hdc,BaseX+6+i,BaseY+10+i,MENUCOLOR_TEXT);
531 }
532 for(i=0;i<4;i++){
533 SetPixel(hdc,BaseX+9+i,BaseY+10-i,MENUCOLOR_TEXT);
534 SetPixel(hdc,BaseX+9+i,BaseY+11-i,MENUCOLOR_TEXT);
535 }
536 }
537 else{
538 if(ppobj_MenuItemData[item_index]->hIcon){
539 //アイコンを描画
540 HICON hIcon;
541 if(mii.fState&MFS_DISABLED) hIcon=ppobj_MenuItemData[item_index]->hGrayIcon;
542 else hIcon=ppobj_MenuItemData[item_index]->hIcon;
543
544 DrawIconEx(hdc,pRect->left+1,pRect->top+3,hIcon,16,16,0,NULL,DI_NORMAL);
545 }
546 }
547
548
549
550 //メイン文字列とショートカットキー文字列を分別
551 char szMain[255],szShortcut[255];
552 for(i=0;;i++){
553 if(ppobj_MenuItemData[item_index]->str[i]=='\t'){
554 szMain[i]=0;
555
556 lstrcpy(szShortcut,ppobj_MenuItemData[item_index]->str+i+1);
557 break;
558 }
559 szMain[i]=ppobj_MenuItemData[item_index]->str[i];
560 if(ppobj_MenuItemData[item_index]->str[i]=='\0'){
561 szShortcut[0]=0;
562 break;
563 }
564 }
565
566 rc=*pRect;
567 rc.left=pRect->left+26;
568 rc.right=pRect->right;
569
570 HFONT hOldFont;
571 hOldFont=(HFONT)SelectObject(hdc,hMenuFont);
572
573 if(mii.fState&MFS_DISABLED){
574 //淡色カラー
575 TextColor=MENUCOLOR_GRAY_TEXT;
576 }
577 else{
578 //通常カラー
579 TextColor=MENUCOLOR_TEXT;
580 }
581
582 SetBkMode(hdc, TRANSPARENT);
583 SetTextColor(hdc, TextColor);
584
585 DrawText(hdc,szMain,-1,&rc,DT_VCENTER|DT_LEFT|DT_SINGLELINE);
586
587 if(szShortcut[0]){
588 rc.left=rc.right-45;
589 DrawText(hdc,szShortcut,-1,&rc,DT_VCENTER|DT_LEFT|DT_SINGLELINE);
590 }
591
592 SelectObject(hdc,hOldFont);
593}
Note: See TracBrowser for help on using the repository browser.