From: http://www.cnblogs.com/seacode/archive/2010/06/17/1759616.html
To modify the background color and text color of a cbutton button, you must use the self-painting method to re-draw the button. This can be achieved by defining a new button class based on the cbutton class. The specific implementation methods are as follows:
Method 1:
Add a new Class, Class Name: cbuttonex, base class: cbutton.
Add the following variables and function definitions to the header file cbuttonex. h:
PRIVATE:
Int m_style; // button shape (0-normal, 1-current, 2-pressed, 3-locked)
Bool B _inrect; // enter the cursor
Cstring m_strtext; // button text
Colorref m_forecolor; // text color
Colorref m_backcolor; // background color
Colorref m_lockforecolor; // The text color of the lock button
Crect m_butrect; // button size
Cfont * p_font; // font
Void drawbutton (CDC * PDC); // draw a normal button
// Interface function
Public:
Void settext (cstring Str );
Void setforecolor (colorref color); // sets the text color.
Void setbkcolor (colorref color); // sets the background color.
Void settextfont (INT fonthight, lpctstr fontname); // set the font
Initialize the variable in the cbuttonex. cpp constructor:
Cbuttonex: cbuttonex ()
{
M_style = 0; // button shape style
B _inrect = false; // enter the cursor flag
M_strtext = _ T (""); // button text (use the default text)
M_forecolor = RGB (0, 0); // text color (black)
M_backcolor = RGB (243,243,243); // background color (gray-white)
M_lockforecolor = getsyscolor (color_graytext); // The text color of the lock button
P_font = NULL; // font pointer
}
Use classwizard to add the following message functions:
Presubclasswindow ();
Drawitem ();
Onmousemove ();
Onlbuttondown ();
Onlbuttonup ();
Add in each functionCode:
Void cbuttonex: presubclasswindow ()
{
Modifystyle (0, bs_ownerdraw); // set the button property to a self-drawn style.
Cbutton: presubclasswindow ();
}
Presubclasswindow () is automatically executed before the button is created, so we can do some initial work in it. Here I only do one job, that is, to set the property of the button to "self-painted". In this way, you do not need to set the "owner draw" attribute after adding the button.
Void cbuttonex: drawitem (lpdrawitemstruct)
{
CDC * PDC = CDC: fromhandle (lpdrawitemstruct-> HDC );
M_butrect = lpdrawitemstruct-> rcitem; // obtain the button size
If (m_strtext.isempty ())
Getwindowtext (m_strtext); // get the button text
Int nsaveddc = PDC-> savedc ();
Verify (PDC );
Drawbutton (PDC); // draw button
PDC-> restoredc (nsaveddc );
}
The drawitem () function is a key function. The button is drawn here. It serves the onpaint () function in the dialog box and the ondraw () function in the view.
Here I have done three tasks: Getting button size, getting button text, and Drawing button. The painting is completed in the custom function drawbutton. The following is the rendering process:
Void cbuttonex: drawbutton (CDC * PDC)
{
// Adjust the status
If (m_style = 3) m_style = 0;
If (getstyle () & ws_disabled)
M_style = 3; // disabled
// Adjust the border color and text color based on the Status
Colorref bcolor, fcolor; // bcolor indicates the border color, and fcolor indicates the text color.
Switch (m_style)
{
Case 0: bcolor = RGB (192,192,192); fcolor = m_forecolor; break; // normal button
Case 1: bcolor = RGB (255,255,255); fcolor = m_forecolor; break; // when the mouse enters the button
Case 2: bcolor = RGB (192,192,192); fcolor = m_forecolor; break; // press the button
Case 3: bcolor = m_backcolor; fcolor = m_lockforecolor; break; // lock button
}
// Draw the button background
Cbrush brush;
Brush. createsolidbrush (m_backcolor); // specifies the background brush.
PDC-> SelectObject (& brush );
Cpen pen;
Pen. createpen (ps_solid, 1, bcolor );
PDC-> SelectObject (& pen );
PDC-> roundrect (& m_butrect, cpoint (5, 5); // draw a rounded rectangle
// Border when the draw button is pressed
If (m_style! = 2)
{
Crect rect;
Rect. setrect (m_butrect.left + 2, m_butrect.top + 1, m_butrect.right, m_butrect.bottom );
PDC-> drawedge (& rect, bdr_raisedinner, bf_rect); // draw a border
}
// Draw button text
PDC-> settextcolor (fcolor); // draw text
PDC-> setbkmode (transparent );
PDC-> drawtext (m_strtext, & m_butrect, dt_singleline | dt_center
| Dt_vcenter | dt_end_ellipsis );
// Draw a dotted box with a focus button
If (getfocus () = This)
{
Crect rect;
Rect. setrect (m_butrect.left + 3, m_butrect.top + 2, m_ButRect.right-3, m_ButRect.bottom-2 );
PDC-> drawfocusrect (& rect); // draw a dashed box with focus
}
}
The m_style variable represents the current button status. The value is 0-normal, 1-current, 2-press, and 3-lock. The border color and text color of a button are different in different States. The m_style value is modified in the mouse response function.
Drawing is mainly done by using the drawing functions of the CDC class. Pay attention to the differences in m_style values.
Void cbuttonex: onmousemove (uint nflags, cpoint point)
{
If (! B _inrect | getcapture ()! = This) // enter the mouse button
{
B _inrect = true; // set the entry flag
Setcapture (); // capture the mouse
M_style = 1; // set the button status
Invalidate (); // redraw button
}
Else
{
If (! M_butrect.ptinrect (point) // click the left button
{
B _inrect = false; // clear the entry flag
Releasecapture (); // release the captured mouse
M_style = 0; // set the button status
Invalidate (); // redraw button
}
}
Cbutton: onmousemove (nflags, point );
}
Onmousemove () is a function used to move the cursor over a message. B _inrect is a flag. True indicates that the mouse pointer enters the button area. Capture the mouse and send the mouse command to the button. When the mouse pointer leaves the button, you need to clear the B _inrect mark and release the captured mouse so that other windows can receive the mouse command.
The invalidate () function is used to update the button. It automatically calls the drawitem () function to redraw the button.
The purpose of setting the condition is to update the button only when the mouse pointer enters the button and leaves the button, so as to prevent the mouse from blinking when moving the button.
Void cbuttonex: onlbuttondown (uint nflags, cpoint point)
{
M_style = 2;
Invalidate (); // redraw button
Cbutton: onlbuttondown (nflags, point );
}
The onlbuttondown () function is the message function when you click the left mouse button. Here, you only need to redraw the button. The specific click response should be carried out in the dialog box or view with the button.
Void cbuttonex: onlbuttonup (uint nflags, cpoint point)
{
M_style = 1;
Invalidate (); // redraw button
Cbutton: onlbuttonup (nflags, point );
}
The onlbuttonup () function is the message function that appears when you click the left mouse button. This is just a re-drawing button, which makes the button different when it is pressed and popped up, so that the button looks dynamic.
The interface function is an interface that uses buttons defined by the cbuttonex class to modify the color, Font, And button text. It consists of the following functions:
// Set button text
Void cbuttonex: settext (cstring Str)
{
M_strtext = _ T ("");
Setwindowtext (STR );
}
// Set the text color
Void cbuttonex: setforecolor (colorref color)
{
M_forecolor = color;
Invalidate ();
}
// Set the background color
Void cbuttonex: setbkcolor (colorref color)
{
M_backcolor = color;
Invalidate ();
}
// Set the font (font height and font name)
Void cbuttonex: settextfont (INT fonthight, lpctstr fontname)
{
If (p_font) delete p_font; // Delete the old font
P_font = new cfont;
P_font-> createpointfont (fonthight, fontname); // create a new font
Setfont (p_font); // set the font
}
Because the new font is generated by new and must be explicitly recycled, this work can be done in the destructor of the cbuttonex class:
Cbuttonex ::~ Cbuttonex ()
{
If (p_font) delete p_font; // Delete the font
}
In this way, you can set the color and font of the button class. In use, place a button in the dialog box, use classwizard to add control variables, and set the variable type to cbuttonex. Then, you can use this variable to call the interface function to set the button color and font.
The tests above are too complicated. Another type is generated.
//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// //////
Method 2:
Add the wm_drawitem message processing function of the DLG class
Void cbtncolordlg: ondrawitem (INT nidctl, lpdrawitemstruct)
{
// Todo: add your message handler code here and/or call default
If (nidctl = idc_button1) // checking for the button
{
Cdc dc;
Rect;
DC. Attach (lpdrawitemstruct-> HDC); // get the button DC to CDC
Rect = lpdrawitemstruct-> rcitem; // store the button rect to our local rect.
DC. draw3drect (& rect, RGB (255,255,255), RGB (, 0 ));
DC. fillsolidrect (& rect, RGB (100,100,255); // here you can define the required color to appear on the button.
Uint state = lpdrawitemstruct-> itemstate; // This defines the State of the push button either pressed or not.
If (State & ods_selected ))
{
DC. drawedge (& rect, edge_sunken, bf_rect );
}
Else
{
DC. drawedge (& rect, edge_raised, bf_rect );
}
DC. setbkcolor (RGB (100,100,255); // setting the text background color
DC. settextcolor (RGB (255, 0, 0); // setting the text color
Tchar buffer [max_path]; // to store the caption of the button.
Zeromemory (buffer, max_path); // intializing the buffer to zero
: Getwindowtext (lpdrawitemstruct-> hwnditem, buffer, max_path); // get the caption of Button window
DC. drawtext (buffer, & rect, dt_center | dt_vcenter | dt_singleline); // redraw the caption of Button window
DC. Detach (); // detach the button DC
}
Cdialog: ondrawitem (nidctl, lpdrawitemstruct );
}