본문 바로가기

Windows/MFC

Context Menu Drawing (컨텍스트 메뉴에 그리기)

// view
// The first statement initializes pMenu with a pointer to a CMenu object representing the main menu. ModifyMenu is then called five times in succession to tag the items in the Color menu with the flag MF_OWNERDRAW.
void CChildView::OnContextMenu(CWnd* pWnd, CPoint point)
{
    CMenu menu;
    menu.LoadMenu (IDR_CONTEXTMENU);
    CMenu* pContextMenu = menu.GetSubMenu (0);

    for (int i=0; i<5; i++)
        pContextMenu->ModifyMenu (ID_COLOR_RED + i, MF_BYCOMMAND | MF_OWNERDRAW, ID_COLOR_RED + i);

    pContextMenu->TrackPopupMenu (TPM_LEFTALIGN | TPM_LEFTBUTTON |
        TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd ());
    return;
}

void CMainFrame::OnDrawItem (int nIDCtl, LPDRAWITEMSTRUCT lpdis)
{
    BITMAP bm;
    CBitmap bitmap;
    bitmap.LoadOEMBitmap (OBM_CHECK);
    bitmap.GetObject (sizeof (bm), &bm);

    CDC dc;
    dc.Attach (lpdis->hDC);

    CBrush* pBrush = new CBrush (::GetSysColor ((lpdis->itemState &
        ODS_SELECTED) ? COLOR_HIGHLIGHT : COLOR_MENU));
    dc.FrameRect (&(lpdis->rcItem), pBrush);
    delete pBrush;

    if (lpdis->itemState & ODS_CHECKED) {
        CDC dcMem;
        dcMem.CreateCompatibleDC (&dc);
        CBitmap* pOldBitmap = dcMem.SelectObject (&bitmap);

        dc.BitBlt (lpdis->rcItem.left + 4, lpdis->rcItem.top +
            (((lpdis->rcItem.bottom - lpdis->rcItem.top) -
            bm.bmHeight) / 2), bm.bmWidth, bm.bmHeight, &dcMem,
            0, 0, SRCCOPY);

        dcMem.SelectObject (pOldBitmap);
    }

    UINT itemID = lpdis->itemID & 0xFFFF; // Fix for Win95/98 bug
    pBrush = new CBrush (m_wndView.m_clrColors[itemID - ID_COLOR_RED]);
    CRect rect = lpdis->rcItem;
    rect.DeflateRect (6, 4);
    rect.left += bm.bmWidth;
    dc.FillRect (rect, pBrush);
    delete pBrush;

    dc.Detach ();
}