MFC button cxpbutton class, the code reading is quite good

Source: Internet
Author: User

When operating with MFC, we often complain that the MFC interface is inferior to other frameworks or languages, such as VB and C #. In the face of the constant updating of MS systems, we are also increasingly pursuing the visual effects of software. For example, we will prefer the glass effects under win7 and it looks very dazzling.

When I was in contact with MFC, I really couldn't help admiring the bulider of MFC, because he put the previous Win32 C Programming (note that there is no object-oriented in it) it has been organically integrated with C ++ (oo is coming soon), so that we can focus more on the functional design of the software, reduces the complexity of the Program (sincerely admire those programmers who come to Win32 ).

Every day, there are new gains. Of course, they are not just about software. Because the lecturer recently taught us how to design our own U. In fact, this seems quite difficult and actually very difficult, but the lecturer said yes. Understanding the hardware architecture is only beneficial to our software colleagues.

On the topic.

The cxpbutton class is a very good button class, and the code reading is very simple, not very difficult, as long as we know something about Windows programming. There are not many difficulties, mainly in processing the mouse message. For example, when you move the mouse over the button but do not press it, what is the case when the mouse button is pressed, this must be reflected. Otherwise, human-computer interaction will suffer and the masses will not like it.

In addition, I think it is quite difficult to design art. Many people know what kind of things looks cool, but they do not know how to design them, it is the so-called unknown.

It is also difficult to read messages. The unfamiliar point is that wm_mouseleave and wm_mousehover mouse messages are not processed by Windows by default, however, they must be used in the Custom button process.

So you need to trigger them.

TRACKMOUSEEVENT tme;tme.cbSize = sizeof(tme);tme.hwndTrack = m_hWnd;tme.dwFlags = TME_LEAVE | TME_HOVER;tme.dwHoverTime = 1;m_bTracking = _TrackMouseEvent(&tme);

The above code is what we need. When you move the cursor over or out of the button area, two messages are triggered.

In cxpbutton, as long as we are proficient in using GDI (plus a little bit of artistic talent), we can make very cool buttons.

The source code is as follows:

# If! Defined (partition _) # define partition _ # If _ msc_ver> 1000 # pragma once # endif // _ msc_ver> 1000 // xpbutton. h: header file ////////////////////////////////////// //////////////////////////////////////// /// cxpbutton windowclass cxpbutton: public cbutton {// constructionpublic: cxpbutton (); // attribu Tesprotected: // The outer border cpen m_boundrypen of the button; // The inside border cpen m_insideboundrypenleft; cpen m_insideboundrypenright; cpen limit; // when the button gets the focus, the inside border of the button is cpen enabled; cpen m_insideboundrypentopsel; cpen m_insideboundrypenbottomsel; // the background color of the button, including valid and invalid cbrush m_fillactive; cbrush m_fillinactive; // The status bool m_bover of the button; // The cursor is located The value above the button is true, and the opposite is flasebool m_btracking; // The value is truebool m_bselected when the mouse is pressed but not released; // The value is truebool m_bfocus when the button is pressed; // when the button is the current focus, the value is true // operationspublic: // overrides // classwizard generated virtual function overrides // {afx_virtual (cxpbutton) protected: virtual void presubclasswindow (); //} afx_virtual // implementationpublic: Virtual void drawitem (lpdrawitemstruct); Virtual void dogradientfill (CD C * PDC, crect * rect); Virtual void drawinsideborder (CDC * PDC, crect * rect); Virtual ~ Cxpbutton (); // generated message map failed: // {afx_msg (cxpbutton) afx_msg void onmousemove (uint nflags, cpoint point); afx_msg lresult onmouseleave (wparam, lparam); afx_msg lresult onmousehover (wparam, lparam); //} afx_msgdeclare_message_map ()}; //////////////////////////////////////// ///////////////////////////////////////{ {afx_insert_location }}// Microsoft visu Al c ++ will insert additional declarations immediately before the previous line. # endif //! Defined (afx_xpbutton_h000044cd5b2a_756e_4939_9261_e0034e0f2def0000included _)

  

// Xpbutton. CPP: implementation file // # include "stdafx. H "# include" xpbutton. H "# include" resource. H "# ifdef _ debug # define new debug_new # UNDEF this_filestatic char this_file [] = _ file __; # endif ////////////////////////////////////// //////////////////////////////////////// /cxpbuttoncxpbutton:: cxpbutton () {m_boundrypen.createpen (ps_insideframe | ps_solid, 1, RGB (0, 0, 0); m_insideboundrypenleft.createpe N (ps_insideframe | ps_solid, 3, RGB (250,196, 88); Round (ps_insideframe | ps_solid, 3, RGB (251,202,106); Round (ps_insideframe | ps_solid, 2, RGB (252,210,121); m_insideboundrypenbottom.createpen (ps_insideframe | ps_solid, 2, RGB (229,151, 0); m_fillactive.createsolidbrush (RGB (223,222,236); m_fillinactive.createsolidbrush (RGB (222,223,236 ); Round (ps_insideframe | ps_solid, 3, RGB (153,198,252); Round (ps_insideframe | ps_solid, 2, RGB (162,201,255); Round (ps_insideframe | ps_solid, 3, RGB (162,189,252); m_insideboundrypenbottomsel.createpen (ps_insideframe | ps_solid, 2, RGB (162,201,255); m_bover = m_bselected = m_btracking = m_bfocus = f Alse;} cxpbutton ::~ Cxpbutton () {m_boundrypen.deleteobject (); values (); m_fillactive.deleteobject (); m_fillinactive.deleteobject (); values (); m_insideboundrypenrightsel.deleteobject (); m_insideboundrypenbottomse L. deleteobject ();} evaluate (cxpbutton, cbutton) // {afx_msg_map (cxpbutton) on_wm_mousemove () on_message (success, onmouseleave) on_message (wm_mousehover, onmousehover) //} afx_msg_mapend_message_map () //////////////////////////////////////// /// // cxpbutton message handlers // Add the owner draw attribute void cxpbutton:: presubclasswindow () {// todo: add your specialized cod E here and/or call the base classcbutton: presubclasswindow (); modifystyle (0, bs_ownerdraw);} void cxpbutton: onmousemove (uint nflags, cpoint point) {// todo: add your message handler code here and/or call defaultif (! M_btracking) {trackmouseevent tme; tme. cbsize = sizeof (TME); tme. hwndtrack = m_hwnd; tme. dwflags = tme_leave | tme_hover; tme. dwhovertime = 1; m_btracking = _ trackmouseevent (& TME);} cbutton: onmousemove (nflags, point);} lresult cxpbutton: onmouseleave (wparam, lparam) {m_bover = false; m_btracking = false; invalidaterect (null, false);/**/return 0;} lresult cxpbutton: onmousehover (wparam, lp Aram lparam) {m_bover = true; invalidaterect (null); Return 0;} void cxpbutton: drawitem (lpdrawitemstruct) {// obtain control information from lpdrawitemstruct crect rect = lpdrawitemstruct-> rcitem; CDC * PDC = CDC: fromhandle (lpdrawitemstruct-> HDC ); int nsavedc = PDC-> savedc (); uint state = lpdrawitemstruct-> itemstate; point pt; tchar strtext [max_path + 1] = l "I Love You ";:: getwindowtext (m_hwnd, strtext, max_path);/* obtain the primary color of the text */ // Draw the outer border of the button, which is a rounded rectangle pt with a radius of 5. X = 5; PT. y = 5; cpen * holdpen = PDC-> SelectObject (& m_boundrypen); PDC-> roundrect (& rect, pt); // get button status if (State & ods_focus) {m_bfocus = true; m_bselected = true;} else {m_bfocus = false; m_bselected = false;} If (State & ods_selected | State & ods_default) {m_bfocus = true ;} PDC-> SelectObject (holdpen); rect. deflaterect (csize (getsystemmetrics (sm_cxedge), getsystemmetrics (sm_cyedge )) ); // Fill the base color of the button * poldbrush; If (m_bover) {poldbrush = PDC-> SelectObject (& m_fillactive); dogradientfill (PDC, & rect) ;}else {poldbrush = PDC-> SelectObject (& m_fillinactive); dogradientfill (PDC, & rect );} // draw the internal border if (m_bover | m_bselected) drawinsideborder (PDC, & rect) based on the button status; PDC-> SelectObject (poldbrush ); // display the button text if (strtext! = NULL) {cfont * hfont = getfont (); cfont * holdfont = PDC-> SelectObject (hfont); csize szextent = PDC-> gettextextent (strtext, lstrlen (strtext )); cpoint Pt (rect. centerpoint (). x-szextent. CX/2, rect. centerpoint (). y-szextent. cy/2); If (State & ods_selected) pt. offset (1, 1); int nmode = PDC-> setbkmode (transparent); If (State & ods_disabled) PDC-> drawstate (PT, szextent, strtext, dss_disabled, true, 0, (HBr Ush) null); elsepdc-> drawstate (PT, szextent, strtext, dss_normal, true, 0, (hbrush) null); PDC-> SelectObject (holdfont ); PDC-> setbkmode (nmode);} PDC-> restoredc (nsavedc);} // specifies the base color of the draw button. Void cxpbutton: dogradientfill (CDC * PDC, crect * rect) {cbrush brbk [64]; int nwidth = rect-> width (); int nheight = rect-> height (); crect CTS;/* For (INT I = 0; I <64; I ++) {If (m_bover) {If (m_bfocus) brbk [I]. createsolidbrush (RGB (255- (I/4), 255-(I/4), 255-(I/3); elsebrbk [I]. createsolidbrush (RGB (255-(I/4), 255-(I/4), 255-(I/5);} else {If (m_bfocus) brbk [I]. createsolidbrush (RGB (255-(I/3), 255-(I/3), 255-(I/4); elsebrbk [I]. createsolidbrush (RGB (255-(I/3), 255-(I/3), 255-(I/5) ;}} int I; for (I = rect-> top; I <= nheight + 2; I ++) {RDBMS. setrect (rect-> left, I, nwidth + 2, I + 1); PDC-> fil Lrect (& RDBMS, & brbk [(I * 63)/nheight)]);} */int I; brbk [0]. createsolidbrush (RGB (255, 0, 0); brbk [1]. createsolidbrush (RGB (0, 0); brbk [2]. createsolidbrush (RGB (255,); brbk [3]. createsolidbrush (RGB (0,255, 0); cbitmap bitmap; bitmap BMP; bitmap. loadbitmapw (idb_qq); bitmap. getbitmap (& BMP); CDC memdc; memdc. createcompatibledc (PDC); If (m_bover) {cbitmap * oldbitmap = memdc. selectObject (& Bitmap); PDC-> bitblt (0, 0, BM P. bmwidth, BMP. bmheight, & memdc, 0, 0, srcand); memdc. selectObject (oldbitmap);/* If (m_bfocus) // mouse + focus PDC-> fillrect (rect, & brbk [0]); // red else // mouse + focus-less PDC-> fillrect (rect, & brbk [1]); // black */} else {cbitmap * oldbitmap = memdc. selectObject (& Bitmap); PDC-> stretchblt (0, 0, BMP. bmwidth + 10, BMP. bmheight + 10, & memdc, 0, 0, BMP. bmwidth, BMP. bmheight, srcand); memdc. selectObject (oldbitmap);/* If (m_bfocus) // No mouse + focus PDC-> fillrect (rect, & BRB K [2]); // blue elsepdc-> fillrect (rect, & brbk [3]); // green */}/* for (I = 0; I <64; I ++) brbk [I]. deleteobject (); * // void cxpbutton: drawinsideborder (CDC * PDC, crect * rect) {cpen * pleft, * pright, * pTop, * pbottom; If (m_bselected &&! M_bover) {pleft = & strong; pright = & strong; pTop = & strong; pbottom = & strong;} else {pleft = & m_insideboundrypenleft; pright = & m_insideboundrypenright; PTop = & m_insideboundrypentop; pbottom = & m_insideboundrypenbottom;} cpoint oldpoint = PDC-> moveTo (rect-> left, rect-> bottom-1 ); cpen * poldpen = PDC-> SelectObject (pleft); PDC-> Li Neto (rect-> left, rect-> top + 1); PDC-> SelectObject (pright); PDC-> moveTo (rect-> right-1, rect-> bottom-1); PDC-> lineto (rect-> right-1, rect-> top); PDC-> SelectObject (pTop ); PDC-> moveTo (rect-> left-1, rect-> top); PDC-> lineto (rect-> right-1, rect-> top ); PDC-> SelectObject (pbottom); PDC-> moveTo (rect-> left, rect-> bottom); PDC-> lineto (rect-> right-1, rect-> bottom); PDC-> SelectObject (poldpen); PDC-> moveTo (oldpo INT); If (m_bselected &&! M_bover) drawfocusrect (PDC-> m_hdc, rect );}

  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.