实现用静态文本作为链接,点击该文本后会打开一个网站的功能,附加功能是静态文本的颜色转换,相关知识有子类化技术,根据光标位置进行改变文本颜色转换,鼠标移动、左击函数,静态文本风格转换,打开网站函数等等。
1.创建一个机遇对话框的应用程序,名叫Ex4_10,标题为“控件子类化例子”.
2.打开Class Wizard ->单击Add Class ->New命令->创建类名为CSuperLinkCtrl的类,基类是CStatic
3.在对话框增加静态文本控件IDC_STATICSUPERLINK,样式:通知√
4.在CSuperLinkCtrl类中添加public成员和函数:
COLORREF m_crText;//静态文本颜色
CSuperLinkCtrl(COLORREF clickedtextcor,COLORREF moveontextcor,COLORREF ordinarytextcor);
BOOL SetLinkAddress(CString linkaddress);//用于设置超链接地址
void MouseLeave(void);
void MouseEnter(void);
void SetLinkCursor(HCURSOR hCursor);//用于设置鼠标形状
void SetSuperLink(BOOL setlink);//设置静态文本为可接受鼠标消息
添加protected成员:
CString m_linktext; //网站链接字符串->用shell函数调用的连接参数parameter
BOOL m_bClicked; //鼠标是否单击超链接
HCURSOR m_hCursor; //鼠标移动到超链接上时的鼠标形状
DECLARE_MESSAGE_MAP()
添加private成员:
BOOL m_bcaptured; //捕获鼠标标志
COLORREF m_clickedtextcor;//鼠标单击超链接后的文档颜色
COLORREF m_moveontextcor;//鼠标移动到超链接时的文档颜色
COLORREF m_ordinarytextcor;//未激活超链接时文档颜色
LOGFONT m_lf;//LOGFONT 字体相关信息结构体
CFont m_font; //超链接上的文档的字体
对话框的默认构造函数设置为:
CSuperLinkCtrl::CSuperLinkCtrl()
{
m_bClicked=FALSE;
m_bcaptured=FALSE;
m_clickedtextcor=RGB(0,255,255);
m_moveontextcor=RGB(0,255,0);
m_ordinarytextcor=RGB(0,0,255);
m_crText=m_ordinarytextcor;
//获取当前默认字体信息存放入m_lf结构体
GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);
m_lf.lfUnderline=TRUE;//字体设置有下划线
//利用m_lf间接创建CFont对象m_font
BOOL bCreated=m_font.CreateFontIndirect(&m_lf);
ASSERT(bCreated);//检查是否成功创建
m_hCursor=NULL;
}
自定义的构造函数:
CSuperLinkCtrl::CSuperLinkCtrl(COLORREF clickedtextcor,COLORREF moveontextcor,COLORREF ordinarytextcor)
{
m_bClicked=FALSE;
m_bcaptured=FALSE;
m_clickedtextcor=clickedtextcor;
m_moveontextcor=moveontextcor;
m_ordinarytextcor=ordinarytextcor;
m_crText=m_ordinarytextcor;//设置初始化字体颜色
//取得当前的默认字体
GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);
m_lf.lfUnderline=TRUE;
BOOL bCreated=m_font.CreateFontIndirect(&m_lf);//创建超链接字体
ASSERT(bCreated);
m_hCursor=NULL;//鼠标在超链接上的光标形状初始化默认
}
析构函数修改为:
CSuperLinkCtrl::~CSuperLinkCtrl()
{
m_font.DeleteObject();//删除在类的构造参数中创建的字体.
}
并在Ex4_10Dlg.cpp中添加如下函数代码:
先用向导Ctrl+W添加如下消息函数
=WM_CTLCOLOR,
WM_LBUTTONDOWN
WM_MOUSEMOVE
WM_SETCURSOR
void CSuperLinkCtrl::MouseEnter()
{
m_crText=m_bClicked?m_clickedtextcor:m_moveontextcor;
OnSetCursor(NULL,NULL,NULL);
RedrawWindow();
}
void CSuperLinkCtrl::MouseLeave()
{
m_crText=m_bClicked?m_clickedtextcor:m_ordinarytextcor;
RedrawWindow();
}
BOOL CSuperLinkCtrl::SetLinkAddress(CString linkaddress)
{
//验证地址合法性
if(linkaddress.Find("http")!=-1)
{
m_linktext=linkaddress;
}
else if(linkaddress.Find("@")!=-1)
{
m_linktext="mailto:"+linkaddress;
}
else
{
//错误
MessageBox("超链接错误");
m_linktext="";
return FALSE;
}
return TRUE;
}
void CSuperLinkCtrl::SetSuperLink(BOOL setlink)
{
if(setlink)//此处必须加入ModifyStyle(),使static控件能响应鼠标消息
ModifyStyle(0,SS_NOTIFY);//0表示默认风格,SS_NOTIFY风格能让静态文本接受鼠标消息//默认是0的所以需要这个去修改
else
ModifyStyle(SS_NOTIFY,0);//如果是0的话就返回默认状态
}
void CSuperLinkCtrl::SetLinkCursor(HCURSOR hCursor)
{
m_hCursor=hCursor;
}
void CSuperLinkCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bClicked=TRUE;
m_crText=m_clickedtextcor;
RedrawWindow();
if(m_linktext!="")
ShellExecute(NULL,"open",m_linktext,NULL,NULL,SW_SHOWNORMAL);//正常开打方式
//父窗口句柄 指定动作 指定要打开的文件或者程序 打开程序指定参数,文件nil 缺省目录 打开选项
//open runas print edit explore
CStatic::OnLButtonDown(nFlags, point);
}
BOOL CSuperLinkCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if(m_hCursor)
{
HCURSOR hCur=m_hCursor;
::SetCursor(hCur);//要用全局::标识符,这样才可以设置!!
return TRUE;
}
return CStatic::OnSetCursor(pWnd, nHitTest, message);
}
void CSuperLinkCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SetCapture();//捕捉鼠标
POINT mpoint;
GetCursorPos(&mpoint);//获取鼠标当前位置
CRect rect;
GetWindowRect(&rect);//获取控件的窗口大小
if(!rect.PtInRect(mpoint))//判断鼠标是否在控件窗口内
{
//鼠标不在控件的窗口内
m_bcaptured=FALSE;
ReleaseCapture();//释放鼠标捕捉
MouseLeave();//调用mouseleave()参数 鼠标离开控件框后颜色变化
return ;
}
//鼠标在控件窗口内
if(m_bcaptured)//鼠标已被捕捉到在控件窗口内,移动不会造成影响
return;
m_bcaptured=TRUE;
MouseEnter();//鼠标进入控件框后改变颜色函数
ReleaseCapture();//释放
CStatic::OnMouseMove(nFlags, point);
}
HBRUSH CSuperLinkCtrl::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
if(nCtlColor==CTLCOLOR_STATIC)
{
pDC->SelectObject(&m_font);
pDC->SetTextColor(m_crText);
pDC->SetBkColor(TRANSPARENT);
}
HBRUSH hBrush=CreateSolidBrush(GetSysColor(COLOR_3DFACE));
// TODO: Return a non-NULL brush if the parent's handler should not be called
return hBrush;
}
请注意:=WM_CTLCOLOR是可反馈的消息响应函数,父窗口反馈子窗口传送的消息,让子窗口处理一些消息,在这里的目的是让子类通过这个函数修改静态文本的背景颜色、字体格式、颜色等。
在Ex4_10Dlg.h中,添加:
#include "SuperLinkCtrl.h"
public:
CSuperLinkCtrl m_SuperLink;
CEx4_10Dlg的OnInitDialog()中添加:
m_SuperLink.SubclassDlgItem(IDC_STATICSUPERLINK,this);//将CStatic控件子类化
m_SuperLink.SetSuperLink(TRUE);//设置控件为超链接控件
//设置超链接控件的光标状态
m_SuperLink.SetLinkCursor(AfxGetApp()->LoadCursor(IDC_CURSORHAND));
//设置超链接的地址
m_SuperLink.SetLinkAddress("http://www.dangdang.com/");
IDC_CURSORHAND为手型光标,可在C盘:Windows的Cursors找到。