62 t.hMenu = pMenu->m_hMenu;
67 return t.cookie * 0x10000;
80 LRESULT
WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
84 case WM_INITMENUPOPUP:
87 HMENU hMenu =
reinterpret_cast<HMENU
>(wParam);
90 if ( m_params[i].hMenu == hMenu )
92 MEASUREITEMSTRUCT m = { 0 };
95 m.itemData =
reinterpret_cast<DWORD
>(
this);
96 m_params[i].pMenu->MeasureItem(&m);
104 MEASUREITEMSTRUCT* P =
reinterpret_cast<MEASUREITEMSTRUCT*
>(lParam);
105 if ( P->CtlType == ODT_MENU )
107 const TParam* T = m_Search(
static_cast<WORD
>(P->itemData / 0x10000));
110 T->pMenu->MeasureItem(P);
118 DRAWITEMSTRUCT* P =
reinterpret_cast<DRAWITEMSTRUCT*
>(lParam);
119 if ( P->CtlType == ODT_MENU )
121 const TParam* T = m_Search(
static_cast<WORD
>(P->itemData / 0x10000));
124 ASSERT( T->hMenu ==
reinterpret_cast<HMENU
>(P->hwndItem) );
125 T->pMenu->DrawItem(P);
138 return _super::WindowProc(message, wParam, lParam);
157 const TParam* m_Search(WORD w)
159 for (
size_t lp = m_params.
GetSize(); lp > 0; lp-- )
162 const TParam& t = m_params.
At(i);
163 if ( ! ::IsMenu(t.hMenu) )
167 else if ( t.cookie == w )
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)
232 return !! ::IsMenu(_super::m_hMenu);
243 m_textColor = color1;
244 m_textDisableColor = color2;
288 m_baseCookie = o.m_baseCookie;
291 m_fontBold = o.m_fontBold;
292 m_textColor = o.m_textColor;
293 m_textDisableColor = o.m_textDisableColor;
294 m_leftMargin = o.m_leftMargin;
319 return InsertDrawingMenu(
static_cast<UINT
>(-1), nFlags | MF_BYPOSITION, draw, lpszText, nIDNewItem);
339 p.pDraw = draw.
Clone();
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));
359 if ( lpMeasureItemStruct->CtlType != ODT_MENU )
363 if ( (lpMeasureItemStruct->itemData & 0xFFFF0000) != m_baseCookie )
368 if ( lpMeasureItemStruct->CtlID ==
'TMDM' )
371 if ( m_isAllOwnerDraw )
373 m_AllSetOwnerDrawState(pProc, m_withSubMenu);
378 INDEX idx = m_ItemDataToPos(lpMeasureItemStruct->itemData);
379 UINT flag = _super::GetMenuState(down_cast<UINT>(idx), MF_BYPOSITION);
380 if ( idx != INVALID_INDEX )
382 lpMeasureItemStruct->itemWidth = down_cast<UINT>(m_items[lpMeasureItemStruct->itemData & 0xFFFF].width);
384 if ( flag & MF_SEPARATOR )
386 lpMeasureItemStruct->itemHeight /= 2;
396 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
398 if ( lpDrawItemStruct->CtlType != ODT_MENU )
402 if ( (lpDrawItemStruct->itemData & 0xFFFF0000) != m_baseCookie )
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) );
413 mii.fMask = MIIM_FTYPE | MIIM_BITMAP | MIIM_STATE | MIIM_STRING | MIIM_CHECKMARKS;
414 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(idx), &mii, TRUE) );
416 HDC dc = lpDrawItemStruct->hDC;
417 const CRect& rc = lpDrawItemStruct->rcItem;
418 CSize sz = rc.Size();
421 INDEX i = lpDrawItemStruct->itemData & 0xFFFF;
424 str = m_items[i].text;
428 if ( bi.
Set(sz.cx, sz.cy) )
434 m_DrawSelectMaker(bmpDC, sz, lpDrawItemStruct->itemState);
436 if ( (mii.fType & MFT_SEPARATOR) == 0 )
439 const IDrawable* pDraw = m_items[lpDrawItemStruct->itemData & 0xFFFF].pDraw;
444 pDraw->
Draw(bmpDC, 0, (sz.cy - s.cy) / 2);
446 bool isEnable = (lpDrawItemStruct->itemState & (CDIS_DISABLED | CDIS_GRAYED)) == 0;
449 COLORREF c = (isEnable ? m_textColor : m_textDisableColor);
451 if ( isEnable && (mii.fState & MFS_DEFAULT) != 0 )
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);
462 UINT ts = (isEnable ? 0 : DFCS_INACTIVE);
463 if ( (mii.fState & MFS_CHECKED) != 0 )
466 if ( mii.hbmpChecked == NULL )
468 if ( (mii.fType & MFT_RADIOCHECK) == 0 )
470 m_DrawIcon(bmpDC, sz, DFC_MENU, DFCS_MENUCHECK | ts);
474 m_DrawIcon(bmpDC, sz, DFC_MENU, DFCS_MENUBULLET | ts);
484 else if ( mii.hbmpItem != NULL )
487 switch (
reinterpret_cast<INT_PTR
>(mii.hbmpItem) )
489 case HBMMENU_POPUP_CLOSE:
490 t = DFCS_CAPTIONCLOSE;
492 case HBMMENU_POPUP_RESTORE:
493 t = DFCS_CAPTIONRESTORE;
495 case HBMMENU_POPUP_MAXIMIZE:
498 case HBMMENU_POPUP_MINIMIZE:
506 m_DrawIcon(bmpDC, sz, DFC_CAPTION, t | DFCS_FLAT | ts);
513 CRect r(0, 0, sz.cx, sz.cy);
514 CPoint po = r.CenterPoint();
519 ::DrawEdge(bmpDC, r, EDGE_ETCHED, BF_TOP | BF_BOTTOM);
523 m_DrawSelectMaker(bmpDC, sz, lpDrawItemStruct->itemState);
525 bmpDC.
Draw(dc, rc.left, rc.top);
548 m_isAllOwnerDraw = isAllOwnerDraw;
549 m_withSubMenu = withSubMenu;
550 if ( isAllOwnerDraw )
552 m_AllSetOwnerDrawState(pProc,
false);
558 void m_DrawIcon(HDC dc,
const SIZE& sz, UINT t1, UINT t2)
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);
568 void m_DrawText(HDC dc,
const CRect& rc, COLORREF color,
const CStr& text, DWORD style = 0)
588 int len = ::GetMenuItemCount(m_hMenu);
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) );
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);
607 HMENU hSub = ::GetSubMenu(m_hMenu,
ToInt(i));
622 INDEX m_ItemDataToPos(DWORD_PTR data)
624 MENUITEMINFO mif = {
sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_DATA };
627 mif.dwTypeData = tempBuf;
628 loop ( i, _super::GetMenuItemCount() )
630 if ( _super::GetMenuItemInfo(down_cast<UINT>(i), &mif, TRUE) )
632 if ( (mif.fType & MFT_OWNERDRAW) != 0 && mif.dwItemData == data )
638 return INVALID_INDEX;
641 void m_ResetWidths(
void)
643 HDC dc = ::GetWindowDC(NULL);
644 HGDIOBJ old = ::GetCurrentObject(dc, OBJ_FONT);
646 MENUITEMINFO mif = {
sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_DATA | MIIM_STATE };
649 mif.dwTypeData = tempBuf;
650 int len = ::GetMenuItemCount(m_hMenu);
656 if ( _super::GetMenuItemInfo(down_cast<UINT>(i), &mif, TRUE) )
658 INDEX idx = mif.dwItemData;
659 if ( (mif.fType & MFT_OWNERDRAW) != 0 && idx != 0 )
662 if ( m_items.
GetSize() <= idx )
666 CString s = m_items[idx].text;
669 MENUITEMINFO mii = {
sizeof(MENUITEMINFO) };
670 mii.fMask = MIIM_STRING;
671 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(i), &mii, TRUE) );
675 VERIFY( _super::GetMenuItemInfo(down_cast<UINT>(i), &mii, TRUE) );
678 if ( s.Find(
'\t') != INVALID_INDEX )
683 if ( (mif.fState & MF_DEFAULT) != 0 )
687 ::SelectObject(dc, ff);
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) )
696 m_items[idx].width = w;
705 m_items[i].width += size.cx;
709 ::SelectObject(dc, old);
710 ::ReleaseDC(NULL, dc);
713 void m_DrawSelectMaker(HDC dc,
const SIZE& sz, UINT itemState)
715 if ( (itemState & CDIS_HOT) != 0 )
719 else if ( (itemState & CDIS_SELECTED) != 0 )
738 COLORREF m_textColor;
739 COLORREF m_textDisableColor;
741 bool m_isAllOwnerDraw;
769 if ( m_pSubParameter != NULL )
771 delete m_pSubParameter;
772 m_pSubParameter = NULL;
783 if ( m_pSubParameter == NULL )
787 return *m_pSubParameter;
802 if ( m_subs[i]->m_hMenu == hMenu )
808 if ( m_pSubParameter == NULL )
816 if ( P->Attach(hMenu) )
818 P->
Regist(pProc,
true,
true);
860 if ( _super::Attach(hMenu) )
862 Regist(pProc, isAllOwnerDraw, withSubMenu);
880 pWnd->SetForegroundWindow();
881 return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, pWnd->GetSafeHwnd(), lpRect);
894 if ( ::GetCursorPos(&po) )
896 HWND hWnd = _super::GetParentHwnd();
897 ::SetForegroundWindow(hWnd);
898 return ::TrackPopupMenu(m_hMenu, nFlags, po.x, po.y, 0, hWnd, NULL);
904 BOOL LoadMenu(LPCTSTR lpszResourceName);
905 BOOL LoadMenu(UINT nIDResource);
906 BOOL LoadMenuIndirect(
const void* lpMenuTemplate);
941 HMENU hMenu = ::GetMenu(hWnd);
942 if ( _super::Attach(hMenu) )
944 Regist(pProc,
true, withSubMenu);
961 ::GetWindowRect(_super::GetParentHwnd(), &rc);
962 MENUBARINFO mbi = {
sizeof(MENUBARINFO) };
963 MENUITEMINFO mif = {
sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_DATA };
966 mif.dwTypeData = tempBuf;
967 loop ( i, _super::GetMenuItemCount() )
969 if ( ::GetMenuBarInfo(_super::GetParentHwnd(), OBJID_MENU, down_cast<LONG>(i + 1), &mbi) )
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) )
978 if ( (mif.fType & MFT_OWNERDRAW) != 0 )
980 dis.itemData = mif.dwItemData;
984 if ( (st & MF_DISABLED) != 0 )
986 dis.itemState |= CDIS_DISABLED;
988 if ( (st & MF_GRAYED) != 0 )
990 dis.itemState |= CDIS_GRAYED;
992 if ( (st & MF_HILITE) != 0 )
994 dis.itemState |= CDIS_SELECTED;
1009 HWND hWnd = _super::GetParentHwnd();
1010 HDC dc = ::GetWindowDC(hWnd);
1012 ::ReleaseDC(hWnd, dc);
1054 m_topMenu.DestroyMenu();
1055 if ( m_topMenu.LoadMenu(nIDResource) )
1057 CMenu* pMenu = &m_topMenu;
1060 pMenu = m_topMenu.GetSubMenu(pos);
1062 if ( pMenu != NULL )
1064 return _super::Attach(pProc, pMenu->GetSafeHmenu(), isAllOwnerDraw, withSubMenu);
#define loop(VAR, CNT)
loop構文.
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
[表示] 透過処理付イメージ描画.
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
[確認] 空チェック
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
CStrT FindCut(TYP c, CStrT *_pstrRest=NULL) const
[作成] 切り分け
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
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
[取得] ウィンドウハンドル取得
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
[取得] セレクトマークタイプ
bool Draw(HDC dc, int x=0, int y=0) const
[処理] イメージ描画.
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
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
[描画] 描画.