MFC控件子类化技术实现

实现用静态文本作为链接,点击该文本后会打开一个网站的功能,附加功能是静态文本的颜色转换,相关知识有子类化技术,根据光标位置进行改变文本颜色转换,鼠标移动、左击函数,静态文本风格转换,打开网站函数等等。
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找到。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值