This article uses the vc6.0 MFC program to implement a custom multi-state button. In vc9.0 (vs2008), remove # DEFINE _ win32_winnt 0x0400 from the stdafx. h file (with a warning ).
You can modify the bitmap resource by yourself because it is only an example and you do not pay attention to the interface.
Three buttons are introduced:
1) Three status buttons
Place the cursor over the button, place the cursor outside the button, and press the button.
2) Six status buttons
On the basis of 1), three situations are added for obtaining the focus.
3) built-in cbitmapbutton class of MFC
There are four statuses: Up, down, focus, and disabled. The control style is different and the number of States is different. For details, refer to msdn.
The code can be downloaded here:
Http://download.csdn.net/source/986965
(1) Three status buttons
1) define the subclass cyctbitmapbutton inherited from cbutton.
2) Three bitmap resources are required in three states.
Install and uninstall bitmap resources:
Int cyctbitmapbutton: Init () <br/>{< br/> // (after the window is created) initialization </P> <p> m_hin =: loadbitmap (:: afxGetInstanceHandle (), makeintresource (idb_bitmap_in); <br/> m_hout =: loadbitmap (: callback (), makeintresource (idb_bitmap_out); <br/> m_hdown = :: loadbitmap (: AfxGetInstanceHandle (), makeintresource (idb_bitmap_down); </P> <p> assert (m_hin! = NULL); <br/> assert (m_hout! = NULL); <br/> assert (m_hdown! = NULL); </P> <p> // setbuttonstyle (bs_bitmap | getbuttonstyle (); <br/> modifystyle (0, bs_bitmap ); // added the bs_bitmap style <br/> setbitmap (m_hout); </P> <p> return 0; <br/>}</P> <p> void cyctbitmapbutton :: ondestroy () <br/>{< br/> cbutton: ondestroy (); </P> <p> // uninstall bitmap resources <br/> # ifdef _ debug <br/> assert (0! = Deleteobject (m_hin); <br/> assert (0! = Deleteobject (m_hout); <br/> assert (0! = Deleteobject (m_hdown); <br/> # else <br/> deleteobject (m_hin); <br/> deleteobject (m_hout); <br/> deleteobject (m_hputdown ); <br/> # endif <br/>}
3) initialize the button
Call the init () function after window initialization. The Boolean variable m_fisinit ensures that the button is initialized only once.
Void cyctbitmapbutton: presubclasswindow () <br/>{< br/> // initialization <br/> If (! M_fisinit) <br/>{< br/> // afxmessagebox (_ T ("cyctbitmapbutton: presubclasswindow"); <br/> Init (); <br/> m_fisinit = true; <br/>}</P> <p> cbutton: presubclasswindow (); <br/>}</P> <p> int cyctbitmapbutton: oncreate (maid) <br/>{< br/> If (cbutton: oncreate (lpcreatestruct) =-1) <br/> return-1; </P> <p> // initialization <br/> If (! M_fisinit) <br/>{< br/> // afxmessagebox (_ T ("cyctbitmapbutton: oncreate"); <br/> Init (); <br/> m_fisinit = true; <br/>}< br/> return 0; <br/>}
4) process the mouse response function (this is the key)
Four types of mouse messages wm_mousemove, wm_lbuttondown, wm_lbuttonup, and wm_mouseleave are processed:
Void cyctbitmapbutton: onmousemove (uint nflags, cpoint point) <br/>{< br/> If (m_mousestate.getcurstate () = _ mouse_out) <br/>{< br/> setbitmap (m_hin); <br/> return; <br/>}</P> <p> // wm_mouseleave event triggered when the mouse leaves <br/> trackmouseevent tme; <br/> tme. cbsize = sizeof (TME); <br/> tme. dwflags = tme_leave; <br/> tme. hwndtrack = m_hwnd; <br/> tme. dwhovertime = hover_default; <br/>: trackmouseevent (& TME); </P> <p> cbutton: onmousemove (nflags, point ); <br/>}</P> <p> void cyctbitmapbutton: onlbuttondown (uint nflags, cpoint point) <br/>{< br/> setbitmap (m_hdown ); </P> <p> cbutton: onlbuttondown (nflags, point); <br/>}</P> <p> void cyctbitmapbutton: onlbuttonup (uint nflags, cpoint point) <br/>{< br/> setbitmap (m_hin); </P> <p> cbutton: onlbuttonup (nflags, point ); <br/>}</P> <p> lresult cyctbitmapbutton: onmouseleave (wparam, lparam) <br/>{< br/> setbitmap (m_hout ); </P> <p> return 0; <br/>}
The wm_mouseleave message response ing is manually added.
Add a sentence before declare_message_map () in the header file:
Afx_msg lresult onmouseleave (wparam, lparam); // manually add
In the corresponding CPP file, add a sentence between begin_message_map and end_message_map:
On_message (wm_mouseleave, onmouseleave) // manually add
The wm_mouseleave message is generated by the trackmouseevent function. The message is triggered when the mouse leaves the button control.
The setbitmap function is defined as follows (see the source code for details ):
Hbitmap cyctbitmapbutton: setbitmap (hbitmap) <br/> {<br/> // set the bitmap of the button </P> <p> assert (m_hin = hbitmap | m_hout = hbitmap | m_hdown = hbitmap ); <br/> If (m_hin = hbitmap) <br/> m_mousestate.setcurstate (_ mouse_in); <br/> else if (m_hout = hbitmap) <br/> m_mousestate.setcurstate (_ mouse_out); <br/> else if (m_hdown = hbitmap) <br/> m_mousestate.setcurstate (_ mouse_down ); </P> <p> return cbutton: setbitmap (hbitmap); <br/>}
5) If you want to remove the dotted box of the button to get the focus, reload the wm_setfocus message and leave the function body blank.
(2) Six status buttons
Similar to (1.
(3) built-in cbitmapbutton class of MFC
It is easy to use. Load four bitmap Resources in the oninitdialog of the dialog box class:
// Initialize cbitmapbutton <br/> m_bitmapbutton.loadbitmaps (idb_bitmap_up, idb_bitmap_down2 <br/>, idb_bitmap_focus, idb_bitmap_disabled );
Conclusion: The multi-state button is mainly implemented using the trackmouseevent function. This document is just an example. You can also download the cbuttonst to see how it works. Download Area:
Http://search.download.csdn.net/search/cbuttonst