在VC中为应用程序添加图形超链接功能
2008-11-14 19:35:28 来源:WEB开发网(8)显示文件或文件夹的属性
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:"; //can be a file as well
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
Windows还提供了一个与ShellExecuteEx()函数相类似的函数WinExec(),它相对于ShellExecuteEx()来说更简单易用,只是功能没有它强大而已,具体使用方法读者朋友自行参阅MSDN。
二、编程步骤
l、启动Visual C++6.0,生成一个基于对话框的应用程序,将该程序命名为"Test";
2、在对话框上放置一个静态控件,并显示一幅图象;
3、使用Class Wizard为应用程序添加一个CMapHyperLink类,其基类为CStatic;
4、在对话框中添加一个CmapHyperLink类对象m_MapHyperLink1;
5、添加代码,编译运行程序。
三、程序代码
/////////////////////////////////////////////////////////////////////////
//MapHyperLink.h , MapHyperLink.cpp
#if !defined(AFX_HYPERLINK_H__D1625061_574B_11D1_ABBA_00A0243D1382__INCLUDED_)
#define AFX_HYPERLINK_H__D1625061_574B_11D1_ABBA_00A0243D1382__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// CHyperLink window
class CMapHyperLink : public CStatic
{
// Construction/destruction
public:
CMapHyperLink();
virtual ~CMapHyperLink();
public:
void SetURL(CString strURL);
CString GetURL() const;
void SetTipText(CString strURL);
CString GetTipText() const;
void SetVisited(BOOL bVisited = TRUE);
BOOL GetVisited() const;
void SetLinkCursor(HCURSOR hCursor);
HCURSOR GetLinkCursor() const;
void SetAutoSize(BOOL bAutoSize = TRUE);
BOOL GetAutoSize() const;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHyperLink)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
protected:
HINSTANCE GotoURL(LPCTSTR url, int showcmd);
void ReportError(int nError);
LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata);
void PositionWindow();
void SetDefaultCursor();
// Protected attributes
protected:
BOOL m_bOverControl; // cursor over control?
BOOL m_bVisited; // Has it been visited?
BOOL m_bAdjustToFit; // Adjust window size to fit text?
CString m_strURL; // hyperlink URL
CString m_strTipText; // TipTool control' text
HCURSOR m_hLinkCursor; // Cursor for hyperlink
CToolTipCtrl m_ToolTip; // The tooltip
protected: // Generated message map functions
//{{AFX_MSG(CHyperLink)
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
afx_msg void OnClicked();
DECLARE_MESSAGE_MAP()
};
#endif
///////////////////////////////////////////////////////////// MapHyperLink.cpp
#include "stdafx.h"
#include "MapHyperLink.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TOOLTIP_ID 1
CMapHyperLink::CMapHyperLink()
{
m_hLinkCursor = NULL; // No cursor as yet
m_bOverControl = FALSE; // Cursor not yet over control
m_bVisited = FALSE; // Hasn't been visited yet.
m_bAdjustToFit = TRUE; // Resize the window to fit the text?
m_strURL.Empty();
m_strTipText.Empty();
}
CMapHyperLink::~CMapHyperLink()
{}
BEGIN_MESSAGE_MAP(CMapHyperLink, CStatic)
//{{AFX_MSG_MAP(CMapHyperLink)
ON_CONTROL_REFLECT(STN_CLICKED, OnClicked)
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CMapHyperLink message handlers
BOOL CMapHyperLink::PreTranslateMessage(MSG* pMsg)
{
m_ToolTip.RelayEvent(pMsg);
return CStatic::PreTranslateMessage(pMsg);
}
void CMapHyperLink::OnClicked()
{
int result = (int)GotoURL(m_strURL, SW_SHOW);
m_bVisited = (result > HINSTANCE_ERROR);
if (!m_bVisited) {
MessageBeep(MB_ICONEXCLAMATION); // Unable to follow link
ReportError(result);
} else
SetVisited(); // Repaint to show visited colour
}
void CMapHyperLink::OnMouseMove(UINT nFlags, CPoint point)
{
CStatic::OnMouseMove(nFlags, point);
if (m_bOverControl) // Cursor is currently over control
{
CRect rect;
GetClientRect(rect);
if (!rect.PtInRect(point))
{
m_bOverControl = FALSE;
ReleaseCapture();
RedrawWindow();
return;
}
}
else // Cursor has just moved over control
{
m_bOverControl = TRUE;
RedrawWindow();
SetCapture();
}
}
BOOL CMapHyperLink::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/)
{
if (m_hLinkCursor)
{
::SetCursor(m_hLinkCursor);
return TRUE;
}
return FALSE;
}
void CMapHyperLink::PreSubclassWindow()
{
// We want to get mouse clicks via STN_CLICKED
DWORD dwStyle = GetStyle();
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
SetDefaultCursor(); // Try and load up a "hand" cursor
// Create the tooltip
CRect rect;
GetClientRect(rect);
m_ToolTip.Create(this);
if (m_strTipText.IsEmpty())
{
m_strTipText = m_strURL;
}
m_ToolTip.AddTool(this, m_strTipText, rect, TOOLTIP_ID);
CStatic::PreSubclassWindow();
}
////////////////////////////////////////////// CMapHyperLink operations
void CMapHyperLink::SetURL(CString strURL)
{
m_strURL = strURL;
if (::IsWindow(GetSafeHwnd())) {
PositionWindow();
if (m_strTipText.IsEmpty())
{
m_strTipText = strURL;
}
m_ToolTip.UpdateTipText(m_strTipText, this, TOOLTIP_ID);
}
}
CString CMapHyperLink::GetURL() const
{
return m_strURL;
}
void CMapHyperLink::SetTipText(CString strTipText)
{
m_strTipText = strTipText;
if (::IsWindow(GetSafeHwnd())) {
PositionWindow();
m_ToolTip.UpdateTipText(m_strTipText, this, TOOLTIP_ID);
}
}
CString CMapHyperLink::GetTipText() const
{
return m_strTipText;
}
void CMapHyperLink::SetVisited(BOOL bVisited /* = TRUE */)
{
m_bVisited = bVisited;
if (::IsWindow(GetSafeHwnd()))
Invalidate();
}
BOOL CMapHyperLink::GetVisited() const
{
return m_bVisited;
}
void CMapHyperLink::SetLinkCursor(HCURSOR hCursor)
{
m_hLinkCursor = hCursor;
if (m_hLinkCursor == NULL)
SetDefaultCursor();
}
HCURSOR CMapHyperLink::GetLinkCursor() const
{
return m_hLinkCursor;
}
void CMapHyperLink::SetAutoSize(BOOL bAutoSize /* = TRUE */)
{
m_bAdjustToFit = bAutoSize;
if (::IsWindow(GetSafeHwnd()))
PositionWindow();
}
BOOL CMapHyperLink::GetAutoSize() const
{
return m_bAdjustToFit;
}
// Move and resize the window so that the window is the same size
void CMapHyperLink::PositionWindow()
{
if (!::IsWindow(GetSafeHwnd()) || !m_bAdjustToFit)
return;
// Get the current window position
CRect rect;
GetWindowRect(rect);
CWnd* pParent = GetParent();
if (pParent)
pParent->ScreenToClient(rect);
CRect rectMap;
GetClientRect(rectMap);
// Get the text justification via the window style
DWORD dwStyle = GetStyle();
// Recalc the window size and position based on the text justification
if (dwStyle & SS_CENTERIMAGE)
rect.DeflateRect(0, (rect.Height() - rectMap.Height())/2);
else
rect.bottom = rect.top + rectMap.Height();
if (dwStyle & SS_CENTER)
rect.DeflateRect((rect.Width() - rectMap.Width())/2, 0);
else if (dwStyle & SS_RIGHT)
rect.left = rect.right - rectMap.Width();
else // SS_LEFT = 0, so we can't test for it explicitly
rect.right = rect.left + rectMap.Width();
// Move the window
SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
}
/////////////////////////////////////////////////// CMapHyperLink implementation
void CMapHyperLink::SetDefaultCursor()
{
if (m_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)
m_hLinkCursor = CopyCursor(hHandCursor);
}
FreeLibrary(hModule);
}
}
LONG CMapHyperLink::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;
}
void CMapHyperLink::ReportError(int nError)
{
CString str;
switch (nError) {
case 0:
str = "The operating system is outnof memory or resources."; break;
case SE_ERR_PNF:
str = "The specified path was not found."; break;
case SE_ERR_FNF:
str = "The specified file was not found."; break;
case ERROR_BAD_FORMAT:
str = "The .EXE file is invalidn(non-Win32 .EXE or error in .EXE image)."; break;
case SE_ERR_ACCESSDENIED:
str = "The operating system deniednaccess to the specified file."; break;
case SE_ERR_ASSOCINCOMPLETE:
str = "The filename association isnincomplete or invalid."; break;
case SE_ERR_DDEBUSY:
str = "The DDE transaction could notnbe completed because other DDE transactionsnwere being processed."; break;
case SE_ERR_DDEFAIL:
str = "The DDE transaction failed."; break;
case SE_ERR_DDETIMEOUT:
str = "The DDE transaction could notnbe completed because the request timed out."; break;
case SE_ERR_DLLNOTFOUND:
str = "The specified dynamic-link library was not found."; break;
case SE_ERR_NOASSOC:
str = "There is no application associatednwith the given filename extension."; break;
case SE_ERR_OOM:
str = "There was not enough memory to complete the operation."; break;
case SE_ERR_SHARE:
str = "A sharing violation occurred. ";
default:
str.Format("Unknown Error (%d) occurred.", nError); break;
}
str = "Unable to open hyperlink:nn" + str;
AfxMessageBox(str, MB_ICONEXCLAMATION | MB_OK);
}
HINSTANCE CMapHyperLink::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("shellopencommand"));
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 = ''; // Remove the parameter
}
else
*pos = ''; // Remove the parameter
lstrcat(pos, _T(" "));
lstrcat(pos, url);
result = (HINSTANCE) WinExec(key,showcmd);
}
}
}
return result;
}
/////////////////////////////////////////////////////////////////////////////////////
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//设置图形的超链接
m_MapHyperLink1.SetURL("www.yesky.com");
m_MapHyperLink1.SetTipText("欢迎访问天极网");
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
四、小结
本实例通过介绍如何实现超链接功能,介绍了工具提示、动态地从可执行文件中加载图标、使用外壳函数ShellExecute()等知识,甚至还包括注册表的操作等内容,应该说虽然程序比较简单,但包含的内容还是比较丰富的。最后,运行此程序,将在对话框上显示"天极网"的首页链接,在图像上点鼠标左键后将自动进入天极网首页,效果很理想。
更多精彩
赞助商链接