XP-style button design Author: Zheng Heng (lbird)
Download this article sample code
Many people in the forum are discussing how to write an XP-style interface. In fact, there is a design class library on the Internet, which can be used directly. But these ends are written by others, can it be converted into them? So the author studies these code, it is a bit :) Studies several controls, here is the simplest button control to be discussed together. This is the running effect of the program: Steps: 1. Create a new class CBUTTONXP 2 derived from CButton, and the PRESUBCLASSWINDOW () function is built, and the style of modify the button is self-drawn (OWNER): MODIFYSTYLE 0, BS_OWNERDRAW; 3, because the XP style button has the effect of mouse induction, when the mouse moves above the button, the color of the button will change. So you must track the mouse. When the mouse is moved above the button, the window will receive the WM_MOUSEMOVE message, but how can you know the mouse off button? Here we use TrackMouseEvent () API functions:
Bool TrackMouseevent (LPTRACKMOUSEEVENT LPEVENTTTRACK);
Parameters: typedef struct tagTRACKMOUSEEVENT {DWORD cbSize; // size of the structure DWORD dwFlags; // set TME_LEAVEHWND hwndTrack; // window handle to track the mouse DWORD dwHoverTime;} TRACKMOUSEEVENT, * LPTRACKMOUSEEVENT; may exit call the function specified window mouse Receive the WM_MouseLeave message when you receive. Add member variables: m_bover, initialized to False. m_bover = true is used to indicate the mouse in the button area. Add a WM_MOUSEMOVE message handler:
Void CButtonXP :: OnMousemove (uint nflags, cpoint point)
{
IF (M_BOVER == false)
{
// mouse above the button
m_bover = true;
// button redraw
INVALIDATERECT (NULL, FALSE);
// Track the mouse
/ / When the mouse leaves the button area, it will receive WM_MouseLeave, which calls onMouseout directly ()
TrackMouseEvent TME;
Tme.cbsize = sizeof (trackmouseevent);
Tme.dwflags = TME_LEVE;
Tme.dwhovertime = 0;
Tme.hwndtrack = m_hwnd;
:: TrackMouseEvent (& TME);
}
CButton :: OnMousemove (NFLAGS, POINT);
}
Add a member function onMouseout () and add a macro on_MAESSAGE (WM_MouseLeave, OnMouseout) between Begin_Message_Map (CButtonXP, CButton) and End_MESSAGE_MAP ()
Write the following code in OnMouseout ()
Void cbuttonxp :: onmouseout ()
{
/ / The mouse has left the button area
m_bover = false;
// Redraw button
INVALIDATERECT (NULL, FALSE);
}
4, add member functions mouseover ()
/ / Return to whether the mouse is in the button area
Bool cbuttonxp :: mouseover ()
{
Return M_BOVER;
}
5, last overload DrawItem (LPDrawItemstruct LPDIS)
Void CButtonXP :: DrawItem (LPDRAWItemstruct LPDIS) {
CDC * PDC = CDC :: fromHandle (LPDIS-> HDC);
CRECT RTCONTROL (LPDIS-> RCITEM);
CPEN PEN, * OLD_PEN;
CBRUSH brush, * old_brush;
CString strText;
HFONT HOLDFONT = (HFONT) PDC-> SelectObject ((hfont):: getStockObject (default_gui_font));
Uint State = lpdis-> itemstate;
IF (State & ODS_FOCUS)
{
RTControl.deflatectureRect (1, 1); // Have the focus rectangle becomes small
}
IF ((State & ODS_DISABED) ||
(! Mouseover () &&! (State & ODS_SELECTED)))))
{
// Ordinary state, disabled, with three cases of focus
Pen.createpen (ps_solid, 1, :: getsyscolor (color_3dshadow);
Brush.createsolidbrush (HLS_TRANSFORM (:: getSyscolor (Color_3dface), - 10, 0));
}
Else
{
ColorRef crborder = :: getsyscolor (color_highlight);
Pen.createpen (PS_SOLID, 1, CRBORDER);
IF (State & ODS_SELECTED)
{
// button press
Brush.createsolidbrush (HLS_TRANSFORM (CRBORDER, 50, -50);
PDC-> SetTextColor (RGB (240, 240, 240);
}
Else
{
// mouse in the area
Brush.createsolidbrush (HLS_TRANSFORM (CRBORDER, 80, -66);
PDC-> setTextColor (: getsyscolor (color_btntext));
}
}
IF (State & ODS_DISABED)
PDC-> setTextColor (: getSyscolor (color_graytext)); // Gray word: Disable status
Else IF (state & ods_selected)
PDC-> SetTextColor (RGB (240, 240, 240)); // White word: Push State
Else IF (Mouseover ())
PDC-> setTextColor (0); // Black word: thermal induction state
Else
PDC-> setTextColor (: getSyscolor (color_btntext)); // Black word: normal state
Old_brush = PDC-> SelectObject (& Brush);
Old_pen = PDC-> SelectObject (& Pen);
PDC-> Rectangle (RTControl);
PDC-> setbkmode (transparent);
GetWindowText (strText);
PDC-> DrawText (Strtext, RTControl, DT_SINGLINE | DT_CENTER | DT_VCENTER);
IF (State & ODS_FOCUS)
{
RTControl.deflateRect (3, 3);
PDC-> DrawFocusRect (RTControl);
}
PDC-> SelectObject (OLD_PEN); PDC-> SELECTOBJECT (OLD_BRUSH);
PDC-> SelectObject (HoldFont);
}
Another note is that you want to use TrackMouseEvent (), you must join header file Winuser.h and Extern "C" WinuseraPi Bool WinAPI TRACKMOUSEEVENT (LPTRACKMOUSEEVENT LPEVENTTRACK); this program is compiled in the Win98 Visual C 6.0 environment.