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

📄 hlinkctl.cpp

📁 VC各工程的源码集合
💻 CPP
字号:
/*
Module : HLINKCTRL.CPP
Purpose: Implementation for a MFC class for a static text control class with hyperlink support
Created: PJN / HLINK/1 / 16-06-1997
History: PJN /         / 24-06-1997, hyperlinks are now coloured ala IE
         PJN /         / 15-07-1997, Now supports ShrinkToFit
         PJN           / 11-09-1997, Added support for a highlight look
                                     which includes a highlight color and
                                     a shadowed look. Also fixed a bug 
                                     relating to the Edit controls context
                                     menu.
                                     Also included is a new context menu ala IE3
         PJN           / 06-11-1997, 1) Improved drawing of control by handling WM_CTLCOLOR through MFC message reflection
                                     2) class now derived from CStatic as it should have been from the begining
                                     3) Dropped support for shrink to fit as now no need
                                     4) Description is now taken from controls window text
                                     5) Now using more standard visited and unvisted colors
                                     6) Dropped support for optional underlying and drop shadow effects
                                     7) streamlined some of the functions declarations
                                     8) Wait cursor is now shown when a shortcut is being saved
                                     9) Context menu for control can now be turned off if so desired
         PJN           / 08-12-1997, 1) Removed ON_COMMAND(ID_POPUP_OPEN, OnOpen) from #define which was causing 
                                        to the hyperlink correctly
                                     2) Removed a level 4 warning which was being generated when building in release mode  
         PJN           / 09-01-1998  1) Removed duplicate OnAddToFavorites and OnAddToDesktop functions


Copyright (c) 1997 by PJ Naughter.  
All rights reserved.

*/

/////////////////////////////////  Includes  //////////////////////////////////

#include "stdafx.h"

#ifndef HLINK_NOOLE
#define INITGUID
#endif
#include "resource.h"
#include "hlinkctl.h"
#ifndef HLINK_NOOLE
#include <initguid.h>
#endif
#include <winnetwk.h>
#include <winnls.h>
#include <shlobj.h>
#ifndef HLINK_NOOLE
#include <intshcut.h>
#endif



/////////////////////////////////  Macros & Statics ///////////////////////////

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


///////////////////////////////// Implementation //////////////////////////////


BEGIN_MESSAGE_MAP(CHLinkCtrl, CStatic)
	ON_WM_CONTEXTMENU()
	//{{AFX_MSG_MAP(CHLinkCtrl)
  ON_WM_SETCURSOR()
  ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_COMMAND(ID_POPUP_COPYSHORTCUT, OnCopyShortcut)
	ON_COMMAND(ID_POPUP_PROPERTIES, OnProperties)
	//}}AFX_MSG_MAP
	ON_WM_CTLCOLOR_REFLECT()
  ON_COMMAND(ID_POPUP_OPEN, OnOpen)
#ifndef HLINK_NOOLE
	ON_COMMAND(ID_POPUP_ADDTOFAVORITES, OnAddToFavorites)
  ON_COMMAND(ID_POPUP_ADDTODESKTOP, OnAddToDesktop)
#endif
END_MESSAGE_MAP()


CHLinkCtrl::CHLinkCtrl()
{
	m_Color = RGB(0, 0, 255);
	m_VisitedColor = RGB(128, 0, 128);
	m_HighlightColor = RGB(255, 0, 0);

	m_bShrinkToFit = TRUE;
  m_bUseHighlight = TRUE;
	m_State = ST_NOT_VISITED;
  m_OldState = ST_NOT_VISITED;
  m_bShowingContext = FALSE;
  m_bAllowContextMenu = TRUE;

	//Load up the cursors
	m_hLinkCursor = AfxGetApp()->LoadCursor(IDC_HLINK);
  m_hArrowCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
}


CHLinkCtrl::~CHLinkCtrl()
{
}


void CHLinkCtrl::SetHyperLink(const CString& sActualLink)
{
	SetActualHyperLink(sActualLink);
}


void CHLinkCtrl::SetHyperLinkDescription(const CString& sDescription)
{
  SetWindowText(sDescription);
}


CString CHLinkCtrl::GetHyperLinkDescription() const
{
  CString sDescription;
  GetWindowText(sDescription);
  return sDescription;
}


void CHLinkCtrl::SetActualHyperLink(const CString& sActualLink)
{
	m_sActualLink = sActualLink;
}


BOOL CHLinkCtrl::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/) 
{
  if (m_bShowingContext)
    ::SetCursor(m_hArrowCursor);
  else
  	::SetCursor(m_hLinkCursor);
	return TRUE;
}


void CHLinkCtrl::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/) 
{
  PostMessage(WM_COMMAND, ID_POPUP_OPEN);
}


void CHLinkCtrl::OnOpen()
{
  if (Open())
	  m_State = ST_VISITED;
}


void CHLinkCtrl::SetLinkColor(const COLORREF& color) 
{ 
	m_Color = color; 
	UpdateWindow(); 
}


void CHLinkCtrl::SetVisitedLinkColor(const COLORREF& color) 
{ 
	m_VisitedColor = color; 
	UpdateWindow(); 
}


void CHLinkCtrl::SetHighlightLinkColor(const COLORREF& color) 
{ 
	m_HighlightColor = color; 
	UpdateWindow(); 
}


void CHLinkCtrl::OnMouseMove(UINT nFlags, CPoint point) 
{
  if (!m_bUseHighlight)
    return;

	CRect rc;
	GetClientRect(rc);
	if (rc.PtInRect(point))
	{
		if (m_State != ST_HIGHLIGHTED)
		{
			SetCapture();
			HighLight(TRUE);
		} 
	}
	else
	{
		if (m_State == ST_HIGHLIGHTED)
		{
			HighLight(FALSE);
			ReleaseCapture();
		}
	}
	
	CStatic::OnMouseMove(nFlags, point);
}


void CHLinkCtrl::HighLight(BOOL state)
{
	if (state)
	{
		if (m_State != ST_HIGHLIGHTED)
		{
			m_OldState = m_State;
			m_State = ST_HIGHLIGHTED;
			Invalidate();
		}
	}
	else
	{
		if (m_State == ST_HIGHLIGHTED)
		{
			m_State = m_OldState;
			Invalidate();
		}
	}
}


void CHLinkCtrl::OnContextMenu(CWnd*, CPoint point)
{
  if (!m_bAllowContextMenu)
    return;

  HighLight(FALSE);
	ReleaseCapture();
  
	if (point.x == -1 && point.y == -1)
  {		//keystroke invocation		CRect rect;		GetClientRect(rect);		ClientToScreen(rect);		point = rect.TopLeft();		point.Offset(5, 5);	}	CMenu menu;	VERIFY(menu.LoadMenu(IDR_HLINK_POPUP));	CMenu* pPopup = menu.GetSubMenu(0);	ASSERT(pPopup != NULL);	CWnd* pWndPopupOwner = this;
  m_bShowingContext = TRUE;	pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,		pWndPopupOwner);
  m_bShowingContext = FALSE;
}


void CHLinkCtrl::OnCopyShortcut() 
{
  if (OpenClipboard())
  {
    int nBytes = sizeof(TCHAR) * (m_sActualLink.GetLength() + 1);
    HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, nBytes);
    TCHAR* pData = (TCHAR*) GlobalLock(hMem);
    _tcscpy(pData, (LPCTSTR) m_sActualLink);
    GlobalUnlock(hMem);
  	SetClipboardData(CF_TEXT, hMem);
    CloseClipboard();
  }
}


void CHLinkCtrl::OnProperties() 
{
	ShowProperties();
}


void CHLinkCtrl::ShowProperties() const
{
	CHLinkSheet propSheet(IDS_HLINK_PROPERTIES, this->GetParent());
  propSheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
  propSheet.SetBuddy(this);
  propSheet.DoModal();
}


BOOL CHLinkCtrl::Open() const
{
  CWaitCursor cursor;

#ifndef HLINK_NOOLE
  //First try to open using IUniformResourceLocator
  BOOL bSuccess = OpenUsingCom();
  
  //As a last resort try ShellExecuting the URL, may
  //even work on Navigator!
  if (!bSuccess)
    bSuccess = OpenUsingShellExecute();
#else
  BOOL bSuccess = OpenUsingShellExecute();
#endif

  return bSuccess;
}


#ifndef HLINK_NOOLE
BOOL CHLinkCtrl::OpenUsingCom() const
{
  //Get the URL Com interface
  IUniformResourceLocator* pURL;
  HRESULT hres = CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (void**) &pURL);
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed to get the IUniformResourceLocator interface\n");
    return FALSE;
  }

  hres = pURL->SetURL(m_sActualLink, IURL_SETURL_FL_GUESS_PROTOCOL);
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed in call to SetURL\n");
    pURL->Release();
    return FALSE;
  }

  //Open the URL by calling InvokeCommand
  URLINVOKECOMMANDINFO ivci;
  ivci.dwcbSize = sizeof(URLINVOKECOMMANDINFO);
  ivci.dwFlags = IURL_INVOKECOMMAND_FL_ALLOW_UI;
  ivci.hwndParent = GetParent()->GetSafeHwnd();
  ivci.pcszVerb = "open";
  hres = pURL->InvokeCommand(&ivci);
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed to invoke URL using InvokeCommand\n");
    pURL->Release();
    return FALSE;
  }

  // Release the pointer to IUniformResourceLocator.
  pURL->Release();

  return TRUE;
}
#endif


BOOL CHLinkCtrl::OpenUsingShellExecute() const
{
	HINSTANCE hRun = ShellExecute(GetParent()->GetSafeHwnd(), _T("open"), m_sActualLink, NULL, NULL, SW_SHOW);
  if ((int) hRun <= 32)
  {
    TRACE("Failed to invoke URL using ShellExecute\n");
    return FALSE;
  }

  return TRUE;
}


#ifndef HLINK_NOOLE
BOOL CHLinkCtrl::AddToSpecialFolder(int nFolder) const
{
  //Give the user some feedback
  CWaitCursor cursor;

  // Get the shell's allocator. 
  IMalloc* pMalloc;
  if (!SUCCEEDED(SHGetMalloc(&pMalloc))) 
  {
    TRACE("Failed to get the shell's IMalloc interface\n");
    return FALSE;
  }

  //Get the location of the special Folder required
  LPITEMIDLIST pidlFolder;
  HRESULT hres = SHGetSpecialFolderLocation(NULL, nFolder, &pidlFolder); 
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed in call to SHGetSpecialFolderLocation\n");
    pMalloc->Release();
    return FALSE;
  }

  //convert the PIDL to a file system name and
  //add an extension of URL to create an Internet 
  //Shortcut file
  TCHAR sFolder[_MAX_PATH];
  if (!SHGetPathFromIDList(pidlFolder, sFolder))
  {
    TRACE("Failed in call to SHGetPathFromIDList");
    pMalloc->Release();
    return FALSE;
  }
  TCHAR sShortcutFile[_MAX_PATH];  

  CString sLinkDescription;
  GetWindowText(sLinkDescription);
  _tmakepath(sShortcutFile, NULL, sFolder, sLinkDescription, _T("URL"));

  //Free the pidl
  pMalloc->Free(pidlFolder);

  //Do the actual saving
  BOOL bSuccess = Save(sShortcutFile);

  // Release the pointer to IMalloc
  pMalloc->Release(); 

  return bSuccess;
}
#endif


#ifndef HLINK_NOOLE
void CHLinkCtrl::OnAddToFavorites() 
{
  AddToSpecialFolder(CSIDL_FAVORITES);
} 
#endif


#ifndef HLINK_NOOLE
void CHLinkCtrl::OnAddToDesktop() 
{
  AddToSpecialFolder(CSIDL_DESKTOP);
} 
#endif


#ifndef HLINK_NOOLE
BOOL CHLinkCtrl::Save(const CString& sFilename) const
{
  //Get the URL Com interface
  IUniformResourceLocator* pURL;
  HRESULT hres = CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (void**) &pURL);
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed to get the IUniformResourceLocator interface\n");
    return FALSE;
  }

  hres = pURL->SetURL(m_sActualLink, IURL_SETURL_FL_GUESS_PROTOCOL);
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed in call to SetURL\n");
    pURL->Release();
    return FALSE;
  }

  // Get the IPersistFile interface for 
  // saving the shortcut in persistent storage.
  IPersistFile* ppf;
  hres = pURL->QueryInterface(IID_IPersistFile, (void **)&ppf);
  if (!SUCCEEDED(hres))
  {
    TRACE("Failed to get the IPersistFile interface\n");
    pURL->Release();
    return FALSE;
  }

  // Save the shortcut via the IPersistFile::Save member function.
  #ifndef _UNICODE
  WORD wsz[_MAX_PATH];
  MultiByteToWideChar(CP_ACP, 0, sFilename, -1, wsz, _MAX_PATH);
  hres = ppf->Save(wsz, TRUE);
  #else
  hres = ppf->Save(sFilename, TRUE);
  #endif
  if (!SUCCEEDED(hres))
  {
    TRACE("IPersistFile::Save failed!\n");
    ppf->Release();
    pURL->Release();
    return FALSE;
  }

  // Release the pointer to IPersistFile.
  ppf->Release();

  // Release the pointer to IUniformResourceLocator.
  pURL->Release();

  return TRUE;
} 
#endif


#ifdef _DEBUG
HBRUSH CHLinkCtrl::CtlColor(CDC* pDC, UINT nCtlColor) 
#else
HBRUSH CHLinkCtrl::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
#endif
{
	ASSERT(nCtlColor == CTLCOLOR_STATIC);

	DWORD dwStyle = GetStyle();
	if (!(dwStyle & SS_NOTIFY)) 
  {
		// Turn on notify flag to get mouse messages and STN_CLICKED.
		// Otherwise, I'll never get any mouse clicks!
		::SetWindowLong(m_hWnd, GWL_STYLE, dwStyle | SS_NOTIFY);
	}
	

	HBRUSH hbr = NULL;
	if ((dwStyle & 0xFF) <= SS_RIGHT) 
  {
		// Modify the font to be underline
    if (!((HFONT) m_font))
    {
		  LOGFONT lf;
		  GetFont()->GetObject(sizeof(lf), &lf);

		  lf.lfUnderline = TRUE;
		  m_font.CreateFontIndirect(&lf);
    }
		pDC->SelectObject(&m_font);


    //set the text colors
    switch (m_State)
    {
		  case ST_NOT_VISITED:	pDC->SetTextColor(m_Color); break;
		  case ST_VISITED:	  	pDC->SetTextColor(m_VisitedColor); break;
		  case ST_HIGHLIGHTED:	pDC->SetTextColor(m_HighlightColor); break;
      default: ASSERT(FALSE);
    }
		pDC->SetBkMode(TRANSPARENT);

		// return hollow brush to preserve parent background color
		hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
	}

	return hbr;
}






/*IMPLEMENT_DYNCREATE(CHLinkPage, CPropertyPage)


CHLinkPage::CHLinkPage() : CPropertyPage(CHLinkPage::IDD)
{
	//{{AFX_DATA_INIT(CHLinkPage)
	//}}AFX_DATA_INIT
  m_pBuddy = NULL;
}


CHLinkPage::~CHLinkPage()
{
}

void CHLinkPage::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CHLinkPage)
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CHLinkPage, CPropertyPage)
	//{{AFX_MSG_MAP(CHLinkPage)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()




IMPLEMENT_DYNAMIC(CHLinkSheet, CPropertySheet)

CHLinkSheet::CHLinkSheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
  AddPage(&m_page1);
}


CHLinkSheet::CHLinkSheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
	:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
  AddPage(&m_page1);
}


CHLinkSheet::~CHLinkSheet()
{
}


BEGIN_MESSAGE_MAP(CHLinkSheet, CPropertySheet)
	//{{AFX_MSG_MAP(CHLinkSheet)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


BOOL CHLinkPage::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	
	ASSERT(m_pBuddy);
  GetDlgItem(IDC_NAME)->SetWindowText(m_pBuddy->GetHyperLinkDescription());
  GetDlgItem(IDC_URL)->SetWindowText(m_pBuddy->GetActualHyperLink());

	return TRUE;
}
*/

⌨️ 快捷键说明

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