beim Clicken auf farbige Button farbe ändern

rano

Mitglied
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::DrawItem(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
 
Wenn das DrawItem in OnPaint oder OnDrawItem aufgerufen wird, sollte nach dem SetColor (oder noch besser, IN SetColor) ein Invalidate aufrufen. Dann wird der Button neu gezeichnet.
 
Danke Endurian.

Invalidate(FALSE) habe ich schon und zwar so SelectColor Ruft SetColor() und SetColor() Ruft ein Redraw() wo Die Invalidate eingefügt ist:

//Redraws color box
void CColorBox::Redraw()
{
Invalidate(FALSE);

}

//Set color
void CColorBox::SetColor(const COLORREF newColor)
{
//Set color
m_color=newColor;
Redraw();

}

trotzdem funktioniet nicht
 
Argh, ich Hirn.

Das Problem liegt in deiner SelectColor-Routine:

Du möchtest vermutlich die aktuelle Farbe des Buttons holen, holst aber immer die selbe Default-Systemfarbe für Button-Oberflächen.

COLORREF SelecButton = ::GetSysColor(COLOR_BTNFACE);

Deshalb springt er in deinem Switch/Case immer denselben Farbwert an. Benutze statt der Zeile:

COLORREF SelectButton = m_color;

In m_color wird die aktuelle Farbe des Buttons gespeichert, dann müsste das mit dem Weiterwechseln auch Klappen.

Nächstesmal lese ich mir die Frage richtig durch ;)
 
Danke für die Erklärung. Stimmt ich habe die GetSysColor(COLOR_BTNFACE); Falsch eingesetzt.

DANKE Danke Danke
 

Neue Beiträge

Zurück