15,979
社区成员
发帖
与我相关
我的任务
分享
#pragma once
// CStaticButton
class CStaticButton : public CButton
{
DECLARE_DYNAMIC(CStaticButton)
public:
CStaticButton();
virtual ~CStaticButton();
COLORREF SetTextColor( COLORREF crText ) { COLORREF crTextOld = m_crText; m_crText = crText; return crTextOld; };
protected:
//按钮的状态
bool m_bIsPressed, m_bIsFocus, m_bIsMouseOver;
HCURSOR m_hHandCursor;
COLORREF m_crText;
protected:
DECLARE_MESSAGE_MAP()
virtual void PreSubclassWindow();
public:
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
public:
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};
// StaticButton.cpp : 实现文件
//
#include "stdafx.h"
#include "StaticButton.h"
// CStaticButton
IMPLEMENT_DYNAMIC(CStaticButton, CButton)
CStaticButton::CStaticButton() : m_crText( RGB(0,0,255) )
{
m_bIsPressed = m_bIsFocus = m_bIsMouseOver = false;
m_hHandCursor = ::LoadCursor(0, MAKEINTRESOURCE(32649/*IDC_HAND*/));
}
CStaticButton::~CStaticButton()
{
}
BEGIN_MESSAGE_MAP(CStaticButton, CButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_WM_SETCURSOR()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
// CStaticButton 消息处理程序
void CStaticButton::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
ModifyStyle(0,BS_OWNERDRAW);
//SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)m_hHandCursor);
CButton::PreSubclassWindow();
}
void CStaticButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
CDC * pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
int nSavedDC = pDC->SaveDC();
CString strText;
GetWindowText( strText );
CSize szExtent = pDC->GetTextExtent( strText,strText.GetLength() );
CRect rc = lpDrawItemStruct->rcItem;
//COLORREF crReturn=CLR_INVALID;
//HWND hParentWnd=::GetParent(m_hWnd);
//if(hParentWnd)
//{
// HDC hParentDC=::GetDC(hParentWnd);
// if(hParentDC)
// {
// HBRUSH brParentBk =(HBRUSH)::SendMessage(hParentWnd,WM_CTLCOLORDLG,(WPARAM)hParentDC,(LPARAM)hParentWnd);
// if(brParentBk)
// {
// LOGBRUSH lb;
// if(GetObject(brParentBk,sizeof(LOGBRUSH),&lb))
// {
// crReturn = lb.lbColor;
// }
// }
// ::ReleaseDC(hParentWnd,hParentDC);
// }
//}
//pDC->FillSolidRect( rc,crReturn );
//pDC->FillRect( rc,CBrush::FromHandle( (HBRUSH)GetClassLong( this->GetSafeHwnd(),GCL_HBRBACKGROUND ) ) );
pDC->SetBkMode( TRANSPARENT );
pDC->SetTextColor( IsWindowEnabled() ? m_crText : GetSysColor(COLOR_GRAYTEXT) );
CFont font;
CFont * pFont = GetFont();
if ( pFont )
{
LOGFONT lf;
pFont->GetObject( sizeof(lf), &lf );
lf.lfUnderline = m_bIsMouseOver;
font.CreateFontIndirect( &lf );
}
pDC->SelectObject( &font );
LONG lStyle = GetWindowLong(m_hWnd,GWL_STYLE);
if( lStyle & BS_LEFT )
{
rc.left = 0;
}
else if( lStyle & BS_RIGHT)
{
rc.left=rc.right-szExtent.cx;
}
else
{
rc.left += ( rc.Width() - szExtent.cx ) / 2;
}
if( m_bIsPressed )
pDC->TextOut(rc.left+1,(rc.bottom-szExtent.cy)/2+1,strText);
else
pDC->TextOut(rc.left,(rc.bottom-szExtent.cy)/2,strText);
pDC->RestoreDC( nSavedDC );
}
void CStaticButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if( !m_bIsMouseOver )
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE;
m_bIsMouseOver = ( _TrackMouseEvent(&tme) == TRUE );
Invalidate();
CWnd * pParent = GetParent();
if( pParent )
{
CRect rc;
GetWindowRect( rc );
pParent->ScreenToClient( rc );
pParent->InvalidateRect( rc );
}
}
CButton::OnMouseMove(nFlags, point);
}
LRESULT CStaticButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bIsMouseOver = false;
Invalidate();
CWnd * pParent = GetParent();
if( pParent )
{
CRect rc;
GetWindowRect( rc );
pParent->ScreenToClient( rc );
pParent->InvalidateRect( rc );
}
return 0;
}
LRESULT CStaticButton::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
switch( message )
{
case BM_SETSTATE:
if( (UINT)m_bIsPressed != wParam )
{
m_bIsPressed = ( wParam == TRUE );
CWnd * pParent = GetParent();
if( pParent )
{
CRect rc;
GetWindowRect( rc );
pParent->ScreenToClient( rc );
pParent->InvalidateRect( rc );
}
}
break;
default:
break;
}
return CButton::WindowProc(message, wParam, lParam);
}
BOOL CStaticButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
::SetCursor( m_hHandCursor );
return TRUE;
//return CButton::OnSetCursor(pWnd, nHitTest, message);
}
BOOL CStaticButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return TRUE;
//return CButton::OnEraseBkgnd(pDC);
}
为什么从CButton派生而不从CStatic派生:当从CStatic派生时,鼠标左键只要在超连接上按下了就会马上打开链接地址,而不是等鼠标按下并弹起之后再打开链接,从CButton派生即可避免该问题。