⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hyperlink.cpp

📁 主要用于一般的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// HyperLink.cpp : implementation file
//
// HyperLink static control.
//
// Copyright (C) 1997, 1998 Giancarlo Iovino (giancarlo@saria.com)
// All rights reserved. May not be sold for profit.
//
// This code is based on CHyperlink by Chris Maunder.
// "GotoURL" function by Stuart Patterson appeared in the Aug, 1997
// Windows Developer's Journal.
// "Default hand cursor" from Paul DiLascia's Jan 1998 MSJ article.

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

#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)

// ShellExecute 函数错误报道,nError:错误号
CString ReportError(int nError)
{
	CString str;
   
	switch (nError) {
        case 0:                       str = _T("操作系统内存或资源不够."); break;
        case ERROR_FILE_NOT_FOUND:    str = _T("指定文件找不到."); break;
		case ERROR_PATH_NOT_FOUND:	  str = _T("指定路径找不到."); break;	
        case ERROR_BAD_FORMAT:        str = _T("这个 .EXE 文件非法\n(不是-Win32 .EXE 或 .EXE 镜像错误)."); break;
        case SE_ERR_ACCESSDENIED:     str = _T("操作系统不让访问指定文件."); break;
        case SE_ERR_ASSOCINCOMPLETE:  str = _T("联系文件名不完全或非法."); break;
        case SE_ERR_DDEBUSY:          str = _T("DDE 引用不能完成:\n其他 DDE 引用正在进行."); break;
        case SE_ERR_DDEFAIL:          str = _T("DDE 引用失败."); break;
        case SE_ERR_DDETIMEOUT:       str = _T("DDE 引用不能完成:\n要求时间超出."); break;
        case SE_ERR_DLLNOTFOUND:      str = _T("指定动态链接库找不到."); break;
        //case SE_ERR_FNF:			  str = _T("Windows 95 only: The specified file was not found."); break; 
		case SE_ERR_NOASSOC:          str = _T("指定文件扩展名没有应用程序关联."); break;
        case SE_ERR_OOM:              str = _T("内存不够."); break;
    	//case SE_ERR_PNF:              str = _T("The specified path was not found."); break;
		case SE_ERR_SHARE:            str = _T("发生共享侵犯. "); break;
        default:                      str.Format(_T("发生未知错误 (%d) ."), nError); break;
    }

	return str;
}

/////////////////////////////////////////////////////////////////////////////
// CHyperLink

const DWORD CHyperLink::StyleUnderline		 = 0x00000001;		// 下划线位
const DWORD CHyperLink::StyleUseHover		 = 0x00000002;		// Hand over coloring bit
const DWORD CHyperLink::StyleAutoSize	  	 = 0x00000004;		// Auto size bit
const DWORD CHyperLink::StyleDownClick		 = 0x00000008;		// Down click mode bit
const DWORD CHyperLink::StyleGetFocusOnClick = 0x00000010;		// Get focus on click bit
const DWORD CHyperLink::StyleNoHandCursor	 = 0x00000020;		// No hand cursor bit
const DWORD CHyperLink::StyleNoActiveColor	 = 0x00000040;		// No active color bit
const DWORD CHyperLink::StyleItalic          = 0x00000080;      // 斜体位

COLORREF CHyperLink::g_crLinkColor		= RGB(0, 0, 255);	// Blue
COLORREF CHyperLink::g_crActiveColor	= RGB(0, 128, 128);	// Dark cyan
COLORREF CHyperLink::g_crVisitedColor	= RGB(128, 0, 128);	// Purple
COLORREF CHyperLink::g_crHoverColor		= RGB(255, 0, 0	);	// Red
HCURSOR	 CHyperLink::g_hLinkCursor		= NULL;				// No cursor


CHyperLink::CHyperLink()
{
	m_bOverControl		= FALSE;	// Cursor not yet over control
	m_bVisited			= FALSE;	// Link has not been visited yet
	m_bLinkActive		= FALSE;	// Control doesn't own the focus yet
	m_strURL.Empty();				// Set URL to an empty string		
	// Set default styles
	m_dwStyle = StyleAutoSize|StyleGetFocusOnClick|StyleUseHover;
}

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

IMPLEMENT_DYNAMIC(CHyperLink, CStatic)

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

/////////////////////////////////////////////////////////////////////////////
// CHyperLink message handlers

BOOL CHyperLink::PreTranslateMessage(MSG* pMsg) 
{
    m_ToolTip.RelayEvent(pMsg);
    return CStatic::PreTranslateMessage(pMsg);
}

void CHyperLink::PreSubclassWindow() 
{		    
	// 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();
}

// Handler for WM_CTLCOLOR reflected message (see message map)
HBRUSH CHyperLink::CtlColor(CDC* pDC, UINT nCtlColor) 
{		
	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);
}

void CHyperLink::OnMouseMove(UINT nFlags, CPoint point) 
{

	static BOOL UnderLine=FALSE;

	if (m_bOverControl)        //Cursor currently  over control
	{
		CRect rect;
		GetClientRect(rect);

		if (!rect.PtInRect(point))
		{
			m_bOverControl = FALSE;
			ReleaseCapture();
			Invalidate();						
			
			if (!UnderLine)
			{
				UnderLine=FALSE;
				CLEARBITS(m_dwStyle,StyleUnderline);
				SwitchFont();
			}  			
			return;
		}			
	}
	else                      // Cursor has left control area
	{
		m_bOverControl = TRUE;

		if (BITSET(m_dwStyle,StyleUnderline)==0)
		{
			SETBITS(m_dwStyle,StyleUnderline);
			SwitchFont();
			SetCapture();		
		}
		else
		{
			UnderLine=TRUE;
			Invalidate();		
			SetCapture();		
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// "Normally, a static control does not get mouse events unless it has
// SS_NOTIFY. This achieves the same effect as SS_NOTIFY, but it's fewer
// lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
// because Windows doesn't send WM_CTLCOLOR to bitmap static controls."
// (Paul DiLascia)
UINT CHyperLink::OnNcHitTest(CPoint /*point*/) 
{
		return HTCLIENT;	
}

void CHyperLink::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/) 
{
	if (BITSET(m_dwStyle,StyleGetFocusOnClick))
		SetFocus();				// Set the focus and make the link active
	if (BITSET(m_dwStyle,StyleDownClick))
		FollowLink();
	m_bLinkActive = TRUE;
}

void CHyperLink::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/) 
{
	if (m_bLinkActive && !BITSET(m_dwStyle,StyleDownClick))
		FollowLink();
}

BOOL CHyperLink::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/) 
{	
	if (g_hLinkCursor)
	{
		::SetCursor(g_hLinkCursor);
		return TRUE;
	}
	return FALSE;
}

void CHyperLink::OnSetFocus(CWnd* /*pOldWnd*/) 
{
	m_bLinkActive = TRUE;
	Invalidate();							// Repaint to set the focus
}

void CHyperLink::OnKillFocus(CWnd* /*pNewWnd*/) 
{	
	// Assume that control lost focus = mouse out
	// this avoid troubles with the Hover color
	m_bOverControl = FALSE;
	m_bLinkActive = FALSE;
	Invalidate();							// Repaint to unset the focus
}

void CHyperLink::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{	
	if (nChar == VK_SPACE)
		FollowLink();
	else
		CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
}

/////////////////////////////////////////////////////////////////////////////
// CHyperLink operations

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

	if (crHoverColor == -1)

⌨️ 快捷键说明

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