VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 378|回复: 12

[求助] 啥时应该用全局函数,啥时不需要呢?我这个为啥非得用全局函数才起作用呢?

[复制链接]
cumulonimbus 发表于 2017-10-10 13:29:53 | 显示全部楼层 |阅读模式
3驿站币
class CHyperLinkButton : public CButton
{
public:
        CHyperLinkButton();
public:
        virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
public:
        virtual ~CHyperLinkButton();
protected:
        //{{AFX_MSG(CHyperLinkButton)
        afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
        afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
        afx_msg void OnMouseMove(UINT nFlags, CPoint point);
        afx_msg void OnTimer(UINT nIDEvent);
        afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
public:
        CFont m_fontUnderline;   //鼠标移动到按钮上时的字体
        HCURSOR m_hCurHand;      //鼠标移动到按钮上时的光标
        BOOL m_bLBtnDown;        //鼠标左键是否按下
        BOOL m_bMouseOver;       //鼠标是否处于按钮上方
};

CHyperLinkButton::CHyperLinkButton()
{
        //初始化鼠标左键没有按下
        //鼠标指针也不在按钮上
        m_bMouseOver = m_bLBtnDown = FALSE;
        //加载所需光标
        m_hCurHand = AfxGetApp()->LoadCursor(IDC_HANDCUR);
}

BOOL CHyperLinkButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{               
        if (m_bMouseOver)   //如果光标在按钮上方则更改光标形状
        {
                ::SetCursor(m_hCurHand);
                return true;
        }       
        return CButton::OnSetCursor(pWnd, nHitTest, message);
}
这个我想不明白,为啥SetCursor(m_hCurHand)一定得用全局函数呢,CButton这个类也有成员函数SetCursor呀,不用成员函数就不行了呢?谢谢

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

 楼主| cumulonimbus 发表于 2017-10-10 13:31:54 | 显示全部楼层
class CHyperLinkButton : public CButton
{
// Construction
public:
        CHyperLinkButton();

// Attributes
public:

// Operations
public:

// Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CHyperLinkButton)
        public:
        virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
        //}}AFX_VIRTUAL

// Implementation
public:
        virtual ~CHyperLinkButton();

        // Generated message map functions
protected:
        //{{AFX_MSG(CHyperLinkButton)
        afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
        afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
        afx_msg void OnMouseMove(UINT nFlags, CPoint point);
        afx_msg void OnTimer(UINT nIDEvent);
        afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
        //}}AFX_MSG

        DECLARE_MESSAGE_MAP()

public:
        CFont m_fontUnderline;   //鼠标移动到按钮上时的字体
        HCURSOR m_hCurHand;      //鼠标移动到按钮上时的光标
        BOOL m_bLBtnDown;        //鼠标左键是否按下
        BOOL m_bMouseOver;       //鼠标是否处于按钮上方

};

CHyperLinkButton::CHyperLinkButton()
{
        //初始化鼠标左键没有按下
        //鼠标指针也不在按钮上
        m_bMouseOver = m_bLBtnDown = FALSE;
        //加载所需光标
        m_hCurHand = AfxGetApp()->LoadCursor(IDC_HANDCUR);
}

CHyperLinkButton::~CHyperLinkButton()
{
}

BEGIN_MESSAGE_MAP(CHyperLinkButton, CButton)
        //{{AFX_MSG_MAP(CHyperLinkButton)
        ON_WM_LBUTTONDOWN()
        ON_WM_LBUTTONUP()
        ON_WM_MOUSEMOVE()
        ON_WM_TIMER()
        ON_WM_SETCURSOR()
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHyperLinkButton message handlers

void CHyperLinkButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
       
        CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);// 获取DC指针
        CRect rect(lpDrawItemStruct->rcItem);//定义按钮区域并初始化       
        pDC->SetBkMode(TRANSPARENT);//设置背景为透明
        UINT nBtnState = lpDrawItemStruct->itemState;//取得按钮状态
        CFont * pOldFont = NULL;
        CString strText;
        GetWindowText(strText);        //获得按钮文本
        if (m_bMouseOver)//光标在按钮上
                {
                        if (nBtnState&ODS_SELECTED)//按下按钮,绘制反向矩形框
                        {       
                                pDC->Draw3dRect(rect,GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHILIGHT));
                        }
                        else//未按下按钮,绘制正常矩形框
                        {
                                pDC->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
                        }
                        pDC->SetTextColor(RGB(0,0,255));        //字体颜色设置为蓝色

                        if (m_fontUnderline.GetSafeHandle() == NULL)
                        {
                                CFont * pFont = GetFont();
                                ASSERT(pFont);
                                LOGFONT lf;
                                pFont->GetLogFont(&lf);
                                lf.lfUnderline = TRUE;        //加下画线
                                m_fontUnderline.CreateFontIndirect(&lf);               
                        }
                        pOldFont = pDC->SelectObject(&m_fontUnderline);
                }
        else pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));//采用系统字体
                pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);//显示按钮文本
        if (pOldFont)
                pDC->SelectObject(pOldFont);
}


void CHyperLinkButton::OnLButtonDown(UINT nFlags, CPoint point)
{
        m_bLBtnDown = TRUE;//鼠标左键按下
        CButton::OnLButtonDown(nFlags, point);
}

void CHyperLinkButton::OnLButtonUp(UINT nFlags, CPoint point)
{
        m_bLBtnDown = FALSE;//鼠标左键没有按下
        if (m_bMouseOver)       
        {
                m_bMouseOver = FALSE;
                InvalidateRect(NULL);//重绘按钮
        }
        CButton::OnLButtonUp(nFlags, point);
}

void CHyperLinkButton::OnMouseMove(UINT nFlags, CPoint point)
{
        SetTimer(1,10,NULL);//设置一个定时器,调用OnTimer
        CButton::OnMouseMove(nFlags, point);
}

void CHyperLinkButton::OnTimer(UINT nIDEvent)
{
        static BOOL bPainted = FALSE;
        POINT pt;
        GetCursorPos(&pt);//获得光标的当前位置
        CRect rect;       
        GetWindowRect (rect);//获得按钮的窗口矩形大小       
        if (m_bLBtnDown)            //左键按下
        {               
                KillTimer (1);//取消定时器
                if (bPainted)
                InvalidateRect (NULL);        //重绘按钮       
                bPainted = FALSE;               
                return;       
        }
        if (!rect.PtInRect (pt))         //当前光标不在按钮区域内
        {               
                m_bMouseOver = FALSE;
                KillTimer (1);//取消定时器
                if (bPainted)                       
                        InvalidateRect(NULL);
                bPainted = FALSE;
                return;       
        }
        else//光标在按钮区域,且左键并没有按下
        {
                m_bMouseOver = TRUE;
                if (!bPainted)
                {
                        bPainted = TRUE;
                        InvalidateRect(NULL);//重绘窗口
                }
        }
        CButton::OnTimer(nIDEvent);
}

BOOL CHyperLinkButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{               
        if (m_bMouseOver)   //如果光标在按钮上方则更改光标形状
        {
                ::SetCursor(m_hCurHand);
                return true;
        }       
        return CButton::OnSetCursor(pWnd, nHitTest, message);
}
这是这个子类所有的函数。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

Syc 发表于 2017-10-10 13:45:03 | 显示全部楼层
在你这里来说应该也可以的,本身 CButton::SetCursor 最终也是调用全局的 ::SetCursor

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

 楼主| cumulonimbus 发表于 2017-10-11 11:55:26 | 显示全部楼层
Syc 发表于 2017-10-10 13:45
在你这里来说应该也可以的,本身 CButton::SetCursor 最终也是调用全局的 ::SetCursor

可为啥非得调用全局函数呢?不调用就没效果,大师请指教。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

Syc 发表于 2017-10-11 13:03:56 | 显示全部楼层
cumulonimbus 发表于 2017-10-11 11:55
可为啥非得调用全局函数呢?不调用就没效果,大师请指教。

去掉前面的 :: 直接调用类内部的 SetCursor 不正常吗?

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

 楼主| cumulonimbus 发表于 2017-10-11 16:40:17 | 显示全部楼层
Syc 发表于 2017-10-11 13:03
去掉前面的 :: 直接调用类内部的 SetCursor 不正常吗?

无法显示自己的光标

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

Syc 发表于 2017-10-11 16:42:56 | 显示全部楼层
cumulonimbus 发表于 2017-10-11 16:40
无法显示自己的光标

怎么写的?F11跟进 类内部的 SetCursor,看看什么情况

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

 楼主| cumulonimbus 发表于 2017-10-11 16:47:48 | 显示全部楼层
Syc 发表于 2017-10-11 16:42
怎么写的?F11跟进 类内部的 SetCursor,看看什么情况

确实不起作用,不能显示自己定制的光标

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

Syc 发表于 2017-10-11 16:58:29 | 显示全部楼层
cumulonimbus 发表于 2017-10-11 16:47
确实不起作用,不能显示自己定制的光标

源码清理下传上来我研究研究

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

 楼主| cumulonimbus 发表于 2017-10-12 10:31:18 | 显示全部楼层
Syc 发表于 2017-10-11 16:58
源码清理下传上来我研究研究

已上传,请研究

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入驿站

x

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

Syc 发表于 2017-10-12 13:00:01 | 显示全部楼层

调用 CButton 成员函数的 SetCursor(m_hCurHand); 时候根本就没成功,GetLastError 得到的错误码是 87,应该是不能这么用。所以光标也没起效果

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

 楼主| cumulonimbus 发表于 2017-10-13 11:15:35 | 显示全部楼层
Syc 发表于 2017-10-12 13:00
调用 CButton 成员函数的 SetCursor(m_hCurHand); 时候根本就没成功,GetLastError 得到的错误码是 87, ...

不太明白,能解释一下吗?

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

Syc 发表于 2017-10-13 16:45:40 | 显示全部楼层
cumulonimbus 发表于 2017-10-13 11:15
不太明白,能解释一下吗?

意思就是如果你直接写 SetCursor(m_hCurHand); 的话,编译是过了,但是调用之后你会发现有错误,提示 SetCursor 的参数有问题,所以 SetCursor(m_hCurHand); 这句话根本没调用成功。肯定不起作用了。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站

本版积分规则

展开

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )

返回顶部
x

VC驿站微信公众号cctry2009

GMT+8, 2017-12-14 04:27

Powered by Discuz!

© 2009-2017 cctry.com

快速回复 返回顶部 返回列表