概述:
CQsHyperLink 继承与 CHyperLinkImpl,通过自绘来透明背景。已经访问颜色转变。
代码实现如下:
#pragma once
#include "QsInclude.h"
class CQsHyperLink :
public CImageMgrCtrlBase< CQsHyperLink>,
public CHyperLinkImpl<CQsHyperLink>,
public COwnerDraw<CQsHyperLink>
{
typedef CHyperLinkImpl< CQsHyperLink > theBaseClass;
typedef CImageMgrCtrlBase< CQsHyperLink > theImageCtrlBaseClass;
volatile UINT m_uCurState;
volatile bool m_bMouseDown;
BOOL m_bTransBKGnd;
volatile bool m_bMouseTrack;
int m_uFirstPos;
int m_uLastPos;
Color m_color;
Color m_Visitedcolor;
HFONT m_hFont;
public:
BEGIN_MSG_MAP(CQsHyperLink)
MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )
MESSAGE_HANDLER( WM_LBUTTONUP, OnLButtonUp )
MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
CHAIN_MSG_MAP_ALT( COwnerDraw<CQsHyperLink>, 1)
CHAIN_MSG_MAP( theBaseClass )
CHAIN_MSG_MAP( theImageCtrlBaseClass )
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
CQsHyperLink():
m_bMouseDown( false ),
m_uCurState( CONTROL_HLINK_NORMAL ),
m_bTransBKGnd( FALSE ),
m_bMouseTrack( TRUE )
{
m_uFirstPos = CONTROL_HLINK_FIRST;
m_uLastPos = CONTROL_HLINK_LAST;
m_color = Color(255, 60, 36, 118);
m_Visitedcolor = Color(255, 255, 13, 192);
}
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);
}
BOOL SubclassWindow( HWND hWnd )
{
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
dwStyle |= SS_OWNERDRAW;
::SetWindowLong( hWnd, GWL_STYLE, dwStyle );
return theBaseClass::SubclassWindow( hWnd );
}
LRESULT OnLButtonDown( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
m_bMouseDown = true;
Invalidate();
bHandled = FALSE;
return 0;
}
void SetNormalColor(Color color)
{
m_color = color;
}
void SetVisitedColor(Color color)
{
m_Visitedcolor = color;
}
LRESULT OnMouseMove( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
if( m_uCurState != CONTROL_HLINK_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;
}
LRESULT OnMouseLeave( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
if(!m_bMouseTrack)
{
Invalidate();
bHandled = FALSE;
m_bMouseTrack = TRUE;
}
return 0;
}
LRESULT OnLButtonUp( UINT , WPARAM , LPARAM , BOOL& bHandled )
{
m_bMouseDown = false;
Invalidate();
bHandled = FALSE;
return 0;
}
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
int width = lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left;
int height = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;
WTL::CDC memDC;
memDC.CreateCompatibleDC( lpDrawItemStruct->hDC );
WTL::CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap( lpDrawItemStruct->hDC, width, height );
HBITMAP hOldBmp = memDC.SelectBitmap( memBitmap );
memDC.SetBkMode( TRANSPARENT );
::SendMessage( GetParent(), WM_DRAWBKGNDUI, ( WPARAM )memDC.m_hDC, ( LPARAM )lpDrawItemStruct->hwndItem );
RECT rcClient = { 0 };
GetClientRect(&rcClient);
Graphics gra(memDC);
StringFormat fmt;
fmt.SetAlignment(StringAlignmentNear);
fmt.SetLineAlignment(StringAlignmentCenter);
SolidBrush brush(Color( 255, 60, 36, 118 ) );
if ( IsWindowEnabled() )
{
if ( m_bVisited )
{
brush.SetColor( Color(m_Visitedcolor.GetA(), m_Visitedcolor.GetR(), m_Visitedcolor.GetG(), m_Visitedcolor.GetB()) );
}
else
{
brush.SetColor(Color(m_color.GetA(), m_color.GetR(), m_color.GetG(), m_color.GetB()));
}
}
else
{
BYTE a, r, g, b;
DWORD dwGray = ::GetSysColor(COLOR_GRAYTEXT);
a = 255;
b = BYTE(( dwGray >> 16 ) & 0xff);
g = BYTE(( dwGray >> 8 ) & 0xff);
r = BYTE(( dwGray ) & 0xff);
brush.SetColor( Color( a, r, g, b ) );
}
CRect rc;
GetWindowRect( rc );
UINT uFontState = CONTROL_HLINK_NORMAL;
HFONT hFont = GetStateFont( uFontState );
Font fnt(memDC,hFont);
Font fntUnderLine(memDC,hFont);
RectF rtf( REAL(rcClient.left), REAL(rcClient.top-3),REAL(rcClient.right - rcClient.left), REAL(rcClient.bottom - rcClient.top) );
if(IsUsingTags())
{
LPTSTR lpstrLeft = NULL;
int cchLeft = 0;
LPTSTR lpstrLink = NULL;
int cchLink = 0;
LPTSTR lpstrRight = NULL;
int cchRight = 0;
CalcLabelParts(lpstrLeft, cchLeft, lpstrLink, cchLink, lpstrRight, cchRight);
if(lpstrLeft != NULL)
{
if ((m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) )
{
gra.DrawString( lpstrLeft, cchLeft,&fnt, rtf, &fmt, &brush );
}
else
{
gra.DrawString( lpstrLeft, cchLeft,&fntUnderLine, rtf, &fmt, &brush );
}
}
Font fntNormal(memDC,m_hFontNormal);
if(lpstrRight != NULL)
{
gra.DrawString( lpstrRight, cchRight, &fnt, rtf, &fmt, &brush );
}
if(GetFocus() == m_hWnd)
{
::DrawFocusRect(memDC,&m_rcLink);
}
}
else
{
LPTSTR lpstrText = (m_lpstrLabel != NULL) ? m_lpstrLabel : m_lpstrHyperLink;
if(lpstrText != NULL)
{
if ((m_hFont != NULL && (!IsUnderlineHover() || (IsUnderlineHover() && m_bHover))) )
{
gra.DrawString( lpstrText, (INT)_tcslen(lpstrText),
&fnt, rtf, &fmt, &brush );
}
else
{
gra.DrawString( lpstrText, (INT)_tcslen(lpstrText),
&fntUnderLine, rtf, &fmt, &brush );
}
}
if(GetFocus() == m_hWnd)
{
::DrawFocusRect( memDC.m_hDC, &m_rcLink );
}
}
::DeleteObject( hFont );
::BitBlt( lpDrawItemStruct->hDC, 0, 0, width, height, memDC.m_hDC, 0, 0, SRCCOPY );
memDC.SelectBitmap( hOldBmp );
}
};
|