Reference: cbuttonst source code demo download: ciconbtn_demodemo program image: Example:M_btn1.seticon (align); // set icon // set the alignment of icon and text to: icon on the left text on the right m_btn1.setalign (ciconbtn: Align); m_btn2.seticon (idi_icon_test ); // set the alignment of the icon and text to: icon on the right text on the left m_btn2.setalign (ciconbtn: ibtn_icon_right_text_left); m_btn3.seticon (idi_icon_test ); // set the alignment of the icon and text to: icon at the top of the text at the bottom m_btn3.setalign (ciconbtn: ibtn_icon_top_text_bottom); m_btn4.seticon (idi_icon_test ); // set the alignment of the icon and text to m_btn4.setalign (ciconbtn: ibtn_icon_bottom_text_top) at the bottom of the icon text );
You can first view a previous blog post: wm_drawitem announcement this article details how to draw the same button as the standard Pushbutton.
Ciconbtn class:Class ciconbtn: Public cbutton {declare_dynamic (ciconbtn) Public: ciconbtn (); Virtual ~ Ciconbtn (); Virtual bool pretranslatemessage (MSG * PMSG); Virtual void presubclasswindow (); Virtual void drawitem (lpdrawitemstruct/* lpdrawitemstruct */); Enum {Limit = 0, // left: icon right: textibtn_icon_right_text_left, // right: icon left: Plain, // top: icon bottom: textibtn_icon_bottom_text_top // bottom: icon top: text}; protected: void drawbackground (); void drawborder (); void draw3dborderforrect (CDC * PDC, crect * prect); void drawfocusrect (); void drawicon (); void drawtext (); void preparedrawiconandtext (); Public: bool seticon (INT nicon, int ncxdesired = 0, int ncydesired = 0); bool setalign (byte byalign); Private: byte m_byalign; // text and Icon alignment mode CDC * m_pdc; // dc handle pointercrect m_rcbtn; // button rectbool m_bisfocused; // button whether the focus bool m_bispressed is obtained; // whether the button is pressed bool m_bisdisabled; // whether the button is disablehicon m_hicon; // icon handleint m_niconwidth; // icon widthint m_niconheight; // icon heightint m_nfocusrectoffset; // offset of the Focus rectangle int m_ncxiconstart; // X coordinate of the start point of the draw icon int m_ncyiconstart; // rect m_rctext, Y coordinate of the start point of the draw icon; // protected: declare_message_map ()};
I. Override pretranslatemessageDouble-click the message as two clicks.BOOL CIconBtn::PreTranslateMessage(MSG* pMsg){// TODO: Add your specialized code here and/or call the base classif (pMsg->message == WM_LBUTTONDBLCLK)pMsg->message = WM_LBUTTONDOWN;return CButton::PreTranslateMessage(pMsg);}
Ii. Override presubclasswindowChange the control to the owner-draw style.void CIconBtn::PreSubclassWindow(){// TODO: Add your specialized code here and/or call the base classModifyStyle(BS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);CButton::PreSubclassWindow();}
Iii. Override drawitemVoid ciconbtn: drawitem (lpdrawitemstruct) {// obtain the DC and button size m_pdc = CDC: fromhandle (bytes-> HDC); m_pdc-> setbkmode (transparent ); m_rcbtn = upload-> rcitem; // monitoring button status m_bisfocused = upload-> itemstate & ods_focus; m_bispressed = upload-> itemstate & ods_selected; m_bisdisabled = upload-> itemstate & ods_disabled; // draw backgroundthis-> drawbackgroun D (); // draw borderthis-> drawborder (); // draw focus rectthis-> drawfocusrect (); // calculate the location of the draw icon and the rectangle of the draw text. This-> preparedrawiconandtext (); // draw iconif (m_hicon) This-> drawicon (); // draw textcstring strtext; getwindowtext (strtext); If (! Strtext. isempty () This-> drawtext ();} // draw background // void ciconbtn: drawbackground () {cbrush brushbk (: getsyscolor (color_btnface )); if (m_bisfocused) {m_rcbtn.deflaterect (1, 1); m_pdc-> fillrect (& m_rcbtn, & brushbk); Round (-1,-1); cbrush brushframe (RGB (0, 0, 0); m_pdc-> framerect (& m_rcbtn, & brushframe);} else {m_pdc-> fillrect (& m_rcbtn, & brushbk );}} /// draw border // void ciconbtn: drawborde R () {If (m_bispressed) {round (1, 1); cbrush brbtnshadow (: getsyscolor (color_btnshadow); m_pdc-> framerect (& m_rcbtn, & brbtnshadow ); else (-1,-1);} else if (m_bisfocused) {m_rcbtn.deflaterect (1, 1); this-> draw3dborderforrect (m_pdc, & m_rcbtn); else (-1, -1) ;}else {This-> draw3dborderforrect (m_pdc, & m_rcbtn) ;}/// draw a 3D border for the prect // void ciconbtn: draw3dborderforrect (CDC * P DC, crect * prect) {cpen penbtnhilight (ps_solid, 0, getsyscolor (color_btnhilight); // whitecpen pen3dlight (ps_solid, 0, getsyscolor (color_3dlight )); // light graycpen penbtnshadow (ps_solid, 0, getsyscolor (color_btnshadow); // dark graycpen pen3ddkshadow (ps_solid, 0, getsyscolor (color_3ddkshadow )); // black // draw top-left borders // white linecpen * poldpen = PDC-> SelectObject (& penbtnhilight); PDC-> m Oveto (prect-> left, prect-> bottom-1); PDC-> lineto (prect-> left, prect-> top ); PDC-> lineto (prect-> right, prect-> top); // light gray linepdc-> SelectObject (pen3dlight); PDC-> moveTo (prect-> left + 1, prect-> bottom-1); PDC-> lineto (prect-> left + 1, prect-> top + 1); PDC-> lineto (prect-> right, prect-> top + 1); // draw bottom-right borders // black linepdc-> SelectObject (pen3ddkshadow); PDC-> moveTo (prect-> left, prect-> bottom-1 ); PDC-> lineto (prect-> right-1, prect-> bottom-1); PDC-> lineto (prect-> right-1, prect-> top-1 ); // dark gray linepdc-> SelectObject (penbtnshadow); PDC-> moveTo (prect-> left + 1, prect-> bottom-2 ); PDC-> lineto (prect-> right-2, prect-> bottom-2); PDC-> lineto (prect-> right-2, prect-> top ); // PDC-> SelectObject (poldpen);} // draw the focus rectangle // void ciconbtn: drawfocusrect () {If (m_bisfocused) {then (m_nfocusrectoffset, M_n Focusrectoffset); m_pdc-> drawfocusrect (& m_rcbtn); trim (-m_nfocusrectoffset,-rows); }}/// calculate the position of the icon and text to be drawn. // void ciconbtn :: preparedrawiconandtext () {// determines whether text and iconbool bishastext = false; bool bishasicon = false; cstring cstrcaption; this-> getwindowtext (cstrcaption); bishastext =! Cstrcaption. isempty (); If (m_hicon) bishasicon = true; // calculates the position of the icon and text to be drawn. If (bishastext & bishasicon) // both text and Icon {Switch (m_byalign) {case when: {m_ncxiconstart = cursor + cursor; m_ncyiconstart = cursor + (m_rcbtn.height ()-m_niconheight)/2; m_rctext.left = cursor + m_niconwidth; m_rctext.top = cursor + weight; m _ Rctext. right = lower-limit; m_rctext.bottom = lower-limit;} break; case when: {m_ncxiconstart = m_rcbtn.right-direction-m_niconwidth; m_ncyiconstart = Lower +) /2; m_rctext.left = m_rcbtn.left + m_nfocusrectoffset; m_rctext.top = m_rcbtn.top + m_nfocusrectoffset; m_rctext.right = m_rc BTN. right-align-m_niconwidth; m_rctext.bottom = accept-limit;} break; case when: {m_ncxiconstart = Lower + (m_rcbtn.width ()-m_niconwidth)/2; m_ncyiconstart = Lower + lower; m_rctext.left = m_rcbtn.left + m_nfocusrectoffset; m_rctext.top = m_rcbtn.top + m_nfocusrectoffset + m_niconheight; m_rctext.right = m_rcbtn.rig Ht-keys; m_rctext.bottom = upper-limit;} break; case when: {m_ncxiconstart = Lower + (m_rcbtn.width ()-m_niconwidth)/2; m_ncyiconstart = lower-minus-m_niconheight; m_rctext.left = m_rcbtn.left + m_nfocusrectoffset; m_rctext.top = m_rcbtn.top + m_nfocusrectoffset; m_rctext.right = m_rcbtn.right-m_nfocusrectof Fset; m_rctext.bottom = m_rcbtn.bottom-m_nfocusrectoffset-m_niconheight;} break; default: break;} else if (! Bishastext & bishasicon) // No text only icon {m_ncxiconstart = centers + (Centers ()-m_niconwidth)/2; m_ncyiconstart = centers + (m_rcbtn.height ()-m_niconheight)/2; m_rctext.left = 0; m_rctext.top = 0; m_rctext.right = 0; m_rctext.bottom = 0;} else if (bishastext &&! Bishasicon) // only text without icon {m_ncxiconstart = 0; m_ncyiconstart = 0; m_rctext.left = gradient; m_rctext.top = gradient; m_rctext.right = gradient; m_rctext.bottom = gradient;} else {cost = 0; m_ncyiconstart = 0; m_rctext.left = 0; m_rctext.top = 0; m_rctext.right = 0; m_rctext.bottom = 0 ;}/// draw icon // void ciconbtn: drawicon () {// determine whether iconif (! M_hicon) return; // gray if disabled. // If pressed is used, 1 uint flag = dst_icon is shifted to the right and down of the icon. | (m_bisdisabled? Dss_disabled: dss_normal); int ncxiconstart = m_bispressed? M_ncxiconstart + 1: m_ncxiconstart; int ncyiconstart = m_bispressed? Values + 1: m_ncyiconstart; // draw icon: drawstate (m_pdc-> m_hdc, null, null, (lparam) m_hicon, null, ncxiconstart, ncyiconstart, m_niconwidth, m_niconheight, flag);} // draw text // void ciconbtn: drawtext () {// determine whether there is textcstring strtext; getwindowtext (strtext); If (strtext. isempty () return; // If you press the button, the text moves one if (m_bispressed) {m_rctext.left + = 2;} else {m_rctext.bottom-= 2; // align text vertically} // draw textif (m_bisdisabled) // draw text and gray text {crect rctext (& m_rctext); rctext. offsetrect (1, 1); m_pdc-> settextcolor (: getsyscolor (color_3dhilight); m_pdc-> drawtext (strtext, & rctext, dt_singleline | dt_vcenter | dt_center); rctext. offsetrect (-1,-1); m_pdc-> settextcolor (: getsyscolor (color_3dshadow); m_pdc-> drawtext (strtext, & rctext, dt_singleline | dt_vcenter | dt_center );} else // draw text {m_pdc-> drawtext (strtext, & m_rctext, dt_singleline | dt_vcenter | dt_center );}}
Iv. open interfaces/// Set the icon // bool ciconbtn: seticon (INT nicon, int ncxdesired, int ncydesired) {hicon = (hicon): LoadImage (:: getmodulehandle (null), makeintresource (nicon), image_icon, ncxdesired, ncydesired, 0); If (hicon) {// first release the previous icon: destroyicon (m_hicon ); // m_hicon = hicon; // get icon sizeiconinfo ICI;: geticoninfo (m_hicon, & ICI); bitmap bm;: GetObject (ici. hbmcolor, sizeof (Bitmap), & BM); m_niconwidth = BM. bmwidth; m_niconheight = BM. bmheight;: deleteobject (ici. hbmcolor);: deleteobject (ici. hbmmask); Return true;} elsereturn false;} // set the alignment of the icon and text. // bool ciconbtn: setalign (byte byalign) {Switch (byalign) {case when: Case ibtn_icon_right_text_left: Case ibtn_icon_top_text_bottom: Case ibtn_icon_bottom_text_top: m_byalign = byalign; default: Return false;} return true ;}