VC超级链接的设计与实现
2013-11-22 10:46
302 查看
在许多软件中,都有一个联系联系作者本人或者软件提供者的超链接,点击这个超链接可以向作者或软件提供者发送邮件或打开某个网页浏览信息,给软件的使用者带很大的方便。本文尝试设计和实现一个超级链接的功能,使它不仅能满足上面得功能,还能根据使用者的喜好在超链接的文本上采用不同的字体。
1.设计原理
CStatic类是从CWnd类继承出来的一个静态文本框类,它对应静态文本框控件。静态文本框控件常用来在对话框上显示软件信息或者是提示信息。本例采用重载CStatic类的方法,用类的成员函数完成上面的功能。
2.具体实现
使用类向导生成一个基类为CStatic的CHyperLinker类。
在CHyperLinker.h文件中,添加类的如下成员变量:
// Attributes
public:
COLORREF m_InitColor; // 超级链接开始时的文本颜色
COLORREF m_VisitedColor; // 超级链接被访问过的的文本颜色
COLORREF m_CoverColor; // 鼠标移动到超级链接文本框上的文本颜色
BOOL m_bAboveControl; // 记录当前鼠标是否停留在超级链接上方
BOOL m_bVisited; // 记录超级链接是否被访问过
BOOL m_bUnderLine; // 文本是否带下划线
CString m_sURL; //
URL信息
CFont m_Font; //
字体
HCURSOR m_hLinkCursor; // 鼠标形状
在CHyperLinker.h文件中,添加类的如下成员函数声明:
// Operations
public:
// 设置对应文本框属性值
void SetAttrbute(CString url = "www.baidu.com", COLORREF InitColor = RGB(0,0,255),
COLORREF VisitedColor = RGB(255,0,0),
COLORREF CoverColor = RGB(125,125,0), BOOL bUnderLine = TRUE);
// shell 外部的程序
BOOL OpenUsingShellExecute();
// 设置字体
void SetFont(CFont *font);
// Generated message map functions
protected:
//{{AFX_MSG(CHyperLinker)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
在CHyperLinker.cpp中添加如下的函数定义:
CHyperLinker::CHyperLinker()
{
m_bAboveControl = FALSE;
m_bUnderLine = FALSE;
m_bVisited = FALSE;
}
CHyperLinker::~CHyperLinker()
{
}
BEGIN_MESSAGE_MAP(CHyperLinker, CStatic)
//{{AFX_MSG_MAP(CHyperLinker)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_CTLCOLOR_REFLECT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHyperLinker message handlers
void CHyperLinker::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
GetClientRect(rect); // 得到当前文本框的矩形区域
static BOOL bIsIn = FALSE; // 判断前一次鼠标是否已经在文本框区域
if (rect.PtInRect(point)) // 在区域内
{
m_bAboveControl = TRUE; // 记录鼠标已经停留在超级链接文本框的上方
if (!bIsIn) // 如果是第一次停留,则用其他颜色重绘文本
{
SetCapture(); // 设置鼠标捕获
bIsIn = TRUE;
Invalidate(); // 调用CtrlColor重绘文本
}
}
else
{
m_bAboveControl = FALSE; // 记录鼠标不在超级链接文本框的上方
if (bIsIn) // 如果是第一次离开区域,则用其他颜色重绘文本
{
ReleaseCapture(); // 释放鼠标捕获
bIsIn = FALSE;
Invalidate(); //
调用CtrlColor重绘文本
}
}
CStatic::OnMouseMove(nFlags, point);
}
void CHyperLinker::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
OpenUsingShellExecute(); // shell外部程序
m_bVisited = TRUE; // 表示应经点击过超级链接文本框
Invalidate(); // 调用CtrlColor重绘文本
CStatic::OnLButtonDown(nFlags, point);
}
BOOL CHyperLinker::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
HCURSOR LinkCurlor = ::AfxGetApp()->LoadCursor(IDC_CUR_HAND);
::SetCursor(LinkCurlor);
return TRUE;
return CStatic::OnSetCursor(pWnd, nHitTest, message);
}
HBRUSH CHyperLinker::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
ASSERT(nCtlColor == CTLCOLOR_STATIC);
DWORD dwStyle = GetStyle();
if (!(dwStyle & SS_NOTIFY))
{
::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 = m_bUnderLine;
m_Font.CreateFontIndirect(&lf);
}
pDC->SelectObject(&m_Font);
// set the text color
if (m_bVisited)
{
pDC->SetTextColor(m_VisitedColor);
}
else
{
if (m_bAboveControl)
{
pDC->SetTextColor(m_CoverColor);
}
else
{
pDC->SetTextColor(m_InitColor);
}
}
pDC->SetBkMode(TRANSPARENT);
hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
}
// TODO: Return a non-NULL brush if the parent's handler should not be called
return hbr;
}
void CHyperLinker::SetAttrbute(CString url, COLORREF InitColor, COLORREF VisitedColor,
COLORREF CoverColor, BOOL bUnderLine)
{
m_sURL = url;
m_InitColor = InitColor;
m_VisitedColor = VisitedColor;
m_CoverColor = CoverColor;
m_bUnderLine = bUnderLine;
}
BOOL CHyperLinker::OpenUsingShellExecute()
{
HINSTANCE hRun = ShellExecute(GetParent()->GetSafeHwnd(),
_T("open"), m_sURL, NULL, NULL, SW_SHOW);
if((int)hRun <= 32)
{
AfxMessageBox(_T("提供的超级链接或者指定的文件无法执行"), MB_OK, 0);
return FALSE;
}
return TRUE;
}
void CHyperLinker::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
DWORD dwStyle = GetStyle();
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY); // 设置动态窗口属性
CStatic::PreSubclassWindow();
}
void CHyperLinker::SetFont(CFont *font)
{
// 设置字体
memcpy(&m_Font, font, sizeof(CFont));
// 根据字体的长度和宽度设置静态框的长度和宽度
CDC *pDC = GetDC();
CFont *pOldfont = pDC->SelectObject(&m_Font);
CString str;
GetWindowText(str);
CSize size = pDC->GetTextExtent(str, str.GetLength());
SetWindowPos(NULL, 0, 0, size.cx, size.cy, SWP_NOMOVE);
pDC->SelectObject(pOldfont);
ReleaseDC(pDC);
}
注:IDC_CUR_HAND是自己添加的鼠标资源,Windows NT 5.0以后的版本可已使用IDC_HAND
3.应用实例
利用MFC AppWizard 生成一个基于对话框的项目,在对话框上添加三个Static控件,修改ID分别为IDC_LINKER、IDC_LOCALFILE和IDC_NET,用Class Wizard 为这三个控件生成3个CHyperLinker对象,在对话框InitDialog函数中添加如下的代码:
// TODO: Add extra initialization here
m_linker.SetAttrbute("http://blog.sina.com.cn/luoshuquan108");// 链接到我的博客
m_localfile.SetAttrbute("E:\musics\Helloween - Forever and One.mp3");// 打开本地文件
CFont *font = new CFont;
font->CreatePointFont(200, "微软雅黑");
m_net.SetAttrbute("mailto:luoshuquan108@hotmail.com");// 给我发邮件
m_net.SetFont(font); // 设置字体
运行效果如下:
参考资料:《Visual C++ 网络通信编程使用案例精选》 人民邮电出版社 丁展 刘海英等编著
ISBN-7-115-12164-8/TP·3903
1.设计原理
CStatic类是从CWnd类继承出来的一个静态文本框类,它对应静态文本框控件。静态文本框控件常用来在对话框上显示软件信息或者是提示信息。本例采用重载CStatic类的方法,用类的成员函数完成上面的功能。
2.具体实现
使用类向导生成一个基类为CStatic的CHyperLinker类。
在CHyperLinker.h文件中,添加类的如下成员变量:
// Attributes
public:
COLORREF m_InitColor; // 超级链接开始时的文本颜色
COLORREF m_VisitedColor; // 超级链接被访问过的的文本颜色
COLORREF m_CoverColor; // 鼠标移动到超级链接文本框上的文本颜色
BOOL m_bAboveControl; // 记录当前鼠标是否停留在超级链接上方
BOOL m_bVisited; // 记录超级链接是否被访问过
BOOL m_bUnderLine; // 文本是否带下划线
CString m_sURL; //
URL信息
CFont m_Font; //
字体
HCURSOR m_hLinkCursor; // 鼠标形状
在CHyperLinker.h文件中,添加类的如下成员函数声明:
// Operations
public:
// 设置对应文本框属性值
void SetAttrbute(CString url = "www.baidu.com", COLORREF InitColor = RGB(0,0,255),
COLORREF VisitedColor = RGB(255,0,0),
COLORREF CoverColor = RGB(125,125,0), BOOL bUnderLine = TRUE);
// shell 外部的程序
BOOL OpenUsingShellExecute();
// 设置字体
void SetFont(CFont *font);
// Generated message map functions
protected:
//{{AFX_MSG(CHyperLinker)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
在CHyperLinker.cpp中添加如下的函数定义:
CHyperLinker::CHyperLinker()
{
m_bAboveControl = FALSE;
m_bUnderLine = FALSE;
m_bVisited = FALSE;
}
CHyperLinker::~CHyperLinker()
{
}
BEGIN_MESSAGE_MAP(CHyperLinker, CStatic)
//{{AFX_MSG_MAP(CHyperLinker)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_CTLCOLOR_REFLECT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHyperLinker message handlers
void CHyperLinker::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
GetClientRect(rect); // 得到当前文本框的矩形区域
static BOOL bIsIn = FALSE; // 判断前一次鼠标是否已经在文本框区域
if (rect.PtInRect(point)) // 在区域内
{
m_bAboveControl = TRUE; // 记录鼠标已经停留在超级链接文本框的上方
if (!bIsIn) // 如果是第一次停留,则用其他颜色重绘文本
{
SetCapture(); // 设置鼠标捕获
bIsIn = TRUE;
Invalidate(); // 调用CtrlColor重绘文本
}
}
else
{
m_bAboveControl = FALSE; // 记录鼠标不在超级链接文本框的上方
if (bIsIn) // 如果是第一次离开区域,则用其他颜色重绘文本
{
ReleaseCapture(); // 释放鼠标捕获
bIsIn = FALSE;
Invalidate(); //
调用CtrlColor重绘文本
}
}
CStatic::OnMouseMove(nFlags, point);
}
void CHyperLinker::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
OpenUsingShellExecute(); // shell外部程序
m_bVisited = TRUE; // 表示应经点击过超级链接文本框
Invalidate(); // 调用CtrlColor重绘文本
CStatic::OnLButtonDown(nFlags, point);
}
BOOL CHyperLinker::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
HCURSOR LinkCurlor = ::AfxGetApp()->LoadCursor(IDC_CUR_HAND);
::SetCursor(LinkCurlor);
return TRUE;
return CStatic::OnSetCursor(pWnd, nHitTest, message);
}
HBRUSH CHyperLinker::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
ASSERT(nCtlColor == CTLCOLOR_STATIC);
DWORD dwStyle = GetStyle();
if (!(dwStyle & SS_NOTIFY))
{
::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 = m_bUnderLine;
m_Font.CreateFontIndirect(&lf);
}
pDC->SelectObject(&m_Font);
// set the text color
if (m_bVisited)
{
pDC->SetTextColor(m_VisitedColor);
}
else
{
if (m_bAboveControl)
{
pDC->SetTextColor(m_CoverColor);
}
else
{
pDC->SetTextColor(m_InitColor);
}
}
pDC->SetBkMode(TRANSPARENT);
hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
}
// TODO: Return a non-NULL brush if the parent's handler should not be called
return hbr;
}
void CHyperLinker::SetAttrbute(CString url, COLORREF InitColor, COLORREF VisitedColor,
COLORREF CoverColor, BOOL bUnderLine)
{
m_sURL = url;
m_InitColor = InitColor;
m_VisitedColor = VisitedColor;
m_CoverColor = CoverColor;
m_bUnderLine = bUnderLine;
}
BOOL CHyperLinker::OpenUsingShellExecute()
{
HINSTANCE hRun = ShellExecute(GetParent()->GetSafeHwnd(),
_T("open"), m_sURL, NULL, NULL, SW_SHOW);
if((int)hRun <= 32)
{
AfxMessageBox(_T("提供的超级链接或者指定的文件无法执行"), MB_OK, 0);
return FALSE;
}
return TRUE;
}
void CHyperLinker::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
DWORD dwStyle = GetStyle();
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY); // 设置动态窗口属性
CStatic::PreSubclassWindow();
}
void CHyperLinker::SetFont(CFont *font)
{
// 设置字体
memcpy(&m_Font, font, sizeof(CFont));
// 根据字体的长度和宽度设置静态框的长度和宽度
CDC *pDC = GetDC();
CFont *pOldfont = pDC->SelectObject(&m_Font);
CString str;
GetWindowText(str);
CSize size = pDC->GetTextExtent(str, str.GetLength());
SetWindowPos(NULL, 0, 0, size.cx, size.cy, SWP_NOMOVE);
pDC->SelectObject(pOldfont);
ReleaseDC(pDC);
}
注:IDC_CUR_HAND是自己添加的鼠标资源,Windows NT 5.0以后的版本可已使用IDC_HAND
3.应用实例
利用MFC AppWizard 生成一个基于对话框的项目,在对话框上添加三个Static控件,修改ID分别为IDC_LINKER、IDC_LOCALFILE和IDC_NET,用Class Wizard 为这三个控件生成3个CHyperLinker对象,在对话框InitDialog函数中添加如下的代码:
// TODO: Add extra initialization here
m_linker.SetAttrbute("http://blog.sina.com.cn/luoshuquan108");// 链接到我的博客
m_localfile.SetAttrbute("E:\musics\Helloween - Forever and One.mp3");// 打开本地文件
CFont *font = new CFont;
font->CreatePointFont(200, "微软雅黑");
m_net.SetAttrbute("mailto:luoshuquan108@hotmail.com");// 给我发邮件
m_net.SetFont(font); // 设置字体
运行效果如下:
参考资料:《Visual C++ 网络通信编程使用案例精选》 人民邮电出版社 丁展 刘海英等编著
ISBN-7-115-12164-8/TP·3903
相关文章推荐
- VC超级链接的设计与实现 (通过CHyperLinker类来实现)
- VC超级链接的设计与实现 (通过CHyperLinker类来实现)
- 如何去掉图片点击后的超级链接产生的虚框问题(两种实现方法)
- 利用jquery实现链接文字截断显示,超级方便
- VC++实现获取所有的TCP与UDP链接
- 实现超级链接
- vc动态升级模块的设计与实现[网络中的虚拟实验平台]
- VC++实现串口通信的应用程序设计
- 【个人项目】项目记录:github链接、设计实现、单元测试、性能分析与改进、PSP完成表格、总结反思
- VC++实现获取所有的TCP与UDP链接
- Asp.net打开新窗口或实现超级链接的多种方法!(转)
- [开发日记]图:图片抽奖软件的原型设想及界面设计-PowerPoint与Vc++完美集成实现 (进展三)-2011年1月3日修订
- VC++实现获取所有的TCP与UDP链接
- CSS实现超级链接需要通过双击后跳转
- 开发日记]图片抽奖软件的原型设想及界面设计-打算用PowerPoint结合Vc++完美实现 (进展二)-于11月7日完工
- 大数据算法设计模式(2) - 左外链接(leftOuterJoin) spark实现
- 关于编译原理词法分析程序的设计(VC实现)
- VC命名管道通信的实现——最终自己的设计中没用VC
- linux&Windows动态链接库技术实现和设计程序常用的技术
- [开发日记]图片抽奖软件的原型设想及界面设计-打算用PowerPoint结合Vc++完美实现 (进展一)