概述:
Buton 按钮对于大家并不陌生,本文章主要是实现基于Wtl CButton 的基础上来,实现重绘,主要是通过 DrawItem( LPDRAWITEMSTRUCT lpdis )来实现重绘,与通常的控件绘制是一样的,先绘制背景、然后绘制控件,最后提交。

 /***@method   DrawItem*@brief    draw item.*    *@param    LPDRAWITEMSTRUCT lpdis  lpdis draw item struct*@return   void*/void DrawItem( LPDRAWITEMSTRUCT lpdis ){int width = lpdis->rcItem.right - lpdis->rcItem.left;int height = lpdis->rcItem.bottom - lpdis->rcItem.top;//创建内存作图对象WTL::CDC memDC;memDC.CreateCompatibleDC( lpdis->hDC );WTL::CBitmap memBitmap;memBitmap.CreateCompatibleBitmap( lpdis->hDC, width, height );HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );//获得控件背景memDC.SetBkMode( TRANSPARENT );::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )lpdis->hwndItem );//绘制按钮DrawButton( memDC.m_hDC, lpdis->rcItem );//提交图像::BitBlt( lpdis->hDC, 0, 0, width, height, memDC.m_hDC, 0, 0, SRCCOPY );memDC.SelectBitmap( hOldBmp );}

CQsButton 详细代码实现:


#pragma once;#include "QsInclude.h"
#include "UserMessage.h"#define  BS_BTNTESTTOP     0x00000001     //表示Button标题在下方
#define  BS_BTNTESTBOTTOM  0x00000002     //表示Button标题在上方
#define  BS_BTNTESTCENTER  0x00000004     //表示Button标题在中间/* CQsButton class */
class CQsButton :public CImageMgrCtrlBase< CQsButton>,public CWindowImpl<CQsButton, CButton>,public COwnerDraw< CQsButton >
{typedef CWindowImpl< CQsButton, CButton > theBaseClass;typedef CImageMgrCtrlBase< CQsButton> theImageCtrlBaseClass;private:volatile UINT   m_uCurState;            //当前按钮状态volatile bool   m_bMouseDown;           //鼠标左键按下BOOL            m_bTransBKGnd;          //是否使用透明背景volatile bool m_bMouseTrack;          //鼠标是否进入DWORD           dwtxtStyle;              //Button 标题在Button中显示样式CMenuHandle     m_mnPopMenu;            //right mouse button pop menuCWindow            m_wndMenuNotify;        //pop up menu notify windowint             m_npost;                //字体离Button中线的距离Image*          m_pImageForegrd;        //前景图片CRect           m_foregrdrect;          //前景图片显示的区域BOOL            m_bunifycolr;           //是否统一到Normal一种状态下的颜色BOOL            m_bunifyfont;           //是否统一到Normal一种状态下的颜色BOOL            m_bflagBK;CRect           m_RectText;             //字显示区域public:DECLARE_WND_SUPERCLASS(TEXT("QSBUTTON"), CButton::GetWndClassName())BEGIN_MSG_MAP( CQsButton )MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBKGnd )MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )MESSAGE_HANDLER( WM_LBUTTONUP, OnLButtonUp )MESSAGE_HANDLER( WM_RBUTTONUP, OnRButtonUp )MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )CHAIN_MSG_MAP_ALT( COwnerDraw< CQsButton >, 1 )CHAIN_MSG_MAP( theImageCtrlBaseClass )DEFAULT_REFLECTION_HANDLER()END_MSG_MAP()/*! \fn CQsButton()*  \param N/A*  \return no return*  \brief CQsButton's default constructor.*/CQsButton():m_bMouseDown( false ),m_uCurState( CONTROL_BTN_NORMAL ),m_bTransBKGnd( FALSE ),m_bMouseTrack( TRUE ){m_uFirstPos = CONTROL_BTN_FIRST;m_uLastPos = CONTROL_BTN_LAST;m_pImageForegrd = NULL;m_bunifycolr = FALSE;m_bunifyfont = FALSE;m_bflagBK = TRUE;m_npost =0;m_RectText.left=0;m_RectText.top=0;m_RectText.right=0;m_RectText.bottom=0;}/***@method   ~CQsButton*@brief    QsButton类的构造函数*    *@return   */~CQsButton(){ClearForeGroundImage();}/***@method   Create*@brief    Use this function to subclass one window*     *@param    HWND hWndParent parent window*@param    ATL::_U_RECT rect = NULL  create window rect*@param    LPCTSTR szWindowName = NULL  the window name*@param    DWORD dwStyle = 0   base window style*@param    DWORD dwExStyle = 0  extended window style*@param    ATL::_U_MENUorID MenuOrID = 0U  menu or ID*@param    LPVOID lpCreateParam = NULL  create param*@return   HWND  BOOL success return TRUE, failed return FALSE*/HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,DWORD dwStyle = 0, DWORD dwExStyle = 0,ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL){return theBaseClass::Create( hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);}/***@method   SetButTextRect*@brief    设置微调ButText的显示区域*    *@param    CRect rect*@return   void*/void SetButTextRect(CRect rect){m_RectText = rect;}/***@method   SetBtnUnifycolr*@brief    设置各种状态下使用一种字体颜色*    *@param    BOOL bunifycolr*@return   void*/void SetBtnUnifycolr(BOOL bunifycolr){m_bunifycolr = bunifycolr;}/***@method   SetBtnUnifFont*@brief    设置各种状态下使用一种字体*    *@return   void*/void SetBtnUnifFont(BOOL bunifyfont){m_bunifyfont = bunifyfont;}/***@method   SetBtnUnit*@brief    设置统一的*    *@param    BOOL bunifycolr*@param    BOOL bunifyfont*@return   void*/void SetBtnUnit(BOOL bunifycolr,BOOL bunifyfont){m_bunifycolr = bunifycolr;m_bunifyfont = bunifyfont;}/***@method   SetBtnBK*@brief     是否绘制背景*    *@param    BOOL bFlagBk*@return   void*/void SetBtnBK(BOOL bFlagBk){m_bflagBK = bFlagBk;}/***@method   SetForegroudImage*@brief    设置前景图片的和图片的大小*    *@param    Image * pImge*@param    CRect rect*@return   void*/void SetForegroudImage(Image* pImge, CRect rect){if(pImge != NULL){ClearForeGroundImage();m_pImageForegrd = pImge->Clone();}m_foregrdrect = rect;}/***@method   GetForegroudImage*@brief    得到前景图片对象*    *@return   Image**/Image* GetForegroudImage(){return m_pImageForegrd;}/***@method   ClearForeGroundImage*@brief    清除前景图片 *    *@param    Image * pImge*@param    CRect rect*@return   void*/void ClearForeGroundImage(){if(m_pImageForegrd != NULL ){delete m_pImageForegrd;m_pImageForegrd = NULL;}}/***@method   SetTextStyle*@brief    设置Button标题的显示方式*    *@param    DWORD dwtxtStyle = BS_BTNTESTCENTER,默认值为中间显示*@return   void*/void  SetTextStyle(DWORD dwtxtStyle = BS_BTNTESTCENTER){m_dwQsStyle = dwtxtStyle; }/***@method   GetCustomState*@brief    GetCustomState's default constructor.*    *@param    void*@return   UINT current state of control*/UINT GetCustomState( void ){return m_uCurState;}/***@method   DrawItem*@brief    draw item.*    *@param    LPDRAWITEMSTRUCT lpdis  lpdis draw item struct*@return   void*/void DrawItem( LPDRAWITEMSTRUCT lpdis ){int width = lpdis->rcItem.right - lpdis->rcItem.left;int height = lpdis->rcItem.bottom - lpdis->rcItem.top;//创建内存作图对象WTL::CDC memDC;memDC.CreateCompatibleDC( lpdis->hDC );WTL::CBitmap memBitmap;memBitmap.CreateCompatibleBitmap( lpdis->hDC, width, height );HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );//获得控件背景memDC.SetBkMode( TRANSPARENT );::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )lpdis->hwndItem );//绘制按钮DrawButton( memDC.m_hDC, lpdis->rcItem );//提交图像::BitBlt( lpdis->hDC, 0, 0, width, height, memDC.m_hDC, 0, 0, SRCCOPY );memDC.SelectBitmap( hOldBmp );}/***@method   SubclassWindow*@brief    Use this function to subclass one window*    *@param    HWND hWnd  subclass binding window handle*@return   BOOL  BOOL success return TRUE, failed return FALSE*/BOOL SubclassWindow( HWND hWnd ){BOOL bRet = theBaseClass::SubclassWindow( hWnd );UINT nBS = GetButtonStyle();SetButtonStyle( nBS | BS_OWNERDRAW );return bRet;}/***@method   ClearImage*@brief    Clear the image of state*    *@param    UINT uState = 0xFFFFFFFF  the state image to clear*@return   void*/void ClearImage( UINT uState = 0xFFFFFFFF ){if( uState != 0xFFFFFFFF ){if( GetImage( uState ) ){CCtrlImageMgr::ClearImage( uState );Invalidate();}}else{CCtrlImageMgr::ClearImage( uState );Invalidate();}}/***@method   SetTransBKGnd*@brief    Set background transparent attitude*    *@param    BOOL bFlag Set the background transparent flag*@return   void*/void SetTransBKGnd( BOOL bFlag ){m_bTransBKGnd = bFlag;}/***@method   SetRClickPopMenu*@brief    Set Right button click to popup menu, is both PopupMenu and Notify is valid, right click will popup menu,BESURE RELEASE menu when menu no longer use.*    *@param    CMenuHandle PopupMenu Context menu to popup, THIS PARAM IS ONLY A REFERENCE OF HANDLE*@param    CWindow Notify Window menu command to notify*@return   void*/void SetRClickPopMenu(CMenuHandle PopupMenu, CWindow Notify){ATLASSERT(PopupMenu.IsMenu());ATLASSERT(Notify.IsWindow());m_mnPopMenu = PopupMenu;m_wndMenuNotify = Notify;}/***@method   SetWindowTextEx*@brief    设置Button显示的标题*    *@param    LPCTSTR lpszString  标题字符串*@param    int nPostion        字符离Button中心的垂直距离*@return   void*/void SetWindowTextEx(LPCTSTR lpszString,int nPostion = 0){::SetWindowText(m_hWnd,lpszString);m_npost = nPostion;}protected:/***@method   OnLButtonDown*@brief    鼠标左键被按下消息响应函数*    *@param    UINT uMsg 消息类型*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnLButtonDown( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){m_bMouseDown = true;Invalidate();bHandled = FALSE;return 0;}/***@method   OnMouseMove*@brief    鼠标进入消息响应函数*    *@param    UINT uMsg 消息类型*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnMouseMove( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){if ( m_bMouseTrack ){// 向父窗口发送BN_MOUSEIN扩展通知消息HWND hParent = GetParent();if ( NULL != hParent ){WPARAM wParam = MAKELONG( ::GetWindowLong(m_hWnd, GWL_ID), BN_MOUSEIN );::PostMessage( hParent, WM_COMMANDEX, wParam, (LPARAM)m_hWnd );}}if( m_uCurState != CONTROL_BTN_MOUSEIN || m_bMouseTrack){Invalidate();// 启动鼠标离开时间TRACKMOUSEEVENT tme;tme.cbSize  = sizeof(tme);tme.hwndTrack = m_hWnd;tme.dwFlags = TME_LEAVE|TME_HOVER;TrackMouseEvent(&tme);m_bMouseTrack = FALSE;}bHandled = FALSE;return 0;}/***@method   OnMouseLeave*@brief    鼠标离开消息响应函数*    *@param    UINT uMsg 消息类型*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnMouseLeave( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){if(!m_bMouseTrack){Invalidate();bHandled = FALSE;m_bMouseTrack = TRUE;// 向父窗口发送BN_MOUSEOUT扩展通知消息HWND hParent = GetParent();if ( NULL != hParent ){WPARAM wParam = MAKELONG( ::GetWindowLong(m_hWnd, GWL_ID), BN_MOUSEOUT );::PostMessage( hParent, WM_COMMANDEX, wParam, (LPARAM)m_hWnd );}}return 0;}/***@method   OnLButtonUp*@brief    鼠标左键被放开消息响应函数*    *@param    UINT uMsg 消息类型*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnLButtonUp( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled ){m_bMouseDown = false;Invalidate();bHandled = FALSE;return 0;}/***@method   OnRButtonUp*@brief    鼠标左键被放开消息响应函数*    *@param    UINT uMsg 消息类型*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnRButtonUp( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ ){RECT rc;         // client area of window POINT pt;        // location of mouse click if (m_mnPopMenu.IsMenu() && m_wndMenuNotify.IsWindow()){// Convert the mouse position to client coordinates. GetCursorPos(&pt);::ScreenToClient(m_hWnd, &pt); ::GetClientRect(m_hWnd, &rc); // If the position is in the client area, display a  // shortcut menu. if (PtInRect(&rc, pt)) { ::ClientToScreen(m_hWnd, &pt); m_mnPopMenu.TrackPopupMenuEx(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, m_wndMenuNotify.m_hWnd, NULL);return TRUE; } }return 0;}/***@method   OnEraseBKGnd*@brief    背景绘制消息函数*    *@param    UINT uMsg 消息类型*@param    WPARAM wParam*@param    LPARAM lParam*@param    BOOL& bHandled*@return   LRESULT*/LRESULT OnEraseBKGnd( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/ ){//禁止绘制底色return 0;}private:/***@method   GetButtonTextFormat*@brief    得到Button文字的对齐方式(用DrawText()输出时的格式)*    *@param    const LONG lStyle 控件风格   *@return   UINT 用DrawText()输出时的格式  button上的字必须是一行  */UINT GetButtonTextFormat(const LONG lStyle){UINT uFormat = DT_SINGLELINE;//button上的字必须是一行//x方向if ( (lStyle & BS_CENTER)==BS_CENTER )//x方向,中uFormat |= DT_CENTER;else if ( (lStyle & BS_RIGHT)==BS_RIGHT )//x方向,右uFormat |= DT_RIGHT;else if ( (lStyle & BS_LEFT) == BS_LEFT )//x方向,左uFormat |= DT_LEFT|DT_END_ELLIPSIS;else//缺省,x中uFormat |= DT_CENTER;//y方向if ( (lStyle & BS_VCENTER ) == BS_VCENTER )//y,中uFormat |= DT_VCENTER;else if ( (lStyle & BS_TOP)==BS_TOP )//y方向,上uFormat |= DT_TOP;else if ( (lStyle & BS_BOTTOM)==BS_BOTTOM )//y方向,下uFormat |= DT_BOTTOM;else//缺省,y中uFormat |= DT_VCENTER;return uFormat;}/***@method   DrawButton*@brief    绘制按钮函数*    *@param    HDC hDC 作图设备句柄*@param    RECT itemRect 按钮位置*@return   void*/void DrawButton( HDC hDC, RECT itemRect ){HDC hdc = hDC;SetBkMode( hdc, TRANSPARENT );int width = itemRect.right - itemRect.left;int height = itemRect.bottom - itemRect.top;//         UINT itemState = GetState();//         LONG lStyle = GetWindowLong( GWL_STYLE );BOOL bIsDisabled = !IsWindowEnabled();//( ( lStyle & WS_DISABLED ) != 0 ); //是否被禁止BOOL bIsFocused = ( ::GetFocus() == m_hWnd );//        BOOL bIsPressed = ( ( itemState & ODS_SELECTED ) == ODS_SELECTED );//判断鼠标是否在按钮上CRect rc;GetWindowRect( rc );//POINT pt;//GetCursorPos( &pt );//BOOL bMouseIn = rc.PtInRect( pt );POINT pt;GetCursorPos( &pt );BOOL bMouseIn =FALSE;HWND hwnd = WindowFromPoint(pt);if(hwnd==m_hWnd){bMouseIn = TRUE;}if(m_bflagBK==TRUE){DrawBkGnd( hdc, width, height, bIsDisabled, bMouseIn, bIsFocused );}DrawForeground( hdc, width, height, bIsDisabled, bMouseIn, bIsFocused );}protected:/***@method   DrawBkGnd*@brief    绘制按钮背景函数*    *@param    HDC hDC 作图设备句柄*@param    int cx  按钮宽度*@param    int cy  按钮高度*@param    BOOL bDisabled*@param    BOOL bMoveIn*@param    BOOL bFocused*@return   void*/virtual void DrawBkGnd( HDC hDC, int cx, int cy, BOOL bDisabled, BOOL bMoveIn, BOOL bFocused ){UINT uState = CONTROL_BTN_NORMAL;//如果当前处于失效状态if( bDisabled ){if( GetImage( CONTROL_BTN_DISABLED ) )uState = CONTROL_BTN_DISABLED;}else if( bMoveIn )  //如果当前鼠标在按钮上{if( m_bMouseDown && GetImage( CONTROL_BTN_MOUSEDOWN ) ){uState = CONTROL_BTN_MOUSEDOWN;}else if( GetImage( CONTROL_BTN_MOUSEIN ) ){uState = CONTROL_BTN_MOUSEIN;}else{uState = m_uCurState;}}else if( bFocused ){if( GetImage( CONTROL_BTN_FOCUS ) ){uState = CONTROL_BTN_FOCUS;}}Image *pImage = GetImage( uState );//绘制图片if( NULL != pImage ){Graphics graph( hDC );graph.SetPageScale( 1.0 );graph.SetPageUnit( UnitPixel ); graph.SetSmoothingMode( SmoothingModeNone );//graph.DrawImage( pImage, 0, 0, cx, cy );DrawImageEx( graph, pImage, RectF(0,0,(REAL)cx,(REAL)cy), RectF(0, 0, REAL(pImage->GetWidth()), REAL(pImage->GetHeight())), 5, 5 );graph.ReleaseHDC( hDC );}m_uCurState = uState;}/***@method   DrawForeground*@brief    绘制按钮前景函数*    *@param    HDC hDC 作图设备句柄*@param    int cx  按钮宽度*@param    int cy  按钮高度*@param    BOOL bDisabled*@param    BOOL bMoveIn*@param    BOOL bFocused*@return   void*/virtual void DrawForeground( HDC hDC, int cx, int cy, BOOL bDisabled, BOOL bMoveIn, BOOL bFocused ){UINT uState = CONTROL_BTN_NORMAL;UINT uFontState = CONTROL_BTN_NORMAL;//如果当前处于失效状态if( bDisabled ){if( GetCtrlIcon( CONTROL_BTN_DISABLED ) )uState = CONTROL_BTN_DISABLED;uFontState = CONTROL_BTN_DISABLED;}else if( bMoveIn )  //如果当前鼠标在按钮上{if( m_bMouseDown ){if( GetCtrlIcon( CONTROL_BTN_MOUSEDOWN ) )uState = CONTROL_BTN_MOUSEDOWN;uFontState = CONTROL_BTN_MOUSEDOWN;}else{if( GetCtrlIcon( CONTROL_BTN_MOUSEIN ) )uState = CONTROL_BTN_MOUSEIN;uFontState = CONTROL_BTN_MOUSEIN;}}else if( bFocused ){if( GetCtrlIcon( CONTROL_BTN_FOCUS ) )uState = CONTROL_BTN_FOCUS;uFontState = CONTROL_BTN_FOCUS;}Image *pImage = GetCtrlIcon( uState );HFONT hFont = NULL; if(m_bunifyfont == TRUE) //统一使用一种字体Normal{hFont = GetStateFont( CONTROL_BTN_NORMAL );}else{hFont = GetStateFont( uFontState );    }//获得当前按钮文字CString strText;int len = GetWindowTextLength() + 1;GetWindowText( strText.GetBuffer( len ), len );strText.ReleaseBuffer();WTL::CDCHandle dc( hDC );HFONT hOldFont = dc.SelectFont( hFont );//计算文字长度      SIZE sSize;::GetTextExtentPoint32( dc.m_hDC, strText, strText.GetLength(), &sSize );CRect  textRect;if(m_dwQsStyle&BS_BTNTESTTOP){textRect = CRect( 0, 0, cx, cy - cy/2 - m_npost);}else if(m_dwQsStyle & BS_BTNTESTBOTTOM){textRect = CRect( 0, cy - cy/2 + m_npost, cx, cy);}else{textRect = CRect( 0, 0, cx, cy);}Image* pFroegroud = GetForegroudImage();//绘制前景色if(NULL != pFroegroud)  //不考虑字体显示的前景图片{Graphics graph( hDC );graph.SetPageScale( 1.0 );graph.SetPageUnit( UnitPixel ); graph.SetSmoothingMode( SmoothingModeNone );RectF rectf(m_foregrdrect.left,m_foregrdrect.top,m_foregrdrect.Width(),m_foregrdrect.Height());graph.DrawImage( pFroegroud,rectf);//DrawImageEx( graph, pImage, RectF(REAL(left), REAL(top), REAL(pImage->GetWidth()), REAL(pImage->GetHeight())), RectF(0, 0, REAL(pImage->GetWidth()), REAL(pImage->GetHeight())), 5, 5 );graph.ReleaseHDC( hDC );}//绘制图标if( NULL != pImage ){int wth = sSize.cx;wth += ( pImage->GetWidth() + 1 );//            int xtmp = cx - wth;int ytmp = cy - pImage->GetHeight();int left = 5;//( xtmp < 0 ? 0 : xtmp ) / 2;int top = ( ytmp < 0 ? 0 : ytmp ) / 2;Graphics graph( hDC );graph.SetPageScale( 1.0 );graph.SetPageUnit( UnitPixel ); graph.SetSmoothingMode( SmoothingModeNone );//graph.DrawImage( pImage, left, top );DrawImageEx( graph, pImage, RectF(REAL(left), REAL(top), REAL(pImage->GetWidth()), REAL(pImage->GetHeight())), RectF(0, 0, REAL(pImage->GetWidth()), REAL(pImage->GetHeight())), 5, 5 );graph.ReleaseHDC( hDC );textRect = CRect( left + pImage->GetWidth() + 5, 0, left + wth + 5, cy );}//绘制文字if( strText.GetLength() > 0 ){LONG lStyle = GetWindowLong( GWL_STYLE );if(m_bunifycolr == TRUE) //统一使用一种颜色Normal{dc.SetTextColor( GetFontColor( CONTROL_BTN_NORMAL ) );}else{dc.SetTextColor( GetFontColor( uFontState ) );}textRect.left = textRect.left+m_RectText.left;textRect.top = textRect.top+m_RectText.top;textRect.right = textRect.right+m_RectText.right;textRect.bottom = textRect.bottom+m_RectText.bottom;dc.DrawText( strText, -1, &textRect, GetButtonTextFormat( lStyle ) );}dc.SelectFont( hOldFont );::DeleteObject( hFont );}/***@method   DrawImageEx*@brief    *    *@param    Graphics& graph*@param    Image *pImg*@param    RectF rtfPanel*@param    RectF rtfImage*@param    REAL rWidth*@param    REAL rHeight*@return   void*/void DrawImageEx( Graphics& graph, Image *pImg, RectF rtfPanel, RectF rtfImage, REAL rWidth, REAL rHeight ){// 绘制左上角区域RectF rtfLeftUp( rtfPanel.X, rtfPanel.Y, rWidth, rHeight );graph.DrawImage( pImg, rtfLeftUp, rtfImage.X, rtfImage.Y, rWidth, rWidth, UnitPixel );// 绘制上边栏区域RectF rtfMidUp( rtfPanel.X + rWidth, rtfPanel.Y, rtfPanel.Width - 2 * rWidth, rHeight );graph.DrawImage( pImg, rtfMidUp, rtfImage.X + rWidth,rtfImage.Y,rtfImage.Width - 2 * rWidth, rHeight, UnitPixel );// 绘制右上角区域RectF rtfRightUp( rtfPanel.X + rtfPanel.Width - rWidth, rtfPanel.Y, rWidth, rHeight );graph.DrawImage( pImg, rtfRightUp, rtfImage.X + rtfImage.Width - rWidth, rtfImage.Y, rWidth, rHeight, UnitPixel );// 绘制左边区域RectF rtfLeftMid( rtfPanel.X, rtfPanel.Y + rHeight, rWidth, rtfPanel.Height - 2 * rHeight );graph.DrawImage( pImg, rtfLeftMid, rtfImage.X, rHeight, rWidth, rtfImage.Height - 2 * rHeight, UnitPixel );// 绘制中央区域RectF rtfMidMid( rtfPanel.X + rWidth, rtfPanel.Y + rHeight, rtfPanel.Width - 2 * rWidth, rtfPanel.Height - 2 * rHeight );graph.DrawImage( pImg, rtfMidMid, rtfImage.X + rWidth,rtfImage.Y + rHeight,rtfImage.Width - 2 * rWidth, rtfImage.Height - 2 * rHeight, UnitPixel );// 绘制右边区域RectF rtfRightMid( rtfPanel.X + rtfPanel.Width - rWidth, rtfPanel.Y + rHeight, rWidth, rtfPanel.Height - 2 * rHeight );graph.DrawImage( pImg, rtfRightMid, rtfImage.X +rtfImage.Width - rWidth, rtfImage.Y + rHeight, rWidth, rtfImage.Height - 2 * rHeight, UnitPixel );// 绘制左下角区域RectF rtfLeftDown( rtfPanel.X, rtfPanel.Y + rtfPanel.Height - rHeight, rWidth, rHeight );graph.DrawImage( pImg, rtfLeftDown, rtfImage.X, rtfImage.Y + rtfImage.Height - rHeight, rWidth, rWidth, UnitPixel );// 绘制下边栏区域RectF rtfMidDown( rtfPanel.X + rWidth, rtfPanel.Y + rtfPanel.Height - rHeight, rtfPanel.Width - 2 * rWidth, rHeight );graph.DrawImage( pImg, rtfMidDown, rtfImage.X + rWidth,rtfImage.Y + rtfImage.Height - rHeight,rtfImage.Width - 2 * rWidth, rHeight, UnitPixel );// 绘制右上角RectF rtfRightDown( rtfPanel.X + rtfPanel.Width - rWidth, rtfPanel.Y + rtfPanel.Height - rHeight, rWidth, rHeight );graph.DrawImage( pImg, rtfRightDown, rtfImage.X + rtfImage.Width - rWidth, rtfImage.Y + rtfImage.Height - rHeight, rWidth, rHeight, UnitPixel );}};

WTL自绘界面库(CQsButton)相关推荐

  1. 仿迅雷播放器教程 -- C++ windows界面库对比(11)

    从上一篇文章中可以看出,C++的界面方向还很弱,没有任何一个界面库可以一统天下,所以才造成了界面库百家争鸣的情况. 从时间上看: 1.出来最早的是QT,1991年就有了. 2.VC++ 虽然1992年 ...

  2. 【190528】VC++ 纯API自绘图形实现的XP界面库源代码

    源码下载简介 VC++纯API自绘图形实现的XP界面库,这已经是本人水平的最大限度了,尽自己最大的努力用纯VC++代码实现的自绘窗体,没有使用任何的图片资源,虽然是个半成品,但熟知要完成一个功能强大的 ...

  3. 一些界面库比较以及如何选择界面库

    记得很早的时候看了一个哥们写的界面库的使用历程,当时还挺有感触的,不断地尝试,不断地被坑,最后有两条结论: 1.自己积累界面库: 2.买就买贵的.好的,并且提前根据自己需要协商好. 今天又重看关于界面 ...

  4. 仿迅雷播放器教程 -- 权威界面库对比 (8)

    上一个教程对MFC的历史已经介绍很多了,那么界面方面该怎么选择呢? 说起界面,那真是百家争鸣.C++里面其他的都好说,像什么XML解析顶多也就十几个著名开源库而已.Office 操作的开源库仅有几个, ...

  5. 软件开发:界面库详细对比,开发工具的选择指导

    说起界面,那真是百家争鸣.C++里面其他的都好说,像什么XML解析顶多也就十几个著名开源库而已.Office 操作的开源库仅有几个,更可怜的是有个很著名的Office开源库只有JAVA和C#版本,但是 ...

  6. C++ 100款开源界面库——内容细节(现在有变动)不必深究,普及就好

    C++ 100款开源界面库 (10) from:http://www.cnblogs.com/Alberl/p/3375162.html (声明:Alberl以后说到开源库,一般都是指著名的.或者不著 ...

  7. C++开发之界面库资源推荐篇

    开发C++的界面,如果用MFC显得过于传统和呆板,如果是企业应用无所谓,要求没那么高,如果是互联网应用,就显得太单调了,不能容易的写出漂亮的界面,吸引眼球,像QQ,360这种客户端界面怎么开发出来的呢 ...

  8. 仿迅雷播放器教程 -- C++ 100款开源界面库 (10)

    (声明:Alberl以后说到开源库,一般都是指著名的.或者不著名但维护至少3年以上的.那些把代码一扔就没下文的,Alberl不称之为开源库,只称为开源代码.这里并不是贬低,像Alberl前面那个系列的 ...

  9. 以金山界面库(openkui)为例思考和分析界面库的设计和实现——代码结构(完)

    三年前,准备将金山界面库做一个全面的剖析.后来由于种种原因,这个系列被中断而一直没有更新.时过境迁,现在在windows上从事开发的人员越来越少,关注这块的技术的朋友也很少了.本以为这系列也随着技术的 ...

  10. 以金山界面库(openkui)为例思考和分析界面库的设计和实现——问题

    随着物质生活的丰富,人们的精神生活也越来越丰富.人们闲暇的时间也相对变多,于是很多人就开始寻找打发时间的方法.其中电视便是其中一种非常重要的消遣方式.假如我们打开电视机,看到了一个电视台正在播一部我们 ...

最新文章

  1. iOS 学习记录----动画
  2. dubbo配置(一)
  3. JAVA web 会话技术CookieSession
  4. POJ - 3261 Milk Patterns(二分+后缀数组)
  5. 操作系统的起源|开源运动的兴起
  6. win7需要计算机管理员权限,Win7系统提示“需要管理员权限”如何解决?
  7. 虚拟空间,域名解析,A记录,MX记录,CNAME记录,TTL 等 更多Web服务器相关名词解释
  8. 消防信号总线原理_AFPM100/B消防设备电源监控系统在百色市人民医院消防设备电源监控系统的应用-安科瑞 华梅超...
  9. css3-13 css3的3D动画如何实现
  10. 明明是OS问题,却认为是CPU,这个教训是什么
  11. 虚拟蜜罐-honeyd安装部署
  12. 第5章-着色基础-5.4-锯齿和抗锯齿
  13. ALVA Systems发布AR新品 倪光南院士致辞
  14. 一个实际电路的原理图是怎样设计出来的?
  15. java集合源码分析
  16. 财务欺诈研究中常用的违规类型
  17. c语言实现词法分析器+文法分析器(全代码)
  18. 使用自定义字体升级您的 SwiftUI 应用程序教程,如何在 SwiftUI 中添加自定义字体
  19. overridePendingTransition设定两个activity之间的转场动画没有效果,但不报错! (大神帮帮我吧,代码如下,谢谢)
  20. Machine Learning学习笔记(四)EML极限学习机

热门文章

  1. linux ps1详解,Linux-玩转系统提示符PS1
  2. 川希:哪些网站百度收录快排名好,高权重网站必收藏!
  3. Vins-Mono 论文 Coding 一 7(3). pose_graph: 4DOF pose_graph
  4. 2021年海河英才计划天津落户天津最详细过程
  5. 在线教育项目(六)之讲师功能实现
  6. linux中apache无法启动,Apache无法启动
  7. win2003服务器360修复漏洞打不开网页,win7电脑使用360浏览器打不开网页的有效恢复方法...
  8. python搭建网盘网站_搭建nextcloud私有云存储网盘
  9. ECSHOP和SHOPEX快递单号查询中通插件V8.6专版
  10. 2018-2019-2 20165205《网络对抗技术》Exp4 恶意代码分析