TNB Library
TnbMfcDrawingMenu.h
[詳解]
1#pragma once
14#include "TnbMfcBitmapDC.h"
15#include "TnbSimpleVector.h"
16#include "TnbPointerVector.h"
18#include "TnbFontHandle.h"
19
20
21
22//TNB Library
23namespace TNB {
24namespace MFC {
25
26
27
40{
41 DEFSUPER(CWindowProcedureHooker);
42public:
43
45 COwnerdrawMenuSupportProcedureHooker(void) : m_cookie(0x8000)
46 {
47 }
48
58 DWORD RegisterMenu(CMenu* pMenu)
59 {
60 TParam t;
61 t.pMenu = pMenu;
62 t.hMenu = pMenu->m_hMenu;
63 t.cookie = m_cookie;
64 m_params.Add(t);
65 m_cookie++;
66 m_cookie |= 0x8000;
67 return t.cookie * 0x10000;
68 }
69
70protected:
71
80 LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
81 {
82 switch ( message )
83 {
84 case WM_INITMENUPOPUP:
85#if 0
86 {
87 HMENU hMenu = reinterpret_cast<HMENU>(wParam);
88 loop ( i, m_params.GetSize() )
89 {
90 if ( m_params[i].hMenu == hMenu )
91 {
92 MEASUREITEMSTRUCT m = { 0 };
93 m.CtlType = ODT_MENU;
94 m.CtlID = 'TMDM';
95 m.itemData = reinterpret_cast<DWORD>(this);
96 m_params[i].pMenu->MeasureItem(&m);
97 }
98 }
99 }
100#endif
101 break;
102 case WM_MEASUREITEM:
103 {
104 MEASUREITEMSTRUCT* P = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
105 if ( P->CtlType == ODT_MENU )
106 {
107 const TParam* T = m_Search(static_cast<WORD>(P->itemData / 0x10000));
108 if ( T != NULL )
109 {
110 T->pMenu->MeasureItem(P);
111 return 0;
112 }
113 }
114 }
115 break;
116 case WM_DRAWITEM:
117 {
118 DRAWITEMSTRUCT* P = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
119 if ( P->CtlType == ODT_MENU )
120 {
121 const TParam* T = m_Search(static_cast<WORD>(P->itemData / 0x10000));
122 if ( T != NULL )
123 {
124 ASSERT( T->hMenu == reinterpret_cast<HMENU>(P->hwndItem) );
125 T->pMenu->DrawItem(P);
126 return 0;
127 }
128 }
129 }
130 break;
131 case WM_DESTROY:
132 m_params.RemoveAll();
133 m_cookie = 0x8000;
134 break;
135 default:
136 break;
137 }
138 return _super::WindowProc(message, wParam, lParam);
139 }
140
141private:
143 struct TParam
144 {
145 HMENU hMenu;
146 CMenu* pMenu;
147 WORD cookie;
148 };
149 CSimpleVectorT<TParam> m_params;
150 WORD m_cookie;
157 const TParam* m_Search(WORD w)
158 {
159 for ( size_t lp = m_params.GetSize(); lp > 0; lp-- )
160 {
161 size_t i = lp - 1;
162 const TParam& t = m_params.At(i);
163 if ( ! ::IsMenu(t.hMenu) )
164 {
165 m_params.Remove(i);
166 }
167 else if ( t.cookie == w )
168 {
169 return &t;
170 }
171 }
172 return NULL;
173 }
174};
175
176
177
194class CAbstractDrawingMenu : public CMenu, public CAbstractDrawingCtrl
195{
196 DEFSUPER(CMenu);
198public:
199
202 : _super(), m_leftMargin(20), m_baseCookie(0), m_hWnd(NULL)
203 , m_textColor(::GetSysColor(COLOR_MENUTEXT)), m_textDisableColor(CLR_INVALID)
204 , m_isAllOwnerDraw(false), m_withSubMenu(false)
205 {
206 m_font.SetSystemMenuFont();
207 m_fontBold.SetAsBold(m_font);
208 }
209
212 {
213 }
214
219 HWND GetParentHwnd(void) const
220 {
221 return m_hWnd;
222 }
223
230 bool IsValid(void) const
231 {
232 return !! ::IsMenu(_super::m_hMenu);
233 }
234
241 void SetTextColor(COLORREF color1, COLORREF color2 = CLR_INVALID)
242 {
243 m_textColor = color1;
244 m_textDisableColor = color2;
245 }
246
252 void SetTextFont(HFONT font)
253 {
254 m_font.SetClone(font);
255 m_fontBold.SetAsBold(m_font);
256 }
257
262 void SetLeftMargin(int m)
263 {
264 m_leftMargin = m;
265 }
266
272 void SetDefaultMarkDrawer(COLORREF base = ::GetSysColor(COLOR_MENU))
273 {
275 }
276
283 {
284 CAbstractDrawingCtrl* pDC1 = this;
285 const CAbstractDrawingCtrl* pDC2 = &o;
286 *pDC1 = *pDC2;
287 m_hWnd = o.m_hWnd;
288 m_baseCookie = o.m_baseCookie;
289 m_items = o.m_items;
290 m_font = o.m_font;
291 m_fontBold = o.m_fontBold;
292 m_textColor = o.m_textColor;
293 m_textDisableColor = o.m_textDisableColor;
294 m_leftMargin = o.m_leftMargin;
295 }
296
317 BOOL AppendDrawingMenu(UINT nFlags, const IDrawable& draw, LPCSTR lpszText = NULL, UINT_PTR nIDNewItem = 0)
318 {
319 return InsertDrawingMenu(static_cast<UINT>(-1), nFlags | MF_BYPOSITION, draw, lpszText, nIDNewItem);
320 }
321
335 BOOL InsertDrawingMenu(UINT nPosition, UINT nFlags, const IDrawable& draw, LPCSTR lpszText = NULL, UINT_PTR nIDNewItem = 0)
336 {
337 size_t l = m_items.GetSize();
338 TParam p;
339 p.pDraw = draw.Clone();
340 p.text = lpszText;
341 UINT nf = MF_OWNERDRAW | MF_SEPARATOR | MF_STRING;
342 nFlags = (nFlags & ~nf);
343 BOOL r = _super::InsertMenu(nPosition, nFlags | MF_OWNERDRAW, nIDNewItem, reinterpret_cast<LPCTSTR>(m_baseCookie | l));
344 if ( r )
345 {
346 m_items.Add(p);
347 m_ResetWidths();
348 }
349 return r;
350 }
351
357 virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
358 {
359 if ( lpMeasureItemStruct->CtlType != ODT_MENU )
360 {
361 return;
362 }
363 if ( (lpMeasureItemStruct->itemData & 0xFFFF0000) != m_baseCookie )
364 {
365 return;
366 }
367#if 0
368 if ( lpMeasureItemStruct->CtlID == 'TMDM' )
369 {
370 COwnerdrawMenuSupportProcedureHooker* pProc = reinterpret_cast<COwnerdrawMenuSupportProcedureHooker*>(lpMeasureItemStruct->itemData);
371 if ( m_isAllOwnerDraw )
372 {
373 m_AllSetOwnerDrawState(pProc, m_withSubMenu);
374 }
375 return;
376 }
377#endif
378 INDEX idx = m_ItemDataToPos(lpMeasureItemStruct->itemData);
379 UINT flag = _super::GetMenuState(down_cast<UINT>(idx), MF_BYPOSITION);
380 if ( idx != INVALID_INDEX )
381 {
382 lpMeasureItemStruct->itemWidth = down_cast<UINT>(m_items[lpMeasureItemStruct->itemData & 0xFFFF].width);
383 }
384 if ( flag & MF_SEPARATOR )
385 {
386 lpMeasureItemStruct->itemHeight /= 2;
387 }
388 }
389
396 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
397 {
398 if ( lpDrawItemStruct->CtlType != ODT_MENU )
399 {
400 return;
401 }
402 if ( (lpDrawItemStruct->itemData & 0xFFFF0000) != m_baseCookie )
403 {
404 return;
405 }
406 INDEX idx = m_ItemDataToPos(lpDrawItemStruct->itemData);
407 MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
408 mii.fMask = MIIM_STRING;
409 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(idx), &mii, TRUE) );
410 CStr str;
411 mii.cch++;
412 mii.dwTypeData = str.GetBuffer(mii.cch);
413 mii.fMask = MIIM_FTYPE | MIIM_BITMAP | MIIM_STATE | MIIM_STRING | MIIM_CHECKMARKS;
414 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(idx), &mii, TRUE) );
415 str.ReleaseBuffer();
416 HDC dc = lpDrawItemStruct->hDC;
417 const CRect& rc = lpDrawItemStruct->rcItem;
418 CSize sz = rc.Size();
419 if ( str.IsEmpty() )
420 {
421 INDEX i = lpDrawItemStruct->itemData & 0xFFFF;
422 if ( m_items.IsInRange(i) )
423 {
424 str = m_items[i].text;
425 }
426 }
427 CBitmapImage bi;
428 if ( bi.Set(sz.cx, sz.cy) )
429 {
430 CBitmapDC bmpDC(&bi);
431 _mark::DrawBackground(bmpDC, CRect(CPoint(0, 0), sz));
432 if ( GetSelectMarkType() == BACKGROUND )
433 {
434 m_DrawSelectMaker(bmpDC, sz, lpDrawItemStruct->itemState);
435 }
436 if ( (mii.fType & MFT_SEPARATOR) == 0 )
437 {
438 //TTRACE3("flag=0x%X, id=0x%X, type=0x%X\n", flag, id, mii.fType);
439 const IDrawable* pDraw = m_items[lpDrawItemStruct->itemData & 0xFFFF].pDraw;
440 if ( pDraw != NULL )
441 {
442 SIZE s;
443 pDraw->GetSize(s);
444 pDraw->Draw(bmpDC, 0, (sz.cy - s.cy) / 2);
445 }
446 bool isEnable = (lpDrawItemStruct->itemState & (CDIS_DISABLED | CDIS_GRAYED)) == 0;
447 if ( ! str.IsEmpty() )
448 {
449 COLORREF c = (isEnable ? m_textColor : m_textDisableColor);
450 CFontHandle ff = m_font;
451 if ( isEnable && (mii.fState & MFS_DEFAULT) != 0 )
452 {
453 ff = m_fontBold;
454 }
455 HGDIOBJ hOldFont = ::SelectObject(bmpDC, ff);
456 ::SetBkMode(bmpDC, TRANSPARENT);
457 DWORD st = (m_leftMargin >= 0 ? 0 : DT_CENTER);
458 int mar = max(m_leftMargin, 0);
459 m_DrawText(bmpDC, CRect(2 + mar, 0, sz.cx - 1, sz.cy), c, str, st);
460 ::SelectObject(bmpDC, hOldFont);
461 }
462 UINT ts = (isEnable ? 0 : DFCS_INACTIVE);
463 if ( (mii.fState & MFS_CHECKED) != 0 )
464 {
465 // チェック
466 if ( mii.hbmpChecked == NULL )
467 {
468 if ( (mii.fType & MFT_RADIOCHECK) == 0 )
469 {
470 m_DrawIcon(bmpDC, sz, DFC_MENU, DFCS_MENUCHECK | ts);
471 }
472 else
473 {
474 m_DrawIcon(bmpDC, sz, DFC_MENU, DFCS_MENUBULLET | ts);
475 }
476 }
477 else
478 {
479 CBitmapHandle b = mii.hbmpChecked; //動作未確認
480 b.Draw(bmpDC);
481 b.Detach();
482 }
483 }
484 else if ( mii.hbmpItem != NULL )
485 {
486 int t = -1;
487 switch ( reinterpret_cast<INT_PTR>(mii.hbmpItem) )
488 {
489 case HBMMENU_POPUP_CLOSE:
490 t = DFCS_CAPTIONCLOSE;
491 break;
492 case HBMMENU_POPUP_RESTORE:
493 t = DFCS_CAPTIONRESTORE;
494 break;
495 case HBMMENU_POPUP_MAXIMIZE:
496 t = DFCS_CAPTIONMAX;
497 break;
498 case HBMMENU_POPUP_MINIMIZE:
499 t = DFCS_CAPTIONMIN;
500 break;
501 default:
502 break;
503 }
504 if ( t >= 0 )
505 {
506 m_DrawIcon(bmpDC, sz, DFC_CAPTION, t | DFCS_FLAT | ts);
507 }
508 }
509 }
510 else
511 {
512 // セパレータ
513 CRect r(0, 0, sz.cx, sz.cy);
514 CPoint po = r.CenterPoint();
515 r.left += 3;
516 r.right -= 3;
517 r.top = po.y;
518 r.bottom = po.y + 2;
519 ::DrawEdge(bmpDC, r, EDGE_ETCHED, BF_TOP | BF_BOTTOM);
520 }
521 if ( GetSelectMarkType() == OVERLAP )
522 {
523 m_DrawSelectMaker(bmpDC, sz, lpDrawItemStruct->itemState);
524 }
525 bmpDC.Draw(dc, rc.left, rc.top);
526 }
527 }
528
529protected:
530
537 virtual void OnFoundSubMenu(HMENU hMenu, COwnerdrawMenuSupportProcedureHooker* pProc) = 0;
538
545 void Regist(COwnerdrawMenuSupportProcedureHooker* pProc, bool isAllOwnerDraw = true, bool withSubMenu = true)
546 {
547 m_Regist(pProc);
548 m_isAllOwnerDraw = isAllOwnerDraw;
549 m_withSubMenu = withSubMenu;
550 if ( isAllOwnerDraw )
551 {
552 m_AllSetOwnerDrawState(pProc, false);
553 }
554 }
555
556private:
558 void m_DrawIcon(HDC dc, const SIZE& sz, UINT t1, UINT t2)
559 {
560 CBitmapImage b;
561 b.Set(sz.cy - 2, sz.cy - 2);
562 ::DrawFrameControl(b.GetDC(), CRect(-1, -1, sz.cy - 1 , sz.cy - 1), t1, t2 | DFCS_TRANSPARENT);
563 b.ReleaseDC();
564 b.ChangePixelColor(RGB(0, 0, 0), m_textColor);
565 b.TransparentBit(dc, 1, 1);
566 }
568 void m_DrawText(HDC dc, const CRect& rc, COLORREF color, const CStr& text, DWORD style = 0)
569 {
570 CStr s2;
571 CStr s1 = text.FindCut('\t', &s2);
572 CTextDrawer::DrawTextRect(dc, rc, DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | style, color, s1);
573 if ( ! s2.IsEmpty() )
574 {
575 CTextDrawer::DrawTextRect(dc, rc, DT_VCENTER | DT_RIGHT | DT_SINGLELINE | DT_END_ELLIPSIS, color, s2 + _T(" "));
576 }
577 }
579 void m_Regist(COwnerdrawMenuSupportProcedureHooker* pProc)
580 {
581 m_baseCookie = pProc->RegisterMenu(this);
582 m_hWnd = pProc->GetSafeHwnd();
583 }
585 void m_AllSetOwnerDrawState(COwnerdrawMenuSupportProcedureHooker* pProc, bool withSubMenu = true)
586 {
587 m_items.RemoveAll();
588 int len = ::GetMenuItemCount(m_hMenu);
589 if ( len >= 0 )
590 {
591 loop ( i, len )
592 {
593 MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
594 mii.fMask = MIIM_FTYPE | MIIM_STATE;
595 VERIFY( ::GetMenuItemInfo(m_hMenu, down_cast<UINT>(i), TRUE, &mii) );
596 mii.fMask = MIIM_FTYPE | MIIM_DATA;
597 mii.dwItemData = (m_baseCookie | i);
598 mii.fType |= MFT_OWNERDRAW;
599 VERIFY( ::SetMenuItemInfo(m_hMenu, down_cast<UINT>(i), TRUE, &mii) );
600 #ifdef _DEBUG
601 CString s;
602 _super::GetMenuString(down_cast<UINT>(i), s, MF_BYPOSITION);
603 TTRACE3("[%s] t=0x%X s=0x%X \n", s, mii.fType, mii.fState);
604 #endif
605 if ( withSubMenu )
606 {
607 HMENU hSub = ::GetSubMenu(m_hMenu, ToInt(i));
608 if ( hSub != NULL )
609 {
610 OnFoundSubMenu(hSub, pProc);
611 }
612 }
613 }
614 }
615 m_ResetWidths();
616 }
622 INDEX m_ItemDataToPos(DWORD_PTR data)
623 {
624 MENUITEMINFO mif = { sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_DATA };
625 TCHAR tempBuf[16];
626 mif.cch = 10;
627 mif.dwTypeData = tempBuf;
628 loop ( i, _super::GetMenuItemCount() )
629 {
630 if ( _super::GetMenuItemInfo(down_cast<UINT>(i), &mif, TRUE) )
631 {
632 if ( (mif.fType & MFT_OWNERDRAW) != 0 && mif.dwItemData == data )
633 {
634 return i;
635 }
636 }
637 }
638 return INVALID_INDEX;
639 }
641 void m_ResetWidths(void)
642 {
643 HDC dc = ::GetWindowDC(NULL);
644 HGDIOBJ old = ::GetCurrentObject(dc, OBJ_FONT);
645 CSize size(0, 0);
646 MENUITEMINFO mif = { sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_DATA | MIIM_STATE };
647 TCHAR tempBuf[16];
648 mif.cch = 10;
649 mif.dwTypeData = tempBuf;
650 int len = ::GetMenuItemCount(m_hMenu);
651 if ( len >= 0 )
652 {
653 bool hasTab = false;
654 loop ( i, len )
655 {
656 if ( _super::GetMenuItemInfo(down_cast<UINT>(i), &mif, TRUE) )
657 {
658 INDEX idx = mif.dwItemData;
659 if ( (mif.fType & MFT_OWNERDRAW) != 0 && idx != 0 )
660 {
661 idx &= 0xFFFF;
662 if ( m_items.GetSize() <= idx )
663 {
664 m_items.SetSize(idx + 1);
665 }
666 CString s = m_items[idx].text;
667 if ( s.IsEmpty() )
668 {
669 MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
670 mii.fMask = MIIM_STRING;
671 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(i), &mii, TRUE) );
672 CStr str;
673 mii.cch++;
674 mii.dwTypeData = s.GetBuffer(mii.cch);
675 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(i), &mii, TRUE) );
676 s.ReleaseBuffer();
677 }
678 if ( s.Find('\t') != INVALID_INDEX )
679 {
680 hasTab = true;
681 }
682 CFontHandle ff = m_font;
683 if ( (mif.fState & MF_DEFAULT) != 0 )
684 {
685 ff = m_fontBold;
686 }
687 ::SelectObject(dc, ff);
688 CTextDrawer::CalcTextSize(size, dc, DT_LEFT, s);
689 int mar = max(m_leftMargin, 0);
690 long w = size.cx + 4 + mar;
691 const IDrawable* pDraw = m_items[idx].pDraw;
692 if ( pDraw != NULL && pDraw->GetSize(size) )
693 {
694 w = max(size.cx, w);
695 }
696 m_items[idx].width = w;
697 }
698 }
699 }
700 if ( hasTab )
701 {
702 CTextDrawer::CalcTextSize(size, dc, DT_LEFT, _T("Atl+F4 "));
703 loop ( i, m_items )
704 {
705 m_items[i].width += size.cx;
706 }
707 }
708 }
709 ::SelectObject(dc, old);
710 ::ReleaseDC(NULL, dc);
711 }
713 void m_DrawSelectMaker(HDC dc, const SIZE& sz, UINT itemState)
714 {
715 if ( (itemState & CDIS_HOT) != 0 )
716 {
717 _mark::DrawSelectMark(dc, CRect(CPoint(0, 0), sz), false);
718 }
719 else if ( (itemState & CDIS_SELECTED) != 0 )
720 {
721 _mark::DrawSelectMark(dc, CRect(CPoint(0, 0), sz), true);
722 }
723 }
724
726 struct TParam
727 {
728 size_t width;
729 IDrawable::Ptr pDraw;
730 CString text;
731 };
732
733 HWND m_hWnd;
734 DWORD m_baseCookie;
735 CSimpleVectorT<TParam> m_items;
736 CFontHandle m_font;
737 CFontHandle m_fontBold;
738 COLORREF m_textColor;
739 COLORREF m_textDisableColor;
740 int m_leftMargin;
741 bool m_isAllOwnerDraw;
742 bool m_withSubMenu;
743};
744
745
746
757{
758 DEFSUPER(CAbstractDrawingMenu);
759public:
760
762 CDrawingSubMenu(void) : m_pSubParameter(NULL)
763 {
764 }
765
768 {
769 if ( m_pSubParameter != NULL )
770 {
771 delete m_pSubParameter;
772 m_pSubParameter = NULL;
773 }
774 }
775
782 {
783 if ( m_pSubParameter == NULL )
784 {
785 m_pSubParameter = new CDrawingSubMenu;
786 }
787 return *m_pSubParameter;
788 }
789
790protected:
791
799 {
800 loop ( i, m_subs )
801 {
802 if ( m_subs[i]->m_hMenu == hMenu )
803 {
804 return;
805 }
806 }
808 if ( m_pSubParameter == NULL )
809 {
810 P->CopyParameter(*this);
811 }
812 else
813 {
814 P->CopyParameter(*m_pSubParameter);
815 }
816 if ( P->Attach(hMenu) )
817 {
818 P->Regist(pProc, true, true);
819 m_subs.Add(P);
820 return;
821 }
822 delete P;
823 }
824
825private:
827 CDrawingSubMenu* m_pSubParameter;
828};
829
830
831
845{
846 DEFSUPER(CDrawingSubMenu);
847public:
848
858 BOOL Attach(COwnerdrawMenuSupportProcedureHooker* pProc, HMENU hMenu, bool isAllOwnerDraw = false, bool withSubMenu = false)
859 {
860 if ( _super::Attach(hMenu) )
861 {
862 Regist(pProc, isAllOwnerDraw, withSubMenu);
863 return TRUE;
864 }
865 return FALSE;
866 }
867
878 BOOL TrackPopupMenu(UINT nFlags, int x, int y, CWnd* pWnd = NULL, LPCRECT lpRect = 0)
879 {
880 pWnd->SetForegroundWindow();
881 return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, pWnd->GetSafeHwnd(), lpRect);
882 }
883
891 BOOL TrackPopupMenu(UINT nFlags = TPM_LEFTALIGN | TPM_RIGHTBUTTON)
892 {
893 POINT po;
894 if ( ::GetCursorPos(&po) )
895 {
896 HWND hWnd = _super::GetParentHwnd();
897 ::SetForegroundWindow(hWnd);
898 return ::TrackPopupMenu(m_hMenu, nFlags, po.x, po.y, 0, hWnd, NULL);
899 }
900 return FALSE;
901 }
902
903private:
904 BOOL LoadMenu(LPCTSTR lpszResourceName);
905 BOOL LoadMenu(UINT nIDResource);
906 BOOL LoadMenuIndirect(const void* lpMenuTemplate);
907
908};
909
910
911
926{
927 DEFSUPER(CDrawingSubMenu);
928public:
929
938 BOOL Attach(COwnerdrawMenuSupportProcedureHooker* pProc, bool withSubMenu = false)
939 {
940 HWND hWnd = pProc->GetSafeHwnd();
941 HMENU hMenu = ::GetMenu(hWnd);
942 if ( _super::Attach(hMenu) )
943 {
944 Regist(pProc, true, withSubMenu);
945 return TRUE;
946 }
947 return FALSE;
948 }
949
956 void Draw(HDC dc)
957 {
958 if ( IsValid() )
959 {
960 RECT rc;
961 ::GetWindowRect(_super::GetParentHwnd(), &rc);
962 MENUBARINFO mbi = { sizeof(MENUBARINFO) }; // WINVER が 0x0501 じゃないとエラーになる
963 MENUITEMINFO mif = { sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_DATA };
964 TCHAR tempBuf[16];
965 mif.cch = 10;
966 mif.dwTypeData = tempBuf;
967 loop ( i, _super::GetMenuItemCount() )
968 {
969 if ( ::GetMenuBarInfo(_super::GetParentHwnd(), OBJID_MENU, down_cast<LONG>(i + 1), &mbi) )
970 {
971 UINT st = ::GetMenuState(mbi.hMenu, down_cast<UINT>(i), MF_BYPOSITION);
972 DRAWITEMSTRUCT dis = { 0 };
973 dis.CtlType = ODT_MENU;
974 dis.rcItem = mbi.rcBar;
975 ::OffsetRect(&dis.rcItem, -rc.left, -rc.top);
976 if ( _super::GetMenuItemInfo(down_cast<UINT>(i), &mif, TRUE) )
977 {
978 if ( (mif.fType & MFT_OWNERDRAW) != 0 )
979 {
980 dis.itemData = mif.dwItemData;
981 }
982 }
983 dis.hDC = dc;
984 if ( (st & MF_DISABLED) != 0 )
985 {
986 dis.itemState |= CDIS_DISABLED;
987 }
988 if ( (st & MF_GRAYED) != 0 )
989 {
990 dis.itemState |= CDIS_GRAYED;
991 }
992 if ( (st & MF_HILITE) != 0 )
993 {
994 dis.itemState |= CDIS_SELECTED;
995 }
996 DrawItem(&dis);
997 }
998 }
999 }
1000 }
1001
1007 void Draw(void)
1008 {
1009 HWND hWnd = _super::GetParentHwnd();
1010 HDC dc = ::GetWindowDC(hWnd);
1011 Draw(dc);
1012 ::ReleaseDC(hWnd, dc);
1013 }
1014};
1015
1016
1017
1033{
1034 DEFSUPER(CDrawingMenu);
1035public:
1036
1039 {
1040 }
1041
1052 BOOL LoadMenu(COwnerdrawMenuSupportProcedureHooker* pProc, UINT nIDResource, int pos = -1, bool isAllOwnerDraw = false, bool withSubMenu = false)
1053 {
1054 m_topMenu.DestroyMenu();
1055 if ( m_topMenu.LoadMenu(nIDResource) )
1056 {
1057 CMenu* pMenu = &m_topMenu;
1058 if ( pos >= 0 )
1059 {
1060 pMenu = m_topMenu.GetSubMenu(pos);
1061 }
1062 if ( pMenu != NULL )
1063 {
1064 return _super::Attach(pProc, pMenu->GetSafeHmenu(), isAllOwnerDraw, withSubMenu);
1065 }
1066 }
1067 return FALSE;
1068 }
1069
1070private:
1071 CMenu m_topMenu;
1072};
1073
1074
1075
1076}; // MFC
1077}; // TNB
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
フォントハンドル関係のヘッダ
描画情報コントロール抽象クラス関係のヘッダ
ビットマップDC関係のヘッダ
ポインタ配列管理関係のヘッダ
簡易配列型情報管理関係のヘッダ
ウィンドウプロシージャフック関係のヘッダ
ウィンドウ管理.
HBITMAP型ハンドルハンドル
bool Draw(HDC hdc, int x=0, int y=0) const
[処理] イメージ描画.
HBITMAP Detach(void)
[取得] デタッチ.
ビットマップイメージ管理クラス
int ChangePixelColor(COLORREF targetColor, COLORREF drawColor)
[処理] カラー変更.
HDC GetDC(void)
[取得]デバイスコンテキストハンドル取得.
bool Set(int cx, int cy, COLORREF color=CLR_INVALID)
[設定] イメージ設定.
bool ReleaseDC(void)
[設定] デバイスコンテキストハンドル返却.
bool TransparentBit(HDC hdc, int x, int y, COLORREF color=CLR_AUTOSELECT, int cx=0, int cy=0) const
[表示] 透過処理付イメージ描画.
HFONT型ハンドルハンドル
Definition: TnbFontHandle.h:80
bool SetClone(HFONT hFont, double mul=1.0)
[設定] フォント設定.
bool SetAsBold(HFONT hFont)
[設定] フォント設定.
bool SetSystemMenuFont(void)
[設定] メニューフォント設定.
ポインタ配列管理テンプレート
void RemoveAll(void)
[削除] 空化
size_t GetSize(void) const
[取得] サイズ取得
bool Remove(INDEX index)
[削除] 要素一つ削除.
void SetSize(size_t s)
[設定] サイズ設定
bool IsInRange(INDEX index) const
[確認] INDEXの有効確認.
const TYP & At(INDEX index) const
[取得] 要素の参照取得.
INDEX Add(const TYP &t)
[追加] 要素一つ追加.
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbStr.h:954
CStrT FindCut(TYP c, CStrT *_pstrRest=NULL) const
[作成] 切り分け
Definition: TnbStr.h:1122
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
Definition: TnbStr.h:914
static bool CalcTextSize(SIZE &_size, HDC dc, UINT drawStyle, LPCTSTR str)
[計算] 文字表示大きさ計算.
static bool DrawTextRect(RECT &_rect, HDC dc, DWORD drawStyle, const POINT &offset, COLORREF color1, COLORREF color2, LPCTSTR str)
[表示] 範囲文字表示.
ウィンドウプロシージャフッククラス
HWND GetSafeHwnd(void) const
[取得] ウィンドウハンドル取得
描画情報コントロール抽象クラス
@ OVERLAP
アイテム描画上に描画
void SetDefaultMarkDrawer(COLORREF base=::GetSysColor(COLOR_WINDOW))
[設定] デフォルトのマーク描画指定.
void DrawBackground(HDC dc, const RECT &rect, LPARAM lParam=0)
[描画] 背景表示
void DrawSelectMark(HDC dc, const RECT &rect, bool isActive, LPARAM lParam=0)
[描画] 選択マーク表示
ESelectMarkType GetSelectMarkType(void) const
[取得] セレクトマークタイプ
描画情報Menuコントロール
void CopyParameter(const CAbstractDrawingMenu &o)
[設定] 設定の複製.
CAbstractDrawingMenu(void)
コンストラクタ
void SetTextFont(HFONT font)
[設定] 文字フォント指定
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
[通知] オーナードロー処理.
bool IsValid(void) const
[確認] 有効確認.
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
[通知] オーナードロー時.
void SetTextColor(COLORREF color1, COLORREF color2=CLR_INVALID)
[設定] 文字色指定
HWND GetParentHwnd(void) const
[取得] 親ウィンドウハンドル取得.
BOOL InsertDrawingMenu(UINT nPosition, UINT nFlags, const IDrawable &draw, LPCSTR lpszText=NULL, UINT_PTR nIDNewItem=0)
[追加] メニュー追加.
void SetDefaultMarkDrawer(COLORREF base=::GetSysColor(COLOR_MENU))
[設定] デフォルトのマーク描画指定.
virtual void OnFoundSubMenu(HMENU hMenu, COwnerdrawMenuSupportProcedureHooker *pProc)=0
[通知] サブメニュ発見.
void SetLeftMargin(int m)
[設定] 文字表示位置指定
BOOL AppendDrawingMenu(UINT nFlags, const IDrawable &draw, LPCSTR lpszText=NULL, UINT_PTR nIDNewItem=0)
[追加] メニュー追加.
void Regist(COwnerdrawMenuSupportProcedureHooker *pProc, bool isAllOwnerDraw=true, bool withSubMenu=true)
[設定] 登録.
~CAbstractDrawingMenu(void)
デストラクタ
ビットマップデバイスコンテキストクラス
bool Draw(HDC dc, int x=0, int y=0) const
[処理] イメージ描画.
描画情報ロードメニュー
CDrawingLoadMenu(void)
コンストラクタ
BOOL LoadMenu(COwnerdrawMenuSupportProcedureHooker *pProc, UINT nIDResource, int pos=-1, bool isAllOwnerDraw=false, bool withSubMenu=false)
[設定] ロードメニュー
描画情報メニューバー
BOOL Attach(COwnerdrawMenuSupportProcedureHooker *pProc, bool withSubMenu=false)
[設定] アタッチ.
void Draw(HDC dc)
[描画] 描画
void Draw(void)
[描画] 描画
描画情報メニュー
BOOL TrackPopupMenu(UINT nFlags, int x, int y, CWnd *pWnd=NULL, LPCRECT lpRect=0)
[表示] メニュー表示.
BOOL TrackPopupMenu(UINT nFlags=TPM_LEFTALIGN|TPM_RIGHTBUTTON)
[表示] メニュー表示.
BOOL Attach(COwnerdrawMenuSupportProcedureHooker *pProc, HMENU hMenu, bool isAllOwnerDraw=false, bool withSubMenu=false)
[設定] アタッチ.
描画情報サブメニュー
CAbstractDrawingMenu & ReferSubParameter(void)
[参照] サブメニュ描画情報.
CDrawingSubMenu(void)
コンストラクタ
void OnFoundSubMenu(HMENU hMenu, COwnerdrawMenuSupportProcedureHooker *pProc)
[通知] サブメニュ発見.
~CDrawingSubMenu(void)
デストラクタ
オーナードローメニューサポートプロシージャ
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
[通知] for processing Windows messages.
DWORD RegisterMenu(CMenu *pMenu)
[登録] メニュー登録.
COwnerdrawMenuSupportProcedureHooker(void)
コンストラクタ
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
TNB Library
Definition: TnbDoxyTitle.txt:2
描画情報インターフェース
Definition: TnbDrawable.h:37
virtual bool GetSize(SIZE &_size) const =0
[取得] サイズ取得.
virtual IDrawable * Clone(void) const =0
[作成] クローン作成.
virtual void Draw(HDC dc, int x=0, int y=0) const =0
[描画] 描画.