VC制作超联接控件

风清扬斈 14年前 (2006-06-22) 信息科技 3346 0

同济大学 
罗筱波 
---- 在当今的网络时代,超联接无所不在,在各种各样的软件上我们都可以看到它的存在,这几乎成了一个必不可少的一项宣传内容。如果能在自己的程序中加入一个超联接,那么会使我们的程序带上鲜明的网络特征。但是在vc6.0中并没有提供一个用于制作超联接的控件,因此只有自己编写实现此功能的程序。下面是本人编写的一个实现超联接的类,希望能与大家分享。 

---- 制作思路是:从类CStatic 派生出一个子类CsuperLinkCtrl,然后为子类CsuperLinkCtrl加入适当的函数使其能响应鼠标的消息和实现超联接的功能。制作过程如下: 

---- 一、首先从类CStatic 派生出一个子类CsuperLinkCtrl,用classwizard生成的头文件具体代码如下: 

class CSuperLinkCtrl : public CStatic
{
// Construction
public:
    CSuperLinkCtrl();
CSuperLinkCtrl(COLORREF 
clickedtextcor,COLORREF moveontextcor,COLORREF 
ordinarytextcor);
// Attributes
public:
    COLORREF m_crText;   //超联接文本的颜色
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CSuperLinkCtrl)
    //}}AFX_VIRTUAL

// Implementation
public:
    BOOL SetLinkAddress(CString linkaddress); 
  //用于设置超联接的地址
    void MouseLeave(void);
    void MouseEnter(void);
    void SetLinkCursor(HCURSOR hCursor); 
 //用于设置超联接的鼠标形状
    void SetSuperLink(BOOL setlink);
    virtual ~CSuperLinkCtrl();

    // Generated message map functions
protected:
CString m_linktext;  // shell 调用的联接参数
BOOL m_bClicked;    // 鼠标是否单击超联接
HCURSOR m_hCursor;  // 鼠标移动到超联接上时的鼠标形状
//{{AFX_MSG(CSuperLinkCtrl)
afx_msg HBRUSH CtlColor(CDC* pDC, 
UINT nCtlColor);
afx_msg void OnLButtonDown(UINT
 nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, 
UINT nHitTest, UINT message);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG

    DECLARE_MESSAGE_MAP()
private:
BOOL m_bcaptured;             //捕捉鼠标移动
COLORREF m_clickedtextcor;    //单击超联接后文本的颜色
COLORREF m_moveontextcor;    //鼠标移动到超联接时的文本的颜色
COLORREF m_ordinarytextcor;   //未激活超联接时文本的颜色
LOGFONT        m_lf;          
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;    
 // 设置初始化字体颜色
    ::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(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();   
  //删除在类的构造函数中创建的字体
}
用classwizard为类加入如下消息映射并编写消息映射函数
BEGIN_MESSAGE_MAP(CSuperLinkCtrl, CStatic)
    //{{AFX_MSG_MAP(CSuperLinkCtrl)
    ON_WM_CTLCOLOR_REFLECT()
    ON_WM_LBUTTONDOWN()
    ON_WM_SETCURSOR()
    ON_WM_MOUSEMOVE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
编写消息映射函数CtlColor()用于实现超联接文本颜色的变化
HBRUSH CSuperLinkCtrl::CtlColor(CDC* pDC, UINT nCtlColor) 
{
    // TODO: Change any attributes of the DC here
    if (CTLCOLOR_STATIC == nCtlColor)
    {
        pDC->SelectObject(&m_font);
        pDC->SetTextColor(m_crText);
        pDC->SetBkMode(TRANSPARENT);
    }
HBRUSH hBrush = ::CreateSolidBrush
(GetSysColor(COLOR_3DFACE));  //创建一个刷子句柄
return hBrush;  // 返回一个用来画控件背景的刷子句柄
}
实现鼠标按下左键消息
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函数实现超联接
        ShellExecute(NULL, "open", m_linktext,
 NULL, NULL, SW_SHOWNORMAL);  
    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)   // 如果已取得光标句柄则设置新的鼠标形状
    {
        ::SetCursor(m_hCursor);
        return TRUE;
    }
    return CStatic::OnSetCursor(pWnd, nHitTest, message);
}

设置超联接文本上的光标句柄
void CSuperLinkCtrl::SetLinkCursor(HCURSOR hCursor)
{
        m_hCursor = hCursor;
}
响应鼠标移动消息
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();   //调用MouseEnter()函数
    ReleaseCapture(); // 释放鼠标捕捉
CStatic::OnMouseMove(nFlags, point); // 调用基类响应函数
}
在MouseEnter()和MouseLeave()
函数中设置鼠标进入和离开时的超联接文本的颜色
void CSuperLinkCtrl::MouseEnter()
{
m_crText=m_bClicked? m_clickedtextcor : m_moveontextcor;
RedrawWindow();    // 重画控件实现超联接文本颜色的变化
}

void CSuperLinkCtrl::MouseLeave()
{
m_crText=m_bClicked? m_clickedtextcor : m_ordinarytextcor;
RedrawWindow();   // 重画控件实现超联接文本颜色的变化
}

在SetLinkAddress()函数中设置超联接到地址
BOOL CSuperLinkCtrl::SetLinkAddress(CString linkaddress)
{   // 验证地址的合法性
    if(linkaddress.Find("http")!=-1)
        m_linktext=linkaddress;
    else if(linkaddress.Find("@")!=-1)
        m_linktext="mailto:"+linkaddress;
    else
    {
        MessageBox("Error: wrong superlink format");
        m_linktext=";
        return FALSE;
    }
    return TRUE;
}

---- 由于static控件并不响应鼠标消息,所以还需在派生的子类中作些修改。下面函数是使static控件能响应鼠标消息的关键(因为通常static控件只能响应很少一部分消息) 

void CSuperLinkCtrl::SetSuperLink(BOOL setlink)
{
if (setlink)   // 此处必须加入ModifyStyle(),
使static控件能响应鼠标消息
        ModifyStyle(0,SS_NOTIFY);
    else
        ModifyStyle(SS_NOTIFY,0);
}

---- 至此类CsuperLinkCtrl已制作完成便可在其它程序中使用了。 

---- 使用方法有两种:一是用classwizard使一个static控件与一个CsuperLinkCtrl变量相关联,另一种方法是定义一个CsuperLinkCtrl变量然后用SubclassDlgItem()使它与一个static控件相关联。 

---- 使用示例: 

---- 首先将SuperLinkCtrl1.h和SuperLinkCtrl1.cpp加入到工程的目录中,然后定义一个变量CSuperLinkCtrl m_test; 然后在对话框中加入一个static控件,设置其ID为IDC_STATICTEST,之后在对话框的OnInitDialog()函数中加入如下代码即可 

m_test.SubclassDlgItem(IDC_STATICTEST,this);  
// IDC_STATICTEST是一个需要子类化的static控件的ID
m_test.SetSuperLink(TRUE);  //设置控件为超联接控件
m_test.SetLinkCursor(AfxGetApp()->
LoadCursor(IDC_CURSORHAND)); 
 // 设置超联接控件的鼠标形状
m_test.SetLinkAddress("xxxx@citiz.net");
 // 设置超联接的地址

---- 怎么样,赶紧试一下吧! 
"

相关推荐

  • 网友评论

    • (*)

    最新评论