Ich brauche für einen Projekt Farbige Buttons, deren farbe beim Clicken sich ändern.
dazu habe ich mir eine Classe "CColorBox" vom Codeproject.com runtergeladen und versucht sie für meine Bedürfnisse einzupassen.
CColorBox: beim Clicken auf Button öffnet sich die Farbepallete und mann kann eine farbe aussuchen.
was ich will: ich habe Farben definiert in ein switch anweisung.
jedes mal wenn ich auf einen button clicke lese ich seine Farbe , Vergleiche es, und wähle die Nächste farbe für den button.
bool CColorBox::SelectColor()
{
COLORREF SelecButton = ::GetSysColor(COLOR_BTNFACE);
switch (SelecButton){
case RGB(128,255,0): SetColor(RGB(128,128,0));break;
case RGB(128,128,0): SetColor(RGB(0,128,255));break ;
case RGB(0,128,255): SetColor(RGB(128,255,0));break ;
default: SetColor(RGB(128,255,0));}
return FALSE;
}
das Problem ich kann die Farbe nur ein Mal ändern. ich nehme an ich muss das DrawItem zwingen? wie mache ich dies:
void CColorBox:
rawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CClientDC dc(this); // device context for painting
CRect rect, ignoreRect;
GetClientRect(&rect);
//First, fill with background. Don't overwrite the button
ignoreRect = rect;
ignoreRect.DeflateRect(2, 2);
dc.SaveDC();
dc.ExcludeClipRect(&ignoreRect);
dc.FillSolidRect(&rect, ::GetSysColor(COLOR_BTNFACE));
/*/Is in focus?*/
if
:GetFocus() == m_hWnd)
{
//Draw focus rect two times. This is necessary to make the focus
//rect visible when using a high contrast color scheme in windows
COLORREF old = dc.SetBkColor(GetColor());
dc.DrawFocusRect(&rect);
dc.SetBkColor
:GetSysColor(COLOR_BTNTEXT));
dc.DrawFocusRect(&rect);
dc.SetBkColor(old);
}
dc.RestoreDC(-1);
rect.DeflateRect(2, 2);
ignoreRect.DeflateRect(1, 1);
//Draw selection rect, or background color if no selection
{
COLORREF rgbBorder = GetSysColor (COLOR_3DDKSHADOW);
// if(!m_selected)
// rgbBorder = GetSysColor (COLOR_BTNFACE);
CPen borderPen(PS_SOLID, 1, rgbBorder);
CPen* pold = dc.SelectObject(&borderPen);
dc.MoveTo(rect.TopLeft());
dc.LineTo(rect.right-1, rect.top);
dc.LineTo(rect.right-1, rect.bottom-1);
dc.LineTo(rect.left, rect.bottom-1);
dc.LineTo(rect.left, rect.top);
dc.SelectObject(pold);
}
//Shrink the rect, 1 pixel on all sides.
rect.DeflateRect(1,1);
//We want to ignore the area inside the border...
ignoreRect = rect;
ignoreRect.DeflateRect(2, 2);
//Draw border
UINT uFrameCtrl = DFCS_BUTTONPUSH;
//Is button pushed?
if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)
uFrameCtrl |= DFCS_PUSHED;
//Disabled?
if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED)
uFrameCtrl |= DFCS_INACTIVE;
//Draw the frame, but ignore the area inside
dc.SaveDC();
dc.ExcludeClipRect(&ignoreRect);
dc.DrawFrameControl(&rect, DFC_BUTTON, uFrameCtrl);
dc.RestoreDC(-1);
//Draw color
rect.DeflateRect(2,2);
dc.FillSolidRect(&rect, m_color);
//Draw text
// Get caption text
CString strCaption;
GetWindowText (strCaption);
//Any text to draw?
if(!strCaption.IsEmpty())
{
int oldTextColor = dc.SetTextColor(COLOR_BTNTEXT);
// Determine drawing format
DWORD dwFormat = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_CENTER;
// Determine dimensions of caption
CRect rectCaption = rect;
//Make push effect by shrinking the rect
if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)
rectCaption.DeflateRect(0, 0, -2, -2);
//Draw text transparent...
int oldMode = dc.SetBkMode(TRANSPARENT);
//...with the original font
CFont* oldFont = dc.SelectObject(GetFont());
//OK, draw the text...
if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED)
{
//Draw like this if disabled.
rectCaption.OffsetRect(1, 1);
dc.SetTextColor(GetSysColor (COLOR_3DHILIGHT));
dc.DrawText(strCaption, &rectCaption, dwFormat);
rectCaption.OffsetRect(-1,-1);
dc.SetTextColor(GetSysColor (COLOR_GRAYTEXT));
dc.DrawText(strCaption, &rectCaption, dwFormat);
}
else
dc.DrawText(strCaption,&rectCaption,dwFormat );
//Set some stuff back
dc.SelectObject(oldFont);
dc.SetBkMode(oldMode);
dc.SetTextColor(oldTextColor);
}
}
Danke
dazu habe ich mir eine Classe "CColorBox" vom Codeproject.com runtergeladen und versucht sie für meine Bedürfnisse einzupassen.
CColorBox: beim Clicken auf Button öffnet sich die Farbepallete und mann kann eine farbe aussuchen.
was ich will: ich habe Farben definiert in ein switch anweisung.
jedes mal wenn ich auf einen button clicke lese ich seine Farbe , Vergleiche es, und wähle die Nächste farbe für den button.
bool CColorBox::SelectColor()
{
COLORREF SelecButton = ::GetSysColor(COLOR_BTNFACE);
switch (SelecButton){
case RGB(128,255,0): SetColor(RGB(128,128,0));break;
case RGB(128,128,0): SetColor(RGB(0,128,255));break ;
case RGB(0,128,255): SetColor(RGB(128,255,0));break ;
default: SetColor(RGB(128,255,0));}
return FALSE;
}
das Problem ich kann die Farbe nur ein Mal ändern. ich nehme an ich muss das DrawItem zwingen? wie mache ich dies:
void CColorBox:

{
CClientDC dc(this); // device context for painting
CRect rect, ignoreRect;
GetClientRect(&rect);
//First, fill with background. Don't overwrite the button
ignoreRect = rect;
ignoreRect.DeflateRect(2, 2);
dc.SaveDC();
dc.ExcludeClipRect(&ignoreRect);
dc.FillSolidRect(&rect, ::GetSysColor(COLOR_BTNFACE));
/*/Is in focus?*/
if

{
//Draw focus rect two times. This is necessary to make the focus
//rect visible when using a high contrast color scheme in windows
COLORREF old = dc.SetBkColor(GetColor());
dc.DrawFocusRect(&rect);
dc.SetBkColor

dc.DrawFocusRect(&rect);
dc.SetBkColor(old);
}
dc.RestoreDC(-1);
rect.DeflateRect(2, 2);
ignoreRect.DeflateRect(1, 1);
//Draw selection rect, or background color if no selection
{
COLORREF rgbBorder = GetSysColor (COLOR_3DDKSHADOW);
// if(!m_selected)
// rgbBorder = GetSysColor (COLOR_BTNFACE);
CPen borderPen(PS_SOLID, 1, rgbBorder);
CPen* pold = dc.SelectObject(&borderPen);
dc.MoveTo(rect.TopLeft());
dc.LineTo(rect.right-1, rect.top);
dc.LineTo(rect.right-1, rect.bottom-1);
dc.LineTo(rect.left, rect.bottom-1);
dc.LineTo(rect.left, rect.top);
dc.SelectObject(pold);
}
//Shrink the rect, 1 pixel on all sides.
rect.DeflateRect(1,1);
//We want to ignore the area inside the border...
ignoreRect = rect;
ignoreRect.DeflateRect(2, 2);
//Draw border
UINT uFrameCtrl = DFCS_BUTTONPUSH;
//Is button pushed?
if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)
uFrameCtrl |= DFCS_PUSHED;
//Disabled?
if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED)
uFrameCtrl |= DFCS_INACTIVE;
//Draw the frame, but ignore the area inside
dc.SaveDC();
dc.ExcludeClipRect(&ignoreRect);
dc.DrawFrameControl(&rect, DFC_BUTTON, uFrameCtrl);
dc.RestoreDC(-1);
//Draw color
rect.DeflateRect(2,2);
dc.FillSolidRect(&rect, m_color);
//Draw text
// Get caption text
CString strCaption;
GetWindowText (strCaption);
//Any text to draw?
if(!strCaption.IsEmpty())
{
int oldTextColor = dc.SetTextColor(COLOR_BTNTEXT);
// Determine drawing format
DWORD dwFormat = DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_CENTER;
// Determine dimensions of caption
CRect rectCaption = rect;
//Make push effect by shrinking the rect
if ((lpDrawItemStruct->itemState & ODS_SELECTED) == ODS_SELECTED)
rectCaption.DeflateRect(0, 0, -2, -2);
//Draw text transparent...
int oldMode = dc.SetBkMode(TRANSPARENT);
//...with the original font
CFont* oldFont = dc.SelectObject(GetFont());
//OK, draw the text...
if ((lpDrawItemStruct->itemState & ODS_DISABLED) == ODS_DISABLED)
{
//Draw like this if disabled.
rectCaption.OffsetRect(1, 1);
dc.SetTextColor(GetSysColor (COLOR_3DHILIGHT));
dc.DrawText(strCaption, &rectCaption, dwFormat);
rectCaption.OffsetRect(-1,-1);
dc.SetTextColor(GetSysColor (COLOR_GRAYTEXT));
dc.DrawText(strCaption, &rectCaption, dwFormat);
}
else
dc.DrawText(strCaption,&rectCaption,dwFormat );
//Set some stuff back
dc.SelectObject(oldFont);
dc.SetBkMode(oldMode);
dc.SetTextColor(oldTextColor);
}
}
Danke