hyperlink.cpp

来自「《突破Visual C++.NET编程实例五十讲+源文件,初学者学习的好东东!」· C++ 代码 · 共 596 行 · 第 1/2 页

CPP
596
字号
// HyperLink.cpp : 实现文件
//

#include "stdafx.h"
#include "HLinkTest.h"
#include "HyperLink.h"


// CHyperLink

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define TOOLTIP_ID 1

#define SETBITS(dw, bits)	(dw |= bits)
#define CLEARBITS(dw, bits)	(dw &= ~(bits))
#define BITSET(dw, bit)		(((dw) & (bit)) != 0L)

//下划线位
const DWORD CHyperLink::StyleUnderline		 = 0x00000001;		
//鼠标在控件上方时的颜色位
const DWORD CHyperLink::StyleUseHover		 = 0x00000002;		
//自动尺寸位
const DWORD CHyperLink::StyleAutoSize	  	 = 0x00000004;		
//鼠标按下模式位
const DWORD CHyperLink::StyleDownClick		 = 0x00000008;		
//获得点击焦点位
const DWORD CHyperLink::StyleGetFocusOnClick = 0x00000010;		
//无手形鼠标位
const DWORD CHyperLink::StyleNoHandCursor	 = 0x00000020;		
//无激活颜色位
const DWORD CHyperLink::StyleNoActiveColor	 = 0x00000040;		

COLORREF CHyperLink::g_crLinkColor		= RGB(0, 0, 255);	
COLORREF CHyperLink::g_crActiveColor	= RGB(0, 128, 128);	
COLORREF CHyperLink::g_crVisitedColor	= RGB(128, 0, 128);	
COLORREF CHyperLink::g_crHoverColor		= RGB(255, 0, 0	);	
HCURSOR	 CHyperLink::g_hLinkCursor		= NULL;				




IMPLEMENT_DYNAMIC(CHyperLink, CStatic)
CHyperLink::CHyperLink()
{
	//初始时鼠标未在控件上方
	m_bOverControl		= FALSE;
	//初始时超级链接未被访问
	m_bVisited			= FALSE;
	// 初始时控件不是操作焦点
	m_bLinkActive		= FALSE;
	//初始时设置URL为空字符串
	m_strURL.Empty();
	
	//设置缺省的风格
	m_dwStyle = StyleUnderline|StyleAutoSize|StyleGetFocusOnClick;
}

CHyperLink::~CHyperLink()
{
	 m_Font.DeleteObject();
}


BEGIN_MESSAGE_MAP(CHyperLink, CStatic)
	ON_WM_CTLCOLOR_REFLECT()
	ON_WM_KEYDOWN()
	ON_WM_KILLFOCUS()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_NCHITTEST()
	ON_WM_SETCURSOR()
	ON_WM_SETFOCUS()
END_MESSAGE_MAP()



// CHyperLink 消息处理程序


HBRUSH CHyperLink::CtlColor(CDC* pDC, UINT nCtlColor)
{
	// TODO:  在此更改 DC 的任何属性

	// TODO:  如果不应调用父级的处理程序,则返回非空画笔

	ASSERT(nCtlColor == CTLCOLOR_STATIC);

	if (m_bOverControl && BITSET(m_dwStyle,StyleUseHover))
		pDC->SetTextColor(g_crHoverColor);
	else if (!BITSET(m_dwStyle,StyleNoActiveColor) && m_bLinkActive)
		pDC->SetTextColor(g_crActiveColor);
	else if (m_bVisited)
		pDC->SetTextColor(g_crVisitedColor);
	else
		pDC->SetTextColor(g_crLinkColor);

	// Set transparent drawing mode
	pDC->SetBkMode(TRANSPARENT);
	return (HBRUSH)GetStockObject(NULL_BRUSH);
	//return NULL;
}

void CHyperLink::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (nChar == VK_SPACE)
		FollowLink();
	else
		CStatic::OnKeyDown(nChar, nRepCnt, nFlags);

	//CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CHyperLink::OnKillFocus(CWnd* /*pNewWnd*/)
{
	//CStatic::OnKillFocus(pNewWnd);

	// TODO: 在此添加消息处理程序代码
	m_bOverControl = FALSE;
	m_bLinkActive = FALSE;
	Invalidate();	
}

void CHyperLink::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (BITSET(m_dwStyle,StyleGetFocusOnClick))
		//设置链接焦点,激活超级链接
		SetFocus();				
	if (BITSET(m_dwStyle,StyleDownClick))
		FollowLink();
	//链接处于激活状态,设置标志变量为TRUE
	m_bLinkActive = TRUE;


	//CStatic::OnLButtonDown(nFlags, point);
}

void CHyperLink::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_bLinkActive && !BITSET(m_dwStyle,StyleDownClick))
		FollowLink();

	//CStatic::OnLButtonUp(nFlags, point);
}

void CHyperLink::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_bOverControl)        // Cursor currently over control
	{
		CRect rect;
		GetClientRect(rect);

		if (!rect.PtInRect(point))
		{
			m_bOverControl = FALSE;
			ReleaseCapture();
			Invalidate();						
			return;
		}			
	}
	else                      // Cursor has left control area
	{
		m_bOverControl = TRUE;
		Invalidate();		
		SetCapture();		
	}

	//CStatic::OnMouseMove(nFlags, point);
}

UINT CHyperLink::OnNcHitTest(CPoint /*point*/)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	return HTCLIENT;

	//return CStatic::OnNcHitTest(point);
}

BOOL CHyperLink::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (g_hLinkCursor)
	{
		::SetCursor(g_hLinkCursor);
		return TRUE;
	}
	return FALSE;

	//return CStatic::OnSetCursor(pWnd, nHitTest, message);
}

void CHyperLink::OnSetFocus(CWnd* /*pOldWnd*/)
{
	//CStatic::OnSetFocus(pOldWnd);

	// TODO: 在此添加消息处理程序代码
	m_bLinkActive = TRUE;
	Invalidate();
}

void CHyperLink::PreSubclassWindow()
{
	// TODO: 在此添加专用代码和/或调用基类
	// If the URL string is empty try to set it to the window text
    if (m_strURL.IsEmpty())
        GetWindowText(m_strURL);

    // Check that the window text isn't empty.
	// If it is, set it as URL string.
    CString strWndText;
    GetWindowText(strWndText);
    if (strWndText.IsEmpty()) {
		// Set the URL string as the window text
        ASSERT(!m_strURL.IsEmpty());    // window text and URL both NULL!
		CStatic::SetWindowText(m_strURL);
    }

    // Get the current window font	
    CFont* pFont = GetFont();	
	
	if (pFont != NULL) {
		LOGFONT lf;
		pFont->GetLogFont(&lf);
		lf.lfUnderline = BITSET(m_dwStyle, StyleUnderline);
		if (m_Font.CreateFontIndirect(&lf))
			CStatic::SetFont(&m_Font);    
		// Adjust window size to fit URL if necessary
		AdjustWindow();
	}
	else {		
		// if GetFont() returns NULL then probably the static
		// control is not of a text type: it's better to set
		// auto-resizing off
		CLEARBITS(m_dwStyle,StyleAutoSize);
	}
	
	if (!BITSET(m_dwStyle,StyleNoHandCursor))
		SetDefaultCursor();      // Try to load an "hand" cursor

    // Create the tooltip
    CRect rect; 
    GetClientRect(rect);
    m_ToolTip.Create(this);	

    m_ToolTip.AddTool(this, m_strURL, rect, TOOLTIP_ID);

    CStatic::PreSubclassWindow();

	//CStatic::PreSubclassWindow();
}

BOOL CHyperLink::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	m_ToolTip.RelayEvent(pMsg);
    return CStatic::PreTranslateMessage(pMsg);

	//return CStatic::PreTranslateMessage(pMsg);
}



void CHyperLink::SetColors(	COLORREF crLinkColor,
							COLORREF crActiveColor,
							COLORREF crVisitedColor,
                            COLORREF crHoverColor /* = -1 */) 
{
	g_crLinkColor    = crLinkColor;
	g_crActiveColor	 = crActiveColor;
	g_crVisitedColor = crVisitedColor;	

	if (crHoverColor == -1)
		g_crHoverColor = ::GetSysColor(COLOR_HIGHLIGHT);
	else
		g_crHoverColor = crHoverColor;	
}

void CHyperLink::SetColors(HYPERLINKCOLORS& linkColors) {
	g_crLinkColor	 = linkColors.crLink;
	g_crActiveColor	 = linkColors.crActive;
	g_crVisitedColor = linkColors.crVisited;
	g_crHoverColor	 = linkColors.crHover;
}

void CHyperLink::GetColors(HYPERLINKCOLORS& linkColors) {
	linkColors.crLink = g_crLinkColor;
	linkColors.crActive = g_crActiveColor;
	linkColors.crVisited = g_crVisitedColor;

⌨️ 快捷键说明

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