123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- // ButtonExt.cpp: implementation of the CButtonExt class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "ButtonExt.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- UINT CButtonExt::m_nStatus = STATUS_BUTTON_NORMAL;
- WNDPROC CButtonExt::m_cWndProc = NULL;
- CArray<int,int>g_btnarray;
- //按钮的状态
- BOOL m_bOver=0; //鼠标位于按钮之上时该值为true,反之为flase
- BOOL m_bTracking=0; //在鼠标按下没有释放时该值为true
- BOOL m_bSelected=0; //按钮被按下是该值为true
- BOOL m_bFocus=0; //按钮为当前焦点所在时该值为true
- //按钮的外边框
- extern CPen m_BoundryPen;
- //鼠标指针置于按钮之上时按钮的内边框
- extern CPen m_InsideBoundryPenLeft;
- extern CPen m_InsideBoundryPenRight;
- extern CPen m_InsideBoundryPenTop;
- extern CPen m_InsideBoundryPenBottom;
- //按钮获得焦点时按钮的内边框
- extern CPen m_InsideBoundryPenLeftSel;
- extern CPen m_InsideBoundryPenRightSel;
- extern CPen m_InsideBoundryPenTopSel;
- extern CPen m_InsideBoundryPenBottomSel;
- //按钮的底色,包括有效和无效两种状态
- extern CBrush m_FillActive;
- extern CBrush m_FillInactive;
- //绘制按钮的底色
- void CButtonExt::DoGradientFill(CDC *pDC, CRect* rect)
- {
- return;
- CBrush brBk[64];
- int nWidth = rect->Width();
- int nHeight = rect->Height();
- CRect rct;
- int i = 0;
- for ( i = 0; i < 64; i ++)
- {
- if (m_bOver)
- {
- if (m_bFocus)
- brBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 3)));
- else
- brBk[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)));
- else
- brBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 5)));
- }
- }
- for (i = rect->top; i <= nHeight + 2; i ++)
- {
- rct.SetRect(rect->left, i, nWidth + 2, i + 1);
- pDC->FillRect(&rct, &brBk[((i * 63) / nHeight)]);
- }
- for (i = 0; i < 64; i ++)
- brBk[i].DeleteObject();
- }
- //绘制按钮的内边框
- void CButtonExt::DrawInsideBorder(CDC *pDC, CRect* rect)
- {
- CPen *pLeft, *pRight, *pTop, *pBottom;
- if (m_bSelected && !m_bOver)
- {
- pLeft = & m_InsideBoundryPenLeftSel;
- pRight = &m_InsideBoundryPenRightSel;
- pTop = &m_InsideBoundryPenTopSel;
- pBottom = &m_InsideBoundryPenBottomSel;
- }
- 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->LineTo(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(oldPoint);
- if (m_bSelected && !m_bOver)
- DrawFocusRect(pDC->m_hDC,rect);
- }
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- int FindBtnPos(int hwnd)
- {
- for(int i=0; i<g_btnarray.GetSize (); i++)
- {
- if(hwnd==g_btnarray.ElementAt (i))return i;
- }
- return -1;
- }
- LRESULT CButtonExt::DefWindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
- {
- CWnd *pWnd = NULL;
- CPoint point;
- pWnd = CWnd::FromHandle( hWnd );
- switch( message )
- {
- case WM_CREATE:
- g_btnarray.Add ((int)hWnd);
- g_btnarray.Add (0);
- g_btnarray.Add (0);
- g_btnarray.Add (0);
- g_btnarray.Add (0);
- break;
- case WM_DESTROY:
- {
- int pos=FindBtnPos((int)hWnd);
- g_btnarray.RemoveAt(pos);
- g_btnarray.RemoveAt(pos);
- g_btnarray.RemoveAt(pos);
- g_btnarray.RemoveAt(pos);
- g_btnarray.RemoveAt(pos);
- }
- break;
- case WM_MOUSEMOVE:
- {
- int pos=FindBtnPos((int)hWnd);
- m_bTracking=g_btnarray.ElementAt (pos+2);
- if (!m_bTracking)
- {
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(tme);
- tme.hwndTrack = hWnd;
- tme.dwFlags = TME_LEAVE | TME_HOVER;
- tme.dwHoverTime = 1;
- m_bTracking = _TrackMouseEvent(&tme);
- g_btnarray.SetAt (pos+2, m_bTracking);
- }
- }
- break;
- case WM_MOUSELEAVE:
- {
- int pos=FindBtnPos((int)hWnd);
- m_bOver = FALSE;
- m_bTracking = FALSE;
- g_btnarray.SetAt (pos+1, m_bOver);
- g_btnarray.SetAt (pos+2, m_bTracking);
- pWnd->Invalidate();
- }
- break;
- case WM_MOUSEHOVER:
- {
- int pos=FindBtnPos((int)hWnd);
- m_bOver = 1;
- g_btnarray.SetAt (pos+1, m_bOver);
- pWnd->Invalidate();
- }
- break;
- case WM_PAINT:
- // case WM_LBUTTONDBLCLK:
- return OnPaint( pWnd );
- break;
- /* case WM_LBUTTONDOWN:
- point.x = LOWORD(lParam);
- point.y = HIWORD(lParam);
- return OnLButtonDown( pWnd, 0, point );
- break;
- case WM_LBUTTONUP:
- point.x = LOWORD(lParam);
- point.y = HIWORD(lParam);
- return OnLButtonUp( pWnd, 0, point );
- break;
- case WM_MOUSEMOVE:
- point.x = LOWORD(lParam);
- point.y = HIWORD(lParam);
- return OnMouseMove( pWnd, 0, point );
- break;
- case WM_ERASEBKGND:
- return TRUE;
- break;
- case WM_ENABLE:
- {
- pWnd->Invalidate();
- return FALSE;
- }
- break;*/
- default:
- break;
- }
- return CallWindowProc( m_cWndProc, hWnd, message, wParam, lParam );
- }
- LRESULT CButtonExt::OnLButtonDown( CWnd *pWnd, UINT nFlags, CPoint point )
- {
- m_nStatus = STATUS_BUTTON_DOWN;
- // m_bOver=1; //鼠标位于按钮之上时该值为true,反之为flase
- // m_bTracking=1; //在鼠标按下没有释放时该值为true
- // m_bSelected=1; //按钮被按下是该值为true
- // m_bFocus=1; //按钮为当前焦点所在时该值为true
- pWnd->Invalidate();
- pWnd->UpdateWindow();
- return TRUE;
- }
- LRESULT CButtonExt::OnLButtonUp( CWnd *pWnd, UINT nFlags, CPoint point )
- {
- ReleaseCapture();
- m_nStatus = STATUS_BUTTON_NORMAL;
- pWnd->Invalidate();
- pWnd->UpdateWindow();
- SendMessage( pWnd->GetParent()->m_hWnd, WM_COMMAND, pWnd->GetDlgCtrlID(), (LPARAM) (pWnd->m_hWnd) );
- return TRUE;
- }
- LRESULT CButtonExt::OnMouseMove( CWnd *pWnd, UINT nFlags, CPoint point )
- {
- HRGN hRgn = CreateRectRgn( 0, 0, 0, 0 );
- pWnd->GetWindowRgn( hRgn );
- BOOL bIn = PtInRegion( hRgn, point.x, point.y );
- if( bIn )
- {
- if(CWnd::GetCapture()==pWnd)return 1;
- if( m_nStatus != STATUS_BUTTON_HOVER )
- {
- m_nStatus = STATUS_BUTTON_HOVER;
- pWnd->Invalidate();
- pWnd->UpdateWindow();
- pWnd->SetCapture();
- }
- }
- else
- {
- //if ( m_nStatus == STATUS_BUTTON_HOVER )
- //{
- m_nStatus = STATUS_BUTTON_NORMAL;
- pWnd->Invalidate();
- pWnd->UpdateWindow();
- ReleaseCapture();
- //}
- }
- DeleteObject( hRgn );
- return TRUE;
- }
- LRESULT CButtonExt::OnPaint( CWnd *pWnd )
- {
- CRect rect ;//= lpDrawItemStruct->rcItem;
- pWnd->GetClientRect( &rect );
- CPaintDC dc(pWnd);
- CDC *pDC=&dc;
- int nSaveDC=pDC->SaveDC();
- int pos=FindBtnPos((int)pWnd->GetSafeHwnd ());
- m_bOver=g_btnarray.ElementAt (pos+1);
- m_bTracking=g_btnarray.ElementAt (pos+2);
- m_bSelected=g_btnarray.ElementAt (pos+3);
- m_bFocus=g_btnarray.ElementAt (pos+4);
- POINT pt ;
- TCHAR strText[MAX_PATH + 1];
- ::GetWindowText(pWnd->GetSafeHwnd (), strText, MAX_PATH);
- //画按钮的外边框,它是一个半径为5的圆角矩形
- pt.x = 5;
- pt.y = 5;
- CPen* hOldPen = pDC->SelectObject(&m_BoundryPen);
- pDC->RoundRect(&rect, pt);
- pDC->SelectObject(hOldPen);
- rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
- //根据按钮的状态填充按钮的底色
- CBrush* pOldBrush;
- if (m_bOver)
- {
- pOldBrush = pDC->SelectObject(&m_FillActive);
- DoGradientFill(pDC, &rect);
- }
- else
- {
- pOldBrush = pDC->SelectObject(&m_FillInactive);
- DoGradientFill(pDC, &rect);
- }
- //根据按钮的状态绘制内边框
- if (m_bOver || m_bSelected)
- DrawInsideBorder(pDC, &rect);
- pDC->SelectObject(pOldBrush);
- //显示按钮的文本
- if (strText!=NULL)
- {
- CFont* hFont = pWnd->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);
- short state=GetKeyState(VK_LBUTTON);
- BYTE sta=(BYTE)(state>>8);
- if (m_bTracking && sta)//state & ODS_SELECTED)
- pt.Offset(1, 1);
- int nMode = pDC->SetBkMode(TRANSPARENT);
- if (pWnd->IsWindowEnabled ()==0)
- pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
- else
- pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
- pDC->SelectObject(hOldFont);
- pDC->SetBkMode(nMode);
- }
- pDC->RestoreDC(nSaveDC);
- /* CPaintDC dc(pWnd);
- CString cs;
- RECT rc;
- CFont Font;
- CFont *pOldFont;
- CBrush Brush;
- CBrush *pOldBrush;
- CPen Pen;
- CPen *pOldPen;
- POINT pt;
- pt.x = 2;
- pt.y = 2;
- if(!pWnd->IsWindowEnabled ())m_nStatus = STATUS_BUTTON_DOWN;
- dc.SetBkMode( TRANSPARENT );
- Font.CreateFont( 14, 0, 0, 0, FW_HEAVY, 0, 0, 0, ANSI_CHARSET, \
- OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \
- VARIABLE_PITCH | FF_SWISS, "黑体" );
- pOldFont = dc.SelectObject( &Font );
- if( m_nStatus == STATUS_BUTTON_DOWN ) {
- Brush.CreateSolidBrush( RGB( 160, 160, 160 ) );
- Pen.CreatePen( PS_SOLID, 1, RGB( 100, 100, 100 ) );
- dc.SetTextColor( RGB( 50, 50, 250 ) );
- } else if( m_nStatus == STATUS_BUTTON_HOVER ) {
- Brush.CreateSolidBrush( RGB( 60, 60, 180 ) );
- Pen.CreatePen( PS_SOLID, 1, RGB( 0, 0, 0 ) );
- dc.SetTextColor( RGB( 250, 250, 50 ) );
- } else if( m_nStatus == STATUS_BUTTON_NORMAL )
- {
- Brush.CreateSolidBrush( RGB( 240, 240, 240 ) );
- Pen.CreatePen( PS_SOLID, 1, RGB( 120, 120, 120 ) );
- dc.SetTextColor( RGB( 50, 50, 50 ) );
- }
- pOldBrush = dc.SelectObject( &Brush );
- pOldPen = dc.SelectObject( &Pen );
- pWnd->GetClientRect( &rc );
- dc.RoundRect( &rc, pt );
- HRGN hRgn = CreateRectRgn( rc.left, rc.top, rc.right, rc.bottom );
- pWnd->SetWindowRgn( hRgn, TRUE );
- DeleteObject( hRgn );
- pWnd->GetWindowText( cs );
- dc.DrawText( cs, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE );
- dc.SelectObject( pOldFont );
- dc.SelectObject( pOldBrush );
- dc.SelectObject( pOldPen );
- m_nStatus = STATUS_BUTTON_NORMAL;*/
- return TRUE;
- }
|