BOOL CWinMenu::DrawMenuItems(HDC hDC, LPRECT pRect) { if ( hDC == NULL || pRect == NULL ) return FALSE; BOOL bFirst = m_bFirstDraw; m_bFirstDraw = FALSE; CText text; long x = pRect->left + 4; long y = pRect->top + 4; long w = pRect->right - pRect->left - 8; long bx = x; long by = y; // Set colors COLORREF rgbMenu, rgbMenuText, rgbSel, rgbSelText; if ( m_bSystemColors ) { rgbMenu = GetSysColor( COLOR_MENU ); rgbMenuText = GetSysColor( COLOR_MENUTEXT ); rgbSel = GetSysColor( COLOR_HIGHLIGHT ); rgbSelText = GetSysColor( COLOR_HIGHLIGHTTEXT ); } // end if else { rgbMenu = m_rgbMenu; rgbMenuText = m_rgbMenuText; rgbSel = m_rgbSel; rgbSelText = m_rgbSelText; } // end else COLORREF rgbLightPen = ScaleColor( rgbMenu, 100 ); COLORREF rgbDarkPen = ScaleColor( rgbMenu, -150 ); COLORREF rgbBck = rgbMenu; COLORREF rgbBckLt = ScaleColor( rgbBck, 40 ); COLORREF rgbBckDk = ScaleColor( rgbBck, -40 ); COLORREF rgbSelLt = ScaleColor( rgbSel, 80 ); COLORREF rgbSelDk = ScaleColor( rgbSel, -120 ); COLORREF rgbSelTextLt = ScaleColor( rgbSelText, 80 ); COLORREF rgbSelTextDk = ScaleColor( rgbSelText, -150 ); COLORREF rgbBumpLt = ScaleColor( rgbBck, 120 ); COLORREF rgbBumpDk = ScaleColor( rgbBck, -120 ); COLORREF rgbText = rgbMenuText; COLORREF rgbTextLt = ScaleColor( rgbBck, 100 ); COLORREF rgbTextDk = ScaleColor( rgbBck, -100 ); if ( GetColorAvg( rgbSel ) > 128 ) { COLORREF swap = rgbSelTextLt; rgbSelTextLt = rgbSelTextDk; rgbSelTextDk = swap; } // end if // What font does the user want for menu's? NONCLIENTMETRICS info; info.cbSize = sizeof(info); SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( info ), &info, 0 ); // Check for empty menu if ( m_mitems.Size() == 0 ) { COLORREF rgbEmptyLt = ScaleColor( rgbBck, 120 ); COLORREF rgbEmptyDk = ScaleColor( rgbBck, -120 ); if ( GetColorAvg( rgbBck ) < 128 ) { COLORREF swap = rgbEmptyLt; rgbEmptyLt = rgbEmptyDk; rgbEmptyDk = swap; } // end if RECT t; CopyRect( &t, pRect ); text.SetWeight( FW_BOLD ); text.SetFont( &info.lfMenuFont ); text.SetFlags( DT_SINGLELINE | DT_CENTER | DT_VCENTER ); // Make text look recessed OffsetRect( &t, -1, -1 ); text.SetColor( rgbEmptyDk ); text.DrawText( hDC, EMPTY_STR, &t ); OffsetRect( &t, 1, 1 ); text.SetColor( rgbEmptyLt ); text.DrawText( hDC, EMPTY_STR, &t ); } // end if // This kinda bites, but we need to know how far to offset the text BOOL islots = 0; LPMITEMINFO pmi = NULL; while( islots < 2 && ( pmi = (LPMITEMINFO)m_mitems.GetNext( pmi ) ) != NULL ) { // Do we need both icon slots? if ( pmi->icon != NULL && pmi->b != NULL ) islots = 2; // Do we have one islot already? else if ( islots < 1 ) { if ( pmi->icon != NULL ) islots = 1; else if ( pmi->b != NULL && m_hCheck == NULL && m_hUncheck == NULL ) islots = 1; } // end else if } // end while // The icon size long iconsize = m_th - 4; // Draw each item pmi = NULL; while( ( pmi = (LPMITEMINFO)m_mitems.GetNext( pmi ) ) != NULL && x < pRect->right && y < pRect->bottom ) { // Set base coords bx = x; by = y; if ( *pmi->name != NULL ) { POINT pt; GetCursorPos( &pt ); ScreenToClient( &pt ); // Is this item being selected? BOOL bSelected = FALSE; RECT hl; hl.left = pRect->left + 3; hl.right = pRect->right - 4; hl.top = by; hl.bottom = by + m_th; // if ( pt.x > hl.left && pt.x < hl.right && // pt.y > hl.top && pt.y < hl.bottom ) // Add for toolbar if ( pmi->toolbar != NULL && pmi->toolbar->GetNumButtons() ) hl.left += pmi->toolbar->GetWidth(); if ( pmi == m_itemover ) { bSelected = TRUE; // HPEN whitepen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) ); // HPEN dkgraypen = CreatePen( PS_SOLID, 1, RGB( 50, 50, 50 ) ); HPEN whitepen = CreatePen( PS_SOLID, 1, rgbLightPen ); HPEN dkgraypen = CreatePen( PS_SOLID, 1, rgbDarkPen ); HPEN oldpen = (HPEN)SelectObject( hDC, whitepen ); // Draw white line MoveToEx( hDC, hl.right, hl.top, NULL ); LineTo( hDC, hl.right, hl.bottom ); LineTo( hDC, hl.left, hl.bottom ); // Draw dark gray line SelectObject( hDC, dkgraypen ); MoveToEx( hDC, hl.right, hl.top, NULL ); LineTo( hDC, hl.left, hl.top ); LineTo( hDC, hl.left, hl.bottom ); SelectObject( hDC, oldpen ); DeleteObject( whitepen ); DeleteObject( dkgraypen ); // InflateRect( &hl, -1, -1 ); hl.left += 1; hl.top += 1; // GradientFill( hDC, &hl, RGB( 170, 170, 190 ), RGB( 110, 110, 110 ) ); CGrDC::VertGradientFill( hDC, &hl, rgbSelLt, rgbSelDk ); /* HBRUSH brush = CreateSolidBrush( RGB( 120, 120, 120 ) ); FillRect( hDC, &hl, brush ); DeleteObject( brush ); */ } // end if // Draw toolbar if ( pmi->toolbar != NULL && pmi->toolbar->GetNumButtons() ) { pmi->toolbar->SetHeight( m_th ); RECT tbar; SetRect( &tbar, bx, by, bx + pmi->toolbar->GetWidth(), by + pmi->toolbar->GetHeight() ); if ( bFirst ) pmi->toolbar->CreateToolTips( GetSafeHwnd(), &tbar ); pmi->toolbar->SetMessageTarget( GetSafeHwnd(), WM_MENUCMD ); pmi->toolbar->Draw( GetSafeHwnd(), hDC, &tbar ); bx += pmi->toolbar->GetWidth(); } // end if RECT t; // Calc text box t.left = bx + 4; t.left += islots * iconsize; t.right = pRect->right; t.top = by; t.bottom = by + m_th; // Draw Check if ( pmi->b != NULL ) { RECT icon; SetRect( &icon, bx + 2, by + 2, bx + 2 + iconsize, by + 2 + iconsize ); if ( *pmi->b != FALSE ) { if ( bSelected && m_hHotCheck != NULL ) CGrDC::DrawIcon( hDC, &icon, m_hHotCheck ); // DrawIconEx( hDC, bx + 2, by + 2, m_hHotCheck, iconsize, iconsize, 0, 0, DI_NORMAL ); else if ( m_hCheck != NULL ) CGrDC::DrawIcon( hDC, &icon, m_hCheck ); // DrawIconEx( hDC, bx + 2, by + 2, m_hCheck, iconsize, iconsize, 0, 0, DI_NORMAL ); } // end if else { if ( bSelected && m_hHotUncheck != NULL ) CGrDC::DrawIcon( hDC, &icon, m_hHotUncheck ); // DrawIconEx( hDC, bx + 2, by + 2, m_hHotUncheck, iconsize, iconsize, 0, 0, DI_NORMAL ); else if ( m_hUncheck != NULL ) CGrDC::DrawIcon( hDC, &icon, m_hUncheck ); // DrawIconEx( hDC, bx + 2, by + 2, m_hUncheck, iconsize, iconsize, 0, 0, DI_NORMAL ); } // end else } // end if // Draw icon if ( pmi->icon != NULL ) { long xoff = 2; xoff += iconsize * ( islots - 1 ) + 1; // DrawIconEx( hDC, x + xoff, y + 2, pmi->icon, // 16, 16, 0, 0, DI_NORMAL ); DrawIconEx( hDC, bx + xoff, by + 2, pmi->icon, iconsize, iconsize, 0, 0, DI_NORMAL ); } // end if // Setup the text object text.SetFlags( DT_SINGLELINE | DT_VCENTER ); if ( bSelected ) { text.SetWeight( FW_BOLD ); text.SetFont( &info.lfMenuFont ); // Make text look recessed OffsetRect( &t, -1, -1 ); // text.SetColor( RGB( 0, 0, 0 ) ); text.SetColor( rgbSelTextDk ); text.DrawText( hDC, pmi->name, &t ); OffsetRect( &t, 1, 1 ); text.SetColor( rgbSelTextLt ); } // end if else { // text.SetItalic( FALSE ); text.SetWeight( FW_BOLD ); text.SetFont( &info.lfMenuFont ); // text.SetFont( TFONTSIZE, TFONTTYPE ); // text.SetColor( RGB( 0, 50, 128 ) ); text.SetColor( rgbText ); } // end else // else text.SetColor( rgbText ); // text.SetColor( RGB( 0, 50, 128 ) ); text.DrawText( hDC, pmi->name, &t ); // Draw sub menu indicator if ( pmi->submenu != NULL ) { // Do we have a tick mark icon? if ( m_hTick != NULL ) { RECT ic; SetRect( &ic, t.right - 18, t.top + 5, t.right - 8, t.bottom - 7 ); // Colorize tick icon HICON hMono = NULL; if ( !pmi->submenu->IsEmpty() ) hMono = CGrDC::CreateMonoChromeIcon( m_hTick, GetSysColor( COLOR_ACTIVECAPTION ) ); else hMono = CGrDC::CreateMonoChromeIcon( m_hTick, GetSysColor( COLOR_INACTIVECAPTION ) ); // hMono = CGrDC::CreateMonoChromeIcon( m_hTick, rgbSel ); // else hMono = CGrDC::CreateMonoChromeIcon( m_hTick, rgbBck ); // Draw the icon if ( hMono != NULL ) { CGrDC::DrawIcon( hDC, &ic, hMono ); DestroyIcon( hMono ); } // end if } // end if else { HPEN whitepen = CreatePen( PS_SOLID, 1, rgbLightPen ); HPEN dkgraypen = CreatePen( PS_SOLID, 1, ScaleColor( rgbBck, -10 ) ); HPEN blackpen = CreatePen( PS_SOLID, 1, ScaleColor( rgbBck, -40 ) ); HPEN oldpen = (HPEN)SelectObject( hDC, whitepen ); HBRUSH mbrush; if ( !pmi->submenu->IsEmpty() ) mbrush = CreateSolidBrush( rgbBck ); else mbrush = CreateSolidBrush( ScaleColor( rgbBck, -80 ) ); HBRUSH oldbrush = (HBRUSH)SelectObject( hDC, mbrush ); POINT pts[ 3 ]; pts[ 0 ].x = t.right - 14; pts[ 0 ].y = t.top + 5; pts[ 1 ].x = t.right - 14; pts[ 1 ].y = t.bottom - 7; pts[ 2 ].x = t.right - 8; pts[ 2 ].y = t.top + ( ( t.bottom - t.top ) / 2 ); // Draw the shape Polygon( hDC, pts, sizeof( pts ) / sizeof( POINT ) ); // Draw border MoveToEx( hDC, pts[ 0 ].x, pts[ 0 ].y, NULL ); LineTo( hDC, pts[ 1 ].x, pts[ 1 ].y ); SelectObject( hDC, blackpen ); LineTo( hDC, pts[ 2 ].x, pts[ 2 ].y ); SelectObject( hDC, dkgraypen ); LineTo( hDC, pts[ 0 ].x, pts[ 0 ].y ); // Release drawing objects SelectObject( hDC, oldpen ); DeleteObject( whitepen ); DeleteObject( dkgraypen ); DeleteObject( blackpen ); SelectObject( hDC, oldbrush ); DeleteObject( mbrush ); } // end if } // end if // Next menu item position y += m_th; } // end if else // separator { // HPEN whitepen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) ); // HPEN dkgraypen = CreatePen( PS_SOLID, 1, RGB( 50, 50, 50 ) ); HPEN whitepen = CreatePen( PS_SOLID, 1, rgbBumpLt ); HPEN dkgraypen = CreatePen( PS_SOLID, 1, rgbBumpDk ); HPEN oldpen = (HPEN)SelectObject( hDC, whitepen ); // Draw white line MoveToEx( hDC, bx + 2, by + 2, NULL ); LineTo( hDC, ( pRect->right - pRect->left ) - 2, by + 2 ); // Draw dark gray line SelectObject( hDC, dkgraypen ); MoveToEx( hDC, bx + 2, by + 3, NULL ); LineTo( hDC, ( pRect->right - pRect->left ) - 2, by + 3 ); SelectObject( hDC, oldpen ); DeleteObject( whitepen ); DeleteObject( dkgraypen ); y += 6; } // end else } // end while return TRUE; }
BOOL CItemList::DrawItem( DWORD i, HDC hDC, LPRECT pRect) { CText text; RECT rect; LPLISTSUBITEMINFO plsii = m_pIndex[ i ]->head; LPHEADERITEMINFO phii = NULL; text.SetFlags( DT_SINGLELINE | DT_VCENTER ); text.SetColor( m_rgbText ); // Use bold text for group names if ( ( m_pIndex[ i ]->flags & LIF_GROUP ) != 0 ) text.SetWeight( FW_BOLD ); // Rect CopyRect( &rect, pRect ); InflateRect( &rect, 0, -1 ); if ( ( m_pIndex[ i ]->flags & LIF_SELECTED ) != 0 && ( m_pIndex[ i ]->flags & LIF_GROUP ) == 0 ) { CGrDC::VertGradientFill( hDC, &rect, m_rgbSelTop, m_rgbSelBottom ); } // end if // Adjust for horz scroll rect.left -= m_lHScroll; // rect.top += 1; BOOL bSpecialFont = TRUE; // Draw all items while ( ( phii = m_header.GetNext( phii ) ) != NULL && plsii != NULL && rect.left < pRect->right ) { // Set special font if ( plsii->pfont != NULL ) { bSpecialFont = TRUE; text.SetFont( plsii->pfont ); } // Set default font else if ( bSpecialFont ) { bSpecialFont = FALSE; text.SetFont( 16, "Arial" ); } if ( m_bGroups && ( m_pIndex[ i ]->flags & LIF_GROUP ) != 0 ) rect.right = pRect->right; else { // Calculate item width rect.right = rect.left + phii->width; if ( rect.right > pRect->right ) rect.right = pRect->right; } // end else if ( rect.right > pRect->left ) { // Fill in bck if needed if ( ( m_pIndex[ i ]->flags & LIF_SELECTED ) != 0 && ( m_pIndex[ i ]->flags & LIF_GROUP ) == 0 ) { if ( plsii->rgbbck != MAXDWORD ) { RECT b; CopyRect( &b, &rect ); InflateRect( &b, -2, -1 ); b.top++; b.right--; CGrDC::FillSolidRect( hDC, &b, plsii->rgbbck ); // COLORREF bottom = CGrDC::ScaleColor( plsii->rgbbck, -50 ); // CGrDC::GradientFill( hDC, &rect, plsii->rgbbck, bottom ); } // end if } // end if else { if ( plsii->rgbbck != MAXDWORD ) { RECT b; CopyRect( &b, &rect ); InflateRect( &b, -2, -1 ); b.top++; b.right--; CGrDC::FillSolidRect( hDC, &b, plsii->rgbbck ); // CGrDC::GradientFill( hDC, &rect, plsii->rgbbck, m_rgbSelBottom ); } // end if } // end else // Draw icon if needed if ( plsii->icon != NULL ) { DrawIconEx( hDC, rect.left + 2, rect.top + 2, plsii->icon, 16, 16, 0, NULL, DI_NORMAL ); rect.left += 17; } // end if if ( plsii->type == SIT_TEXT ) { rect.left += 3; // Did the user specify a color? if ( plsii->rgbtext != MAXDWORD ) text.SetColor( plsii->rgbtext ); // Is Item selected? else if ( ( m_pIndex[ i ]->flags & LIF_SELECTED ) != 0 && ( m_pIndex[ i ]->flags & LIF_GROUP ) == 0 ) text.SetColor( m_rgbSelText ); // Set default text color else text.SetColor( m_rgbText ); text.DrawText( hDC, (char*)plsii->data, &rect ); } // end if } // end if // Shift rect rect.left = rect.right; // Next sub-item plsii = plsii->pNext; } // end while return TRUE; }
BOOL CWinMenu::GetMenuRect(long x, long y, LPRECT pRect) { if ( pRect == NULL ) return FALSE; long w = 0; long h = 8; RECT rect; CText text; HDC hDC = ::GetDC( NULL ); // Punt if no dc if ( hDC == NULL ) return FALSE; m_tw = w; m_th = 20; // What font does the user want for menu's? NONCLIENTMETRICS info; info.cbSize = sizeof(info); SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( info ), &info, 0 ); text.SetWeight( FW_BOLD ); text.SetFont( &info.lfMenuFont ); // Handle NULL menu if ( m_mitems.Size() == 0 ) { // Get size of empty string SetRect( &rect, 0, 0, 10, 10 ); // text.SetFlags( DT_SINGLELINE | DT_CENTER | DT_VCENTER ); text.SetFlags( 0 ); text.CalcRect( hDC, EMPTY_STR, &rect ); // Save text params w = ( rect.right - rect.left ); if ( rect.bottom - rect.top > 20 ) { m_th = rect.bottom - rect.top; h += m_th; } else h += 20; } // end if LPMITEMINFO pmi = NULL; while( ( pmi = (LPMITEMINFO)m_mitems.GetNext( pmi ) ) != NULL ) { if ( *pmi->name != NULL ) { // Acc. width SetRect( &rect, 0, 0, 10, 10 ); // text.SetFlags( DT_SINGLELINE | DT_CENTER | DT_VCENTER ); text.SetFlags( DT_SINGLELINE | DT_VCENTER ); text.CalcRect( hDC, pmi->name, &rect ); RECT rrect; if ( *pmi->rtext != 0 ) { SetRect( &rect, 0, 0, 10, 10 ); text.CalcRect( hDC, pmi->rtext, &rrect ); } // end if else ZeroMemory( &rrect, sizeof( rrect ) ); long cw = ( ( rect.right - rect.left ) + MARGIN ); // Add toolbar size if ( pmi->toolbar != NULL ) cw += pmi->toolbar->GetWidth(); // Track width if ( cw > w ) w = cw; if ( ( rect.bottom - rect.top ) > 20 ) { m_th = rect.bottom - rect.top; h += m_th; } // end if else h += 20; } // end if else h += 6; } // end while // Correct width w += ( m_th * 3 ); if ( w < 80 ) w = 80; m_tw = w; ::ReleaseDC( NULL, hDC ); pRect->left = x; pRect->right = x + w; pRect->top = y; pRect->bottom = y + h; // Correct if drifting offscreen if ( m_bCorrectOverhang ) { long ox = 0, oy = 0; if ( pRect->left < 10 ) ox = 10 - pRect->left; if ( pRect->top < 10 ) oy = 10 - pRect->top; // Offset rect if needed if ( ox || oy ) OffsetRect( pRect, ox, oy ); } // end if return TRUE; }