Click here to Skip to main content
15,896,118 members
Articles / Desktop Programming / MFC

Auto-Task Tool for Web Game Travian

Rate me:
Please Sign up or sign in to vote.
4.84/5 (26 votes)
29 Oct 20075 min read 783.8K   7.1K   45  
Developing Auto-Task Tool for Web Game Travian
// HyperLink.cpp : ʵ���ļ�
//

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


// CHyperLink


namespace System
{
	namespace UI
	{


#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;
	// ��ʼʱ�ؼ����Dz�������
	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*/)
LRESULT 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;
	linkColors.crHover = g_crHoverColor;
}

void CHyperLink::SetLinkCursor(HCURSOR hCursor) {
	ASSERT(hCursor != NULL);

	g_hLinkCursor = hCursor;
	if (g_hLinkCursor == NULL)
		SetDefaultCursor();
}

HCURSOR CHyperLink::GetLinkCursor() {
	return g_hLinkCursor;
}

BOOL CHyperLink:: ModifyLinkStyle(DWORD dwRemove, DWORD dwAdd,
								  BOOL bApply /* =TRUE */)
{
	// Check if we are adding and removing the same style
	if ((dwRemove & dwAdd) != 0L)
		return FALSE;

	// Remove old styles and set the new ones
	CLEARBITS(m_dwStyle, dwRemove);
	SETBITS(m_dwStyle, dwAdd);
		
	if (bApply && ::IsWindow(GetSafeHwnd())) {
		// If possible, APPLY the new styles on the fly
		if (BITSET(dwAdd,StyleUnderline) || BITSET(dwRemove,StyleUnderline))
			SwitchUnderline();		
		if (BITSET(dwAdd,StyleAutoSize))
			AdjustWindow();		
		if (BITSET(dwRemove,StyleUseHover))
			Invalidate();
	}
	return TRUE;
}

DWORD CHyperLink::GetLinkStyle() const {
	return m_dwStyle;
}

void CHyperLink::SetURL(CString strURL)
{
	m_strURL = strURL;

	if (::IsWindow(GetSafeHwnd())) {
		ShowWindow(SW_HIDE);
		AdjustWindow();
		m_ToolTip.UpdateTipText(strURL, this, TOOLTIP_ID);
		ShowWindow(SW_SHOW);
	}
}

CString CHyperLink::GetURL() const { 
	return m_strURL;   
}

void CHyperLink::SetWindowText(LPCTSTR lpszText)
{
	ASSERT(lpszText != NULL);

	if (::IsWindow(GetSafeHwnd())) {
		// Set the window text and adjust its size while the window
		// is kept hidden in order to allow dynamic modification
		ShowWindow(SW_HIDE);				// Hide window
		// Call the base class SetWindowText()
		CStatic::SetWindowText(lpszText);
		// Resize the control if necessary
		AdjustWindow();
		ShowWindow(SW_SHOW);				// Show window
	}
}

void CHyperLink::SetFont(CFont* pFont)
{
	ASSERT(::IsWindow(GetSafeHwnd()));
	ASSERT(pFont != NULL);
	
	// Set the window font and adjust its size while the window
	// is kept hidden in order to allow dynamic modification
	ShowWindow(SW_HIDE);				// Hide window
	LOGFONT lf;
	// Create the new font
	pFont->GetLogFont(&lf);
	m_Font.DeleteObject();
	m_Font.CreateFontIndirect(&lf);
	// Call the base class SetFont()
	CStatic::SetFont(&m_Font);
	// Resize the control if necessary
	AdjustWindow();
	ShowWindow(SW_SHOW);				// Show window	
}

// Function to set underline on/off
void CHyperLink::SwitchUnderline()
{	
	LOGFONT lf;
	CFont* pFont = GetFont();
	if (pFont != NULL) {
		pFont->GetLogFont(&lf);		
		lf.lfUnderline = BITSET(m_dwStyle,StyleUnderline);
		m_Font.DeleteObject();
		m_Font.CreateFontIndirect(&lf);
		SetFont(&m_Font);					
	}	
}

// Move and resize the window so that its client area has the same size
// as the hyperlink text. This prevents the hyperlink cursor being active
// when it is not over the text.
void CHyperLink::AdjustWindow()
{	
	ASSERT(::IsWindow(GetSafeHwnd()));
    
	if (!BITSET(m_dwStyle,StyleAutoSize)) 
        return;

    // Get the current window rect
    CRect rcWnd;
    GetWindowRect(rcWnd);

	// For a child CWnd object, window rect is relative to the 
	// upper-left corner of the parent window�s client area. 
    CWnd* pParent = GetParent();
    if (pParent)
        pParent->ScreenToClient(rcWnd);
	
	// Get the current client rect
	CRect rcClient;
	GetClientRect(rcClient);

	// Calc border size based on window and client rects
	int borderWidth = rcWnd.Width() - rcClient.Width();
	int borderHeight = rcWnd.Height() - rcClient.Height();

    // Get the extent of window text 
    CString strWndText;
    GetWindowText(strWndText);
	
    CDC* pDC = GetDC();	
    CFont* pOldFont = pDC->SelectObject(&m_Font);
    CSize Extent = pDC->GetTextExtent(strWndText);
    pDC->SelectObject(pOldFont);
    ReleaseDC(pDC);

    // Get the text justification style
    DWORD dwStyle = GetStyle();

    // Recalc window size and position based on text justification
    if (BITSET(dwStyle, SS_CENTERIMAGE))
		rcWnd.DeflateRect(0, (rcWnd.Height() - Extent.cy) / 2);
    else
		rcWnd.bottom = rcWnd.top + Extent.cy;

    if (BITSET(dwStyle, SS_CENTER))
		rcWnd.DeflateRect((rcWnd.Width() - Extent.cx) / 2, 0);
    else if (BITSET(dwStyle,SS_RIGHT))
		rcWnd.left  = rcWnd.right - Extent.cx;
	else // SS_LEFT
		rcWnd.right = rcWnd.left + Extent.cx;

	// Move and resize the window
	MoveWindow(rcWnd.left, rcWnd.top, rcWnd.Width() + borderWidth,
		rcWnd.Height() + borderHeight);
}

void CHyperLink::SetVisited(BOOL bVisited /* = TRUE */) {
	m_bVisited = bVisited;
}

BOOL CHyperLink::IsVisited() const {
	return m_bVisited;
}

/////////////////////////////////////////////////////////////////////////////
// CHyperLink implementation

// The following function appeared in Paul DiLascia's Jan 1998 
// MSJ articles. It loads a "hand" cursor from "winhlp32.exe"
// resources
void CHyperLink::SetDefaultCursor()
{
	if (g_hLinkCursor == NULL)		// No cursor handle - load our own
	{
        // Get the windows directory
		CString strWndDir;
		GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
		strWndDir.ReleaseBuffer();

		strWndDir += _T("\\winhlp32.exe");
		// This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
		HMODULE hModule = LoadLibrary(strWndDir);
		if (hModule) {
			HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
			if (hHandCursor)
				g_hLinkCursor = CopyCursor(hHandCursor);
		}
		FreeLibrary(hModule);
	}
}

LONG CHyperLink::GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata)
{
    HKEY hkey;
    LONG retval = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey);

    if (retval == ERROR_SUCCESS) {
        long datasize = MAX_PATH;
		TCHAR data[MAX_PATH];
		RegQueryValue(hkey, NULL, data, &datasize);
		lstrcpy(retdata,data);
		RegCloseKey(hkey);
    }

    return retval;
}

// Error report function
void CHyperLink::ReportError(int nError)
{
	CString str;
   
	switch (nError) {
        case 0:                       str = _T("The operating system is out\nof memory or resources."); break;
        case ERROR_FILE_NOT_FOUND:    str = _T("The specified file was not found."); break;
		case ERROR_PATH_NOT_FOUND:	  str = _T("The specified path was not found."); break;	
        case ERROR_BAD_FORMAT:        str = _T("The .EXE file is invalid\n(non-Win32 .EXE or error in .EXE image)."); break;
        case SE_ERR_ACCESSDENIED:     str = _T("The operating system denied\naccess to the specified file."); break;
        case SE_ERR_ASSOCINCOMPLETE:  str = _T("The filename association is\nincomplete or invalid."); break;
        case SE_ERR_DDEBUSY:          str = _T("The DDE transaction could not\nbe completed because other DDE transactions\nwere being processed."); break;
        case SE_ERR_DDEFAIL:          str = _T("The DDE transaction failed."); break;
        case SE_ERR_DDETIMEOUT:       str = _T("The DDE transaction could not\nbe completed because the request timed out."); break;
        case SE_ERR_DLLNOTFOUND:      str = _T("The specified dynamic-link library was not found."); break;
        //case SE_ERR_FNF:			  str = _T("Windows 95 only: The specified file was not found."); break; 
		case SE_ERR_NOASSOC:          str = _T("There is no application associated\nwith the given filename extension."); break;
        case SE_ERR_OOM:              str = _T("There was not enough memory to complete the operation."); break;
    	//case SE_ERR_PNF:              str = _T("The specified path was not found."); break;
		case SE_ERR_SHARE:            str = _T("A sharing violation occurred. "); break;
        default:                      str.Format(_T("Unknown Error (%d) occurred."), nError); break;
    }

	str = "Can't open link:\n\n" + str;
	AfxMessageBox(str, MB_ICONEXCLAMATION | MB_OK);
}

// "GotoURL" function by Stuart Patterson
// As seen in the August, 1997 Windows Developer's Journal.
HINSTANCE CHyperLink::GotoURL(LPCTSTR url, int showcmd)
{
    TCHAR key[MAX_PATH + MAX_PATH];	

    // First try ShellExecute()
    HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, showcmd);

    // If it failed, get the .htm regkey and lookup the program
    if ((UINT)result <= HINSTANCE_ERROR) {		
		
        if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) {
            lstrcat(key, _T("\\shell\\open\\command"));

            if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) {
                TCHAR *pos;
                pos = _tcsstr(key, _T("\"%1\""));
                if (pos == NULL) {                     // No quotes found
                    pos = strstr(key, _T("%1"));       // Check for %1, without quotes
                    if (pos == NULL)                   // No parameter at all...
                        pos = key+lstrlen(key)-1;
                    else
                        *pos = '\0';                   // Remove the parameter
                }
                else
                    *pos = '\0';                       // Remove the parameter

                lstrcat(pos, _T(" "));
                lstrcat(pos, url);
                result = (HINSTANCE) WinExec(key,showcmd);
            }
        }
	}
	  
    return result;
}

// Activate the link
void CHyperLink::FollowLink() 
{	
	int result = (int) GotoURL(m_strURL, SW_SHOW);
    if (result <= HINSTANCE_ERROR) {
        MessageBeep(MB_ICONEXCLAMATION);	// Unable to follow link
        ReportError(result);
    } else {
		// Mark link as visited and repaint window
		m_bVisited = TRUE;		
		Invalidate();
	}
}

}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions