📄 hlink.cpp
字号:
///////////////////////////////////////////////////////////////////////////
// File: hlink.cpp
// Version: 1.1.0.4
// Updated: 19-Jul-1998
//
// Copyright: Ferdinand Prantl, portions by MFC Codeguru "gurus"
// E-mail: prantl@ff.cuni.cz, http://www.codeguru.com
//
// Hyperlink control
//
// You are free to use or modify this code to the following restrictions:
// - Acknowledge me somewhere in your about box, simple "Parts of code by.."
// will be enough. If you can't (or don't want to), contact me personally.
// - LEAVE THIS HEADER INTACT
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#ifndef HLINK_NOOLE
#define INITGUID
#endif
#include "resource.h"
#include "editcmd.h"
#ifndef HLINK_NOOLE
#include <initguid.h>
#endif
#include <winnetwk.h>
#include <winnls.h>
#include <shlobj.h>
#ifndef HLINK_NOOLE
#include <intshcut.h>
#endif
#define FP_SRC_HYPERLINK
#include "hlink.h"
///////////////////////////////// Macros & Statics ///////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////// Implementation //////////////////////////////
#define TOOLTIP_ID 1
BEGIN_MESSAGE_MAP (CHyperlink, CStatic)
ON_WM_CONTEXTMENU ()
//{{AFX_MSG_MAP(CHyperlink)
ON_WM_SETCURSOR ()
ON_WM_LBUTTONDOWN ()
ON_WM_MOUSEMOVE ()
ON_COMMAND (ID_POPUP_OPEN, OnOpen)
ON_COMMAND (ID_POPUP_EDIT, OnEdit)
ON_COMMAND (ID_POPUP_PRINT, OnPrint)
ON_COMMAND (ID_POPUP_COPYSHORTCUT, OnCopyShortcut)
ON_COMMAND (ID_POPUP_PROPERTIES, OnProperties)
ON_WM_CTLCOLOR_REFLECT ()
//}}AFX_MSG_MAP
#ifndef HLINK_NOOLE
ON_COMMAND (ID_POPUP_ADDTOFAVORITES, OnAddToFavorites)
ON_COMMAND (ID_POPUP_ADDTODESKTOP, OnAddToDesktop)
#endif
END_MESSAGE_MAP ()
CHyperlink::CHyperlink ()
{
m_Color = RGB (0, 0, 255);
m_VisitedColor = RGB (128, 0, 128);
m_FailedColor = RGB (128, 128, 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_hBadCursor = AfxGetApp ()->LoadCursor (IDC_HLINK_BAD);
m_hArrowCursor = AfxGetApp ()->LoadStandardCursor (IDC_ARROW);
}
CHyperlink:: ~ CHyperlink ()
{
}
void CHyperlink::
SetHyperLink (const CString & sActualLink)
{
SetActualHyperLink (sActualLink);
}
void CHyperlink::
SetHyperLinkDescription (const CString & sDescription)
{
SetWindowText (sDescription);
}
CString CHyperlink::
GetHyperLinkDescription ()
const
{
CString sDescription;
GetWindowText (sDescription);
return sDescription;
}
void CHyperlink::SetActualHyperLink (const CString & sActualLink)
{
m_sActualLink = sActualLink;
CheckActualHyperLink ();
m_ToolTip.UpdateTipText (m_sToolTip, this, TOOLTIP_ID);
}
void CHyperlink::
CheckActualHyperLink ()
{
int pos = m_sActualLink.Find (_T ('\n'));
if (pos != -1)
{
SetHyperLinkDescription (m_sActualLink.Left (pos));
int pos1 = m_sActualLink.Mid (pos + 1).Find (_T ('\n'));
if (pos1 != -1)
{
m_sToolTip = m_sActualLink.Mid (pos + pos1 + 2);
m_sActualLink = m_sActualLink.Mid (pos + 1, pos1);
}
else
{
m_sActualLink = m_sActualLink.Mid (pos + 1);
m_sToolTip = m_sActualLink;
}
}
}
BOOL CHyperlink::
OnSetCursor (CWnd * /*pWnd */ , UINT /*nHitTest */ , UINT /*message */ )
{
if (m_bShowingContext)
::SetCursor (m_hArrowCursor);
else if (m_State == ST_VISIT_FAILED)
::SetCursor (m_hBadCursor);
else
::SetCursor (m_hLinkCursor);
return TRUE;
}
void CHyperlink::
OnLButtonDown (UINT /*nFlags */ , CPoint /*point */ )
{
PostMessage (WM_COMMAND, ID_POPUP_OPEN);
}
void CHyperlink::
OnOpen ()
{
if (Open ())
m_State = ST_VISITED;
else
m_State = ST_VISIT_FAILED;
}
void CHyperlink::
OnEdit ()
{
if (Open (EDIT))
m_State = ST_VISITED;
else
m_State = ST_VISIT_FAILED;
}
void CHyperlink::
OnPrint ()
{
if (Open (PRINT))
m_State = ST_VISITED;
else
m_State = ST_VISIT_FAILED;
}
void CHyperlink::
SetLinkColor (const COLORREF & color)
{
m_Color = color;
UpdateWindow ();
}
void CHyperlink::
SetVisitedLinkColor (const COLORREF & color)
{
m_VisitedColor = color;
UpdateWindow ();
}
void CHyperlink::
SetHighlightLinkColor (const COLORREF & color)
{
m_HighlightColor = color;
UpdateWindow ();
}
void CHyperlink::
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 CHyperlink::
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 CHyperlink::
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 (IDM_POPUP_HLINK));
CMenu *pPopup = menu.GetSubMenu (0);
ASSERT (pPopup != NULL);
MENUITEMINFO mi;
mi.fMask = MIIM_STATE;
mi.fState = MFS_ENABLED | MFS_DEFAULT;
//VERIFY(SetMenuItemInfo(pPopup->GetSafeHmenu(), ID_POPUP_OPEN, FALSE, &mi));
SetMenuItemInfo (pPopup->GetSafeHmenu (), ID_POPUP_OPEN, FALSE, &mi);
CWnd *pWndPopupOwner = this;
m_bShowingContext = TRUE;
pPopup->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner);
m_bShowingContext = FALSE;
}
void CHyperlink::
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 CHyperlink::
OnProperties ()
{
ShowProperties ();
}
void CHyperlink::
ShowProperties ()
const
{
CHyperlinkSheet propSheet (IDS_HLINK_PROPERTIES, this->GetParent ());
propSheet.m_psh.dwFlags |= PSH_NOAPPLYNOW;
propSheet.SetBuddy (this);
propSheet.DoModal ();
}
BOOL CHyperlink::Open (int how /*= OPEN*/ )
const
{
CWaitCursor cursor;
#ifndef HLINK_NOOLE
//First try to open using IUniformResourceLocator
BOOL bSuccess = OpenUsingCom (how);
//As a last resort try ShellExecuting the URL, may
//even work on Navigator!
if (!bSuccess)
bSuccess = OpenUsingShellExecute (how);
#else
BOOL bSuccess = OpenUsingShellExecute (how);
#endif
if (!bSuccess)
bSuccess = OpenUsingRegisteredClass (how);
return bSuccess;
}
#ifndef HLINK_NOOLE
BOOL CHyperlink::OpenUsingCom (int how /*= OPEN*/ )
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 (_T ("Failed to get the IUniformResourceLocator interface\n"));
return FALSE;
}
hres = pURL->SetURL (m_sActualLink, IURL_SETURL_FL_GUESS_PROTOCOL);
if (!SUCCEEDED (hres))
{
TRACE (_T ("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 ();
switch (how)
{
case OPEN:
ivci.pcszVerb = _T ("open");
break;
case EDIT:
ivci.pcszVerb = _T ("edit");
break;
case PRINT:
ivci.pcszVerb = _T ("print");
break;
default:
ASSERT (FALSE);
}
hres = pURL->InvokeCommand (&ivci);
if (!SUCCEEDED (hres))
{
TRACE (_T ("Failed to invoke URL using InvokeCommand\n"));
pURL->Release ();
return FALSE;
}
// Release the pointer to IUniformResourceLocator.
pURL->Release ();
return TRUE;
}
#endif
BOOL CHyperlink::
OpenUsingShellExecute (int how /*= OPEN*/ )
const
{
LPCTSTR mode;
switch (how)
{
case OPEN:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -