我们在使用一些小软件时可能会注意到很多软件的版权对话框中都设有超级链接,这些链接或提供制作者的网址,或提供其电子邮件信箱,使软件的使用者能够非常方便地与公司和作者联系,同时也为作者或公司作了很好的宣传。如果能在自己写的软件中实现这个功能,定会使程序大增光彩。那么如何实现这个功能呢? 请看下面介绍:
实现这个功能要用到一个Windows API函数ShellExecute,其原形为:
HINSTANCE ShellExecute(
HWND hwnd, //窗口句柄
LPCTSTR lpOperation, //操作类型
LPCTSTR lpFile, //文件指针
LPCTSTR lpParameters, //文件可带的参数
LPCTSTR lpDirectory, //缺省目录
INT nShowCmd //显示方式
);
ShellExecute函数用于打开或执行一个文件,在调用此函数时只须指定要打开或执行的文件名,而不必管用什么程序去打开或执行文件,
WINDOWS会自动根据要打开或执行的文件去判断该如何执行文件或用什么程序去打开文件。 这个函数可以使用已经在Windows注册的相关程
序打开Windows系统中的文件。例如给出一个URL到lpFile参数中,系统会启动浏览器去浏览网址;给出一个.DOC文档到lpFile中,系统会使用
Word打开这个文档。
以下给出一个完整实例,具体的操作步骤:
1.创建一个基于对话框的应用程序,命名为hyPerlink;
2.打开资源编辑器,在对话框上添加两个static text控件和两个button控件。
Static1和button1并列排放,Static1和button1并列排放。
将static1的ID设为ID_STATIC1,caption设为:计算机世界日报:,button1的ID设为ID_BUTTON1,caption设为:
http://lzw.me,并选中flat属性。将static2的ID设为:ID_STATIC2,caption设为为:给我写信:,button2的ID设为
ID_BUTTON2,caption设为:west_virginia@netease.com,并选中flat属性。
3.创建一个新光标,将其图标编辑成一个手的图像,其ID命名为ID_CURSOR1;
4.给ChyperlinkDlg类增加一个WM_SETCURSOR消息处理函数,其代码如下:
BOOL ChyperlinkDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
CRect rcButton1,rcButton2;
CPoint ptCursor;
CWnd *pStatic1=GetDlgItem(IDC_BUTTON1);
CWnd *pStatic2=GetDlgItem(IDC_BUTTON2);
pStatic1->GetWindowRect (rcButton1);
pStatic2->GetWindowRect (rcButton2);
GetCursorPos(&ptCursor);
if (rcButton1.PtInRect (ptCursor)||rcButton2.PtInRect (ptCursor))
{
CWinApp *pApp=AfxGetApp();
HICON hIconBang=pApp->LoadCursor (IDC_CURSOR1);
SetCursor(hIconBang);
return TRUE;
}
else
return CDialog::OnSetCursor
(pWnd, nHitTest, message);
}
其作用是当鼠标位于button1和button2控件上时,将其形状设为手形。
5、 给IDC_BUTTON1增加BN_CLICKD消息处理函数,代码如下:
void ChyperlinkDlg::OnButton1()
{
// TODO: Add your control notification handler
ShellExecute(m_hWnd,NULL, "http://lzw.me",NULL,NULL,SW_SHOWMAXIMIZED);
}
6、 给IDC_BUTTON2增加BN_CLICKD消息处理函数,代码如下:
void ChyperlinkDlg::OnButton2()
{
// TODO: Add your control notification
ShellExecute(m_hWnd,NULL,"mailto:lzwy0820@qq.com",NULL,NULL,SW_SHOWMAXIMIZED);
}
运行此程序,在对话框上显示计算机世界日报的首页链接和作者的电子邮件地址,在其上点鼠标左键后将自动进入计算机日报首页或启动邮件收发程序给作者写信,效果很理想。读者可在此基础上进一步完善,使其更专业化,也可将其写成类,用起来更方便。
上面写的是一个从无到有的完整制作示例,其实最关键的一句话就是:
ShellExecute(m_hWnd,NULL, “http://lzw.me”,NULL,NULL,SW_SHOWMAXIMIZED);
我们在要实现连接的文本或者按钮上用类向导建立单击事件函数,然后添加上这句话,就可以实现功能了。
ShellExecute是一功能很强大的函数,本文只使用了它的一种用法,更详细全面的用法可参考Visual studio 6.0中所带的MSDN library 。
当然上面我们只是对少数按钮等做简单的连接,如果想做的更好一些,可以自己写一个相关的类来实现更好的应用.下面是一个相关的示例,有兴趣的可以深入研究:
//以下是HyperLink.h头文件
#if !defined(AFX_HYPERLINK_H__61EBFE33_4D61_4851_95A1_68E146E63ED0__INCLUDED_)
#define AFX_HYPERLINK_H__61EBFE33_4D61_4851_95A1_68E146E63ED0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HyperLink.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CHyperLink window
class CHyperLink : public CStatic
{
// Construction
public:
CHyperLink();
// Attributes
public:
HCURSOR m_hLinkCursor;
CFont m_Font;
COLORREF m_LinkColor;
COLORREF m_VisitedColor;
COLORREF m_HoverColor;
CString m_sUrl;
BOOL m_bIsHover;
BOOL m_bIsVisited;
BOOL m_bUnderline;
CToolTipCtrl m_ToolTip;
private:
void SetCursor();
public:
void SetURL(CString sUrl);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHyperLink)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CHyperLink();
// Generated message map functions
protected:
//{{AFX_MSG(CHyperLink)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnClicked();
//}}AFX_MSG
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_Insert_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HYPERLINK_H__61EBFE33_4D61_4851_95A1_68E146E63ED0__INCLUDED_)
//以下是HyperLink.cpp源文件
// HyperLink.cpp : implementation file
//
#i nclude “stdafx.h”
#i nclude “bb.h”
#i nclude “HyperLink.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHyperLink
CHyperLink::CHyperLink()
{
m_hLinkCursor = NULL;
m_LinkColor = RGB(0,0,255);
m_VisitedColor = RGB(0,0,255);
m_HoverColor = RGB(242,101,34);
m_sUrl = “”;
m_bIsHover = false;
m_bIsVisited = false;
m_bUnderline = true;
}
CHyperLink::~CHyperLink()
{
m_Font.DeleteObject();
}
BEGIN_MESSAGE_MAP(CHyperLink, CStatic)
//{{AFX_MSG_MAP(CHyperLink)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHyperLink message handlers
void CHyperLink::OnClicked()
{
HINSTANCE result=ShellExecute(NULL,_T(“open”),m_sUrl,NULL,NULL,SW_SHOW);
m_bIsVisited = true;
}
HBRUSH CHyperLink::CtlColor(CDC* pDC, UINT nCtlColor)
{
ASSERT(nCtlColor==CTLCOLOR_STATIC);
if(m_bIsHover) //鼠标在上面时的颜色
pDC->SetTextColor(m_HoverColor);
else if(m_bIsVisited) //已经打开过一次后的颜色
pDC->SetTextColor(m_VisitedColor);
else //默认颜色
pDC->SetTextColor(m_LinkColor);
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
BOOL CHyperLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if(m_hLinkCursor)
{
::SetCursor(m_hLinkCursor);
return true;
}
return false;
//return CStatic::OnSetCursor(pWnd, nHitTest, message);
}
void CHyperLink::OnMouseMove(UINT nFlags, CPoint point)
{
CStatic::OnMouseMove(nFlags, point);
if(m_bIsHover)
{
CRect rect;
GetClientRect(rect);
if(!rect.PtInRect(point))
{
m_bIsHover = false;
ReleaseCapture();
RedrawWindow();
return;
}
}
else
{
m_bIsHover = true;
RedrawWindow();
SetCapture();
}
}
BOOL CHyperLink::PreTranslateMessage(MSG* pMsg)
{
m_ToolTip.RelayEvent(pMsg);
return CStatic::PreTranslateMessage(pMsg);
}
void CHyperLink::PreSubclassWindow()
{
//设置标签样式
DWORD dwStyle=GetStyle();
::SetWindowLong(GetSafeHwnd(),GWL_STYLE,dwStyle|SS_NOTIFY);
//如果链接的URL为空,则从标签中取出字符当做URL
if(m_sUrl.IsEmpty())
GetWindowText(m_sUrl);
//如果标签文字为空,设置标签文字为URL
CString strWndText;
GetWindowText(strWndText);
if(strWndText.IsEmpty())
SetWindowText(m_sUrl);
//设置标签的下划线
LOGFONT lf;
GetFont()->GetLogFont(&lf);
lf.lfUnderline=m_bUnderline;
m_Font.CreateFontIndirect(&lf);
SetFont(&m_Font);
//得到鼠标样式
SetCursor();
//创建ToolTip对象
CRect rect;
GetClientRect(rect);
m_ToolTip.Create(this);
m_ToolTip.AddTool(this,m_sUrl,rect, 1);
CStatic::PreSubclassWindow();
}
void CHyperLink::SetCursor()
{
if(m_hLinkCursor == NULL)
{
CString strWndDir;
GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH),MAX_PATH);
strWndDir.ReleaseBuffer();
strWndDir+=_T(“\winhlp32.exe”);
HMODULE hModule= LoadLibrary(strWndDir);
if(hModule)
{
HCURSOR hHandCursor=::LoadCursor(hModule,MAKEINTRESOURCE(106));
if(hHandCursor)
m_hLinkCursor=CopyCursor(hHandCursor);
}
::FreeLibrary(hModule);
}
}
void CHyperLink::SetURL(CString sUrl)
{
m_sUrl= sUrl;
if(::IsWindow(GetSafeHwnd()))
m_ToolTip.UpdateTipText(sUrl,this,1);
}
//在对话框类头文件加入以下代码:
#i nclude”hyperlink.h”
public:
CHyperLink m_st; //链接类
//在对话框类源文件以下函数加入代码如下:
void CBbDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CBbDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX,IDC_ST,m_st); //这段代码是增加的,IDC_ST 是静态文本控件ID
//}}AFX_DATA_MAP
}