另外一种实现平面工具栏的方.htm

来自「VC的一些技巧性文档」· HTM 代码 · 共 1,007 行 · 第 1/3 页

HTM
1,007
字号
</pre>    </dd>    <dd><pre>#if _mfc_ver &gt;= 0x420</pre>    </dd>    <dd><pre>   lresult ccustomdrawinfo :: notifyparent() {      lresult lres = cdrf_dodefault;</pre>    </dd>    <dd><pre>      if( m_preceiver )         lres = m_preceiver-&gt;sendmessage(wm_notify,                                 wparam(m_cdrw.hdr.idfrom),                                 lparam(&amp;m_cdrw));      return lres;   }</pre>    </dd>    <dd><pre>   ccustomdrawinfo :: ccustomdrawinfo( cdc &amp; dc, ctoolbarex * pbar )      : m_prepaint(0)      , m_itemprepaint(0)   {      verify((m_ptoolbar = pbar) != 0);      verify((m_cdrw.hdc = dc.getsafehdc()) != 0);</pre>    </dd>    <dd><pre>      hwnd hwnd = pbar-&gt;getsafehwnd();      verify(::iswindow(hwnd));</pre>    </dd>    <dd><pre>      // initialise the nmhdr member of the customdraw structure      m_cdrw.hdr.hwndfrom = hwnd;      m_cdrw.hdr.idfrom = uint(::getwindowlong(hwnd, gwl_id));      m_cdrw.hdr.code = nm_customdraw;</pre>    </dd>    <dd><pre>      // do not use ccontrolbar::getdockingframe() to receive      // the parent. cwnd::getparent() is inacceptable too.      // both these functions don't work, if the toolbar is      // floating in the air!      m_preceiver = pbar-&gt;getparentframe();      if( m_preceiver )         verify(::iswindow(m_preceiver-&gt;getsafehwnd()));   }</pre>    </dd>    <dd><pre>   void ccustomdrawinfo :: notifyprepaint() {      // fill the customdraw structure with values for cdds_prepaint      m_cdrw.dwdrawstage = cdds_prepaint;      // the rest of the structure stays undefined in this stage      // of drawing.      m_prepaint = notifyparent();   }</pre>    </dd>    <dd><pre>   bool ccustomdrawinfo :: notifyitemprepaint( int nitem ) {      bool bret = true;   // we assume to do the default      if( m_prepaint &amp; cdrf_notifyitemdraw ) {         m_cdrw.dwdrawstage = cdds_itemprepaint;         m_ptoolbar-&gt;getitemrect(nitem, &amp;m_cdrw.rc);         m_cdrw.dwitemspec = dword(m_ptoolbar-&gt;getitemid(nitem));         uint ustyle = m_ptoolbar-&gt;getbuttonstyle(nitem);         bool benable = m_ptoolbar-&gt;gettoolbarctrl()                     .isbuttonenabled(m_cdrw.dwitemspec);         m_cdrw.uitemstate = (benable ? 0 : cdis_disabled) |                        (((ustyle &amp; tbbs_pressed) || (ustyle &amp; tbbs_checked)) ?                           cdis_checked : 0);         m_cdrw.litemlparam = 0;         m_itemprepaint = notifyparent();         if( m_itemprepaint &amp; cdrf_skipdefault )            bret = false;      }      return bret;   }</pre>    </dd>    <dd><pre>   void ccustomdrawinfo :: notifyitempostpaint( int nitem ) {      if( m_itemprepaint &amp; cdrf_notifypostpaint ) {         m_cdrw.dwdrawstage = cdds_itempostpaint;         // the rest of the data has not been changed since itemprepaint         // make sure it is so:         assert(m_ptoolbar-&gt;getitemid(nitem) == m_cdrw.dwitemspec);         notifyparent();      }   }</pre>    </dd>    <dd><pre>   void ccustomdrawinfo :: notifypostpaint() {      if( m_prepaint &amp; cdrf_notifypostpaint ) {         m_cdrw.dwdrawstage = cdds_postpaint;         notifyparent();      }   }      	</pre>    </dd>    <dd><pre>#else   // _mfc_ver &lt; 4.2</pre>    </dd>    <dd><pre>   ccustomdrawinfo :: ccustomdrawinfo( cdc &amp; dc, cwnd * pparent ) {   }</pre>    </dd>    <dd><pre>   void ccustomdrawinfo :: notifyprepaint() {   }</pre>    </dd>    <dd><pre>   void ccustomdrawinfo :: notifypostpaint() {   }	</pre>    </dd>    <dd><pre>   bool ccustomdrawinfo :: notifyitemprepaint( int ) {      return true;   // we always make the drawing by ourself   }</pre>    </dd>    <dd><pre>   void ccustomdrawinfo :: notifyitempostpaint( int ) {   }</pre>    </dd>    <dd><pre>#endif   // _mfc_ver</pre>    </dd>    <dd><pre>/////////////////////////////////////////////////////////////////////////////// ctoolbarex</pre>    </dd>    <dd><pre>ctoolbarex::ctoolbarex()   : m_bflatlook(true)   , m_clrbtnface(::getsyscolor(color_btnface))   , m_clrbtnhilight(::getsyscolor(color_btnhilight))   , m_clrbtnshadow(::getsyscolor(color_btnshadow))   , m_nlastbtn(-1)   , m_utimerevent(0){   calculateoffset();</pre>    </dd>    <dd><pre>   // create the default font, used for buttons with text   cfont font;   bool boldsys = false;   if( ! font.createstockobject( default_gui_font ) ) {      // older versions of windows* (nt 3.51 for instance)      // fail with default_gui_font      verify( font.createstockobject( system_font ) );      boldsys = true;   }   logfont logfont ;   font.getlogfont( &amp;logfont ) ;   if( boldsys ) {      logfont.lfweight = 400;      strcpy(logfont.lffacename,&quot;ms sans serif&quot;);   }   logfont.lfheight = 6 ;   logfont.lfwidth = 0 ;   // let windows compute this.   verify( m_guifont.createfontindirect( &amp;logfont ) ) ;}</pre>    </dd>    <dd><pre>ctoolbarex::~ctoolbarex(){}</pre>    </dd>    <dd><pre>implement_dynamic(ctoolbarex, ctoolbar)</pre>    </dd>    <dd><pre>begin_message_map(ctoolbarex, ctoolbar)   //{{afx_msg_map(ctoolbarex)   on_wm_paint()   on_wm_syscolorchange()   on_wm_nccalcsize()   on_wm_mousemove()   on_wm_ncpaint()   on_wm_timer()   on_wm_create()   //}}afx_msg_map   on_message(tb_setbuttonsize, onsetbuttonsize)   on_message(tb_setbitmapsize, onsetbitmapsize)end_message_map()</pre>    </dd>    <dd><pre>/////////////////////////////////////////////////////////////////////////////// ctoolbarex message handlers</pre>    </dd>    <dd><pre>lresult ctoolbarex :: onsetbuttonsize(wparam wparam, lparam lparam) {   lresult lresult = ctoolbar::onsetbuttonsize(wparam, lparam);   if( lresult )      calculateoffset();   return lresult;}</pre>    </dd>    <dd><pre>lresult ctoolbarex :: onsetbitmapsize(wparam wparam, lparam lparam) {   lresult lresult = ctoolbar::onsetbitmapsize(wparam, lparam);   if( lresult )      calculateoffset();   return lresult;}</pre>    </dd>    <dd><pre>void ctoolbarex::onpaint() {   himagelist himg = getimagelist();</pre>    </dd>    <dd><pre>#ifdef _debug   if( himg == 0 ) {      trace0(&quot;ctoolbarex::onpaint(): could not get image list\n&quot;);   }#endif</pre>    </dd>    <dd><pre>   if( m_bflatlook &amp;&amp; himg ) {      crect rcupdate;      if( ! getupdaterect(rcupdate) )         return;</pre>    </dd>    <dd><pre>      if( m_pstringmap &amp;&amp; !m_pstringmap-&gt;isempty() )         calculateoffset();      // strings may have been added</pre>    </dd>    <dd><pre>      // attach image-list for even more mfc feeling :)      cimagelist imglist;      imglist.attach(himg);</pre>    </dd>    <dd><pre>      point cursor;      ::getcursorpos(&amp;cursor);      screentoclient(&amp;cursor);</pre>    </dd>    <dd><pre>      cpaintdc dc(this); // device context for painting      cfont * poldfont = dc.selectobject(&amp;m_guifont);</pre>    </dd>    <dd><pre>      // now it's time for the first custom-draw-notification...      ccustomdrawinfo cdrw(dc, this);      cdrw.notifyprepaint();</pre>    </dd>    <dd><pre>      register const int nbtn = gettoolbarctrl().getbuttoncount();</pre>    </dd>    <dd><pre>      for( register int i = 0; i &lt; nbtn; ++i ) {         crect rc;         getitemrect(i, rc);</pre>    </dd>    <dd><pre>         int nbitmap; uint uid, ustylestate;         getbuttoninfo(i, uid, ustylestate, nbitmap);         word wstyle = loword(ustylestate);         word wstate = hiword(ustylestate);</pre>    </dd>    <dd><pre>         if( wstate &amp; tbstate_hidden )            continue;</pre>    </dd>    <dd><pre>         if( wstyle == tbstyle_sep ) {            if( !(wstate &amp; tbstate_wrap) || ! isfloating() )               drawseparator(dc, rc);         } else {            if( ! crect().intersectrect(rcupdate, rc) )               continue;   // this button needs no repaint</pre>    </dd>    <dd><pre>            // maybe the button has text            dc.settextcolor(rgb(0,0,0));            dc.setbkcolor(m_clrbtnface);</pre>    </dd>    <dd><pre>            // there is a bug in ctoolbar: if there are texts assigned            // to buttons, then the button-widths may change transparently            // (without notified by ctoolbar), so we recalculate the            // horizontal offset here:            m_sizeoffset.cx = (rc.width() - m_sizeimage.cx) / 2;</pre>    </dd>    <dd><pre>            if( ! cdrw.notifyitemprepaint(i) )               continue;   // parent has already drawn the button</pre>    </dd>    <dd><pre>            bool bbtndown = (wstate &amp; tbstate_checked) || (wstate &amp; tbstate_pressed);            bool bbtnenabled = gettoolbarctrl().isbuttonenabled(int(uid));</pre>    </dd>    <dd><pre>            dc.fillsolidrect(rc,m_clrbtnface);</pre>    </dd>    <dd><pre>            // it seems, that cdc::draw3drect() changes the backgrounddi2001.jpgd color            colorref clrbk = dc.getbkcolor();</pre>    </dd>    <dd><pre>            if( bbtndown )               // draw a pressed button               dc.draw3drect(rc, m_clrbtnshadow, m_clrbtnhilight);            else if( rc.ptinrect(cursor) &amp;&amp; ! bbtndown &amp;&amp; bbtnenabled )               // draw a normal button               dc.draw3drect(rc, m_clrbtnhilight, m_clrbtnshadow);            else if( ! bbtndown &amp;&amp; bbtnenabled )               // draw an invisible rect around the button.               // this prevents us from erasing the backgrounddi2001.jpgd               // if the button was formed before               // (that would cause the button to flicker ...)               dc.draw3drect(rc, m_clrbtnface, m_clrbtnface);         	</pre>    </dd>    <dd><pre>            dc.setbkcolor(clrbk);</pre>    </dd>    <dd><pre>            // the point where to start with the image            cpoint pt(rc.left + m_sizeoffset.cx + bbtndown,                    rc.top + m_sizeoffset.cy + bbtndown);         	</pre>    </dd>    <dd><pre>            imglist.draw(&amp;dc, nbitmap, pt, ild_transparent);            cstring strtext = getbuttontext(i);            if( strtext.getlength() ) {               crect recttext(                  rc.left+3+bbtndown,                  rc.top+m_sizeoffset.cy+m_sizeimage.cy+1+bbtndown,                  rc.right-3+bbtndown,                  rc.bottom-3+bbtndown               );               dc.drawtext(strtext, recttext, dt_center|dt_vcenter|dt_noclip);            }         	</pre>    </dd>    <dd><pre>            if( ! bbtnenabled )               // gray out that button               drawdisabledbutton(dc, rc);</pre>    </dd>    <dd><pre>            cdrw.notifyitempostpaint(i);         }      }</pre>    </dd>    <dd><pre>      dc.selectobject(poldfont);</pre>    </dd>    <dd><pre>      if( ! m_bdeleteimglist )         imglist.detach();</pre>    </dd>    <dd><pre>      // last but not least: inform the parent for end of painting      cdrw.notifypostpaint();   } else      // classic mode (or couldn't receive imagelist)      ctoolbar::onpaint();}</pre>    </dd>    <dd><pre>void ctoolbarex :: drawdisabledbutton( cdc &amp; dc, const crect &amp; rc ) const {   // create a monochrome memory dc   cdc ddc;   ddc.createcompatibledc(0);   cbitmap bmp;   bmp.createcompatiblebitmap(&amp;ddc, rc.width(), rc.height());   cbitmap * poldbmp = ddc.selectobject(&amp;bmp);	</pre>    </dd>    <dd><pre>   // build a mask   ddc.patblt(0, 0, rc.width(), rc.height(), whiteness);   dc.setbkcolor(m_clrbtnface);   ddc.bitblt(0, 0, rc.width(), rc.height(), &amp;dc, rc.left, rc.top, srccopy);   dc.setbkcolor(m_clrbtnhilight);   ddc.bitblt(0, 0, rc.width(), rc.height(), &amp;dc, rc.left, rc.top, srcpaint);</pre>    </dd>    <dd><pre>   // copy the image from the toolbar into the memory dc   // and draw it (grayed) back into the toolbar.   dc.fillsolidrect(rc.left, rc.top, rc.width(), rc.height(), m_clrbtnface);   dc.setbkcolor(rgb(0, 0, 0));   dc.settextcolor(rgb(255, 255, 255));   cbrush brshadow, brhilight;   brhilight.createsolidbrush(m_clrbtnhilight);   brshadow.createsolidbrush(m_clrbtnshadow);   cbrush * poldbrush = dc.selectobject(&amp;brhilight);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?