想请教下各位大牛这个小功能该怎么实现?
就是说窗口上有一个按钮
鼠标一接近快要接触
鼠标就会自动停止
也就是说按钮的那块区域是鼠标的死角?麻烦各位有兴趣的大牛解释下
也不是一个很复杂的程序
最后附有源码
这是我的E-mail:[email protected]
可以传我邮箱!谢谢!

解决方案 »

  1.   

    鼠标一接近快要接触
    鼠标就会自动停止
    ==============
    自动停止很难实现吧,可以将鼠标移到别的地方去。
    你可以先派生出一个CButton的子类:CMyButton类,然后处理它的WM_MOUSEMOVE消息,代码如下:
    void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    ::SetCursorPos(point.x,point.y);
    CButton::OnMouseMove(nFlags, point);
    }
    然后将按钮和CMyButton关联在一起即可。一般是给按钮加上一个CMyButton类型的控件型成员变量。
      

  2.   

    红猪大哥
    先谢过你的回复
    但是如果这样的话
    那样只能把鼠标定位了
    而我是想做出那种:<font color=blue>就是说你一直努力往上面移,但是程序会根据你鼠标所在位置靠近那时就自动让鼠标移到按钮周围的最近的位置!</font>
    麻烦高手再想下
    最好能把详细代码贴出来,让我膜拜下!
    谢谢!
      

  3.   

    有个问题,如果WM_MOUSEMOVE的处理是放在对话框类中的,应该不行,因为当鼠标移到按钮上时,WM_MOUSEMOVE是由按钮来处理的,对话框就收不到WM_MOUSEMOVE消息了。所以一般都是放在按钮类中来处理。
      

  4.   

    有点难,你试下这个代码:
    void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CPoint pt;
    pt=point;
    CRect rect;
    GetWindowRect(&rect); ClientToScreen(&pt);
    int lx,rx,ty,by;
    lx=abs(rect.left-pt.x);
    rx=abs(rect.right-pt.x);
    ty=abs(rect.top-pt.y);
    by=abs(rect.bottom-pt.y); if(lx<=rx ) 
    {
    //AfxMessageBox(_T("lll"));
    SetCursorPos(rect.left-1,pt.y); }
    else
    {
    SetCursorPos(rect.right+1,pt.y);

    }
    if(ty<=by)
    {
    SetCursorPos(pt.x,rect.top-1); }
    else
    {
    SetCursorPos(pt.x,rect.bottom+1);
    }
    CButton::OnMouseMove(nFlags, point);
    }
      

  5.   

    大概意思是,定义一个矩形rect(200,200,400,400),当光标移动到矩形范围之内,自动跳到坐标100,100处。函数rect.PtInRect(point)是关键void CMainWindow::OnMouseMove (UINT flag,CPoint point)
    {
     CRect rect=CRect(200,200,400,400);     if(rect.PtInRect(point))
       {
    SetCursorPos(100,100);
    MessageBox("禁止进入");
       }
    }
      

  6.   

    void CMainWindow::OnMouseMove (UINT flag,CPoint point)
    {
     CRect rect=CRect(200,200,400,400);     if(rect.PtInRect(point))   //如果光标进入矩形范围
     {
     int a=point.y-200;
     int b=400-point.y;
     int c=point.x-200;
     int d=400-point.x;   //进入矩形的一瞬间,计算光标到各个边的垂直距离

     if(a最小)
     {把光标定位到"上边一点"}  
                                  //用SetCursorPos()函数  if(b最小)
     {把光标定位到"下边一点"}

     if(c最小)
     {把光标定位到"左边一点"}
     
     if(d最小)
     {把光标定位到"右边一点"}
     }
    }
    仅供参考。关注中。
      

  7.   

    void CMyButtonDlg::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    CRect buttonRect;
    GetDlgItem(IDC_MYBUTTON)->GetWindowRect(&buttonRect);
    ScreenToClient(&buttonRect);
    TRACE("buttonRect:%d,%d\t\t",buttonRect.TopLeft().x,buttonRect.TopLeft().y);// ScreenToClient(&point);
    if (buttonRect.PtInRect(point))
    {
    CPoint pt;
    pt = m_oriPoint;
    ClientToScreen(&pt);
    ::SetCursorPos(pt.x,pt.y);
    TRACE("1\t");
    }
    else
    {
    m_oriPoint = point;
    TRACE("2\t");
    }

    TRACE("point:%d,%d\n",point.x,point.y);
    CDialog::OnMouseMove(nFlags, point);
    }void CMyButton::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    ClientToScreen(&point);
    AfxGetMainWnd()->ScreenToClient(&point);
    LPARAM lParam;
    lParam = point.y << 16 | point.x;
    ::SendMessage(AfxGetMainWnd()->m_hWnd,WM_MOUSEMOVE,0,lParam);
    // AfxGetMainWnd()->OnWndMsg(WM_MOUSEMOVE,0,0,NULL);
    // CButton::OnMouseMove(nFlags, point);
    }以上代码在VC6中调试通过,能满足楼主的要求。
      

  8.   

    重载CButton类,处理WM_MOUSEMOVE消息
    void CNewButton::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default

    CButton::OnMouseMove(nFlags, point); if(GetSafeHwnd())
    {
    CRect rc;
    GetWindowRect(rc);
    SetCursorPos(rc.right+2, rc.bottom+2);
    }
    }
      

  9.   

    感谢楼上所有高手的支持
    特别要感谢11楼的wangyt涛哥,感谢他在如此短的时间内用如此精悍的代码结决了这个问题
    但是程序还有一点小BUG
    在涛哥修正之后会公布出来
    大家共同学习还有12楼的高手,我想如果只是单纯的加2的话应该不行吧,如果鼠标在按钮的左上角呢!
    这只是我的一点理解,我没有跑这段代码,
    如果理解有什么不对,欢迎大家批评指出,上面有我的邮箱
    再次谢谢诸位!
      

  10.   

    还有就是这句
    C/C++ code
     lParam = point.y << 16 | point.x;移位的运算,我试着改甩17、15,程序失效了
    小弟实在不明
    还请指点
      

  11.   

    高16位,低16位,
    使用这个宏应该会比较容易理解
    MAKELPARAM(point.x ,point.y);
      

  12.   

    这个简单啊,在Dialog类里加两个成员变量
    protected:
    CRect m_rtButton1;
    POINT m_PrePoint;
    在OnInitDialog函数里加
    // TODO: Add extra initialization here
    ::GetWindowRect(GetDlgItem(IDC_BUTTON1)->GetSafeHwnd(),&m_rtButton1);
    ScreenToClient(&m_rtButton1);
    m_rtButton1.bottom+=10;
    m_rtButton1.top -=10;
    m_rtButton1.left-=10;
    m_rtButton1.right+=10;
    在OnMouseMove里
    if(m_rtButton1.PtInRect(point))
    {
    SetCursorPos(m_PrePoint.x,m_PrePoint.y);
    }
    else
    {
    m_PrePoint = point;
    ClientToScreen(&m_PrePoint);
    }
    就可以了啊
    鼠标移动到ID = IDC_BUTTON1的按钮附近10像素的距离时,就不能再靠近按钮了。
      

  13.   

    11楼的确实强悍, m_oriPoint变量添加的非常精彩!这是我以11楼为基础简化的代码,
    void CMainWindow::OnMouseMove(UINT nFlags, CPoint point) 
    {
     CRect rect=CRect(200,200,400,400);    if (rect.PtInRect(point))
        {
            CPoint pt;
            pt = m_oriPoint;
            ClientToScreen(&pt);
            ::SetCursorPos(pt.x,pt.y);
        }
        else
        {
            m_oriPoint = point;
        }
    }
      

  14.   

    这么多人感兴趣啊,我修改的代码,试验结果基本上能工作,不过有个小问题,如果很快的移动鼠标的话,最终光标定位的地方不能保证是原来的点,如果慢慢的移,能达到楼主的要求,主要方法还是处理CMyButton类的WM_MOUSEMOVE消息:
    void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CPoint pt;
    pt=point;
    CRect rect;
    GetWindowRect(&rect); ClientToScreen(&pt);
    int lx,rx,ty,by;
    lx=abs(rect.left-pt.x);
    rx=abs(rect.right-pt.x);
    ty=abs(rect.top-pt.y);
    by=abs(rect.bottom-pt.y); if(lx<=14  ) 
    {
    //AfxMessageBox(_T("lll"));
    SetCursorPos(rect.left-1,pt.y); }
    if(rx<=14 )
    {
    SetCursorPos(rect.right+1,pt.y);

    }
    if(ty<=14 )
    {
    SetCursorPos(pt.x,rect.top-1); }
    if(by<=14 )
    {
    SetCursorPos(pt.x,rect.bottom+1);
    }
    CButton::OnMouseMove(nFlags, point);
    }
      

  15.   

    修改了一下,应该比较完善了void CNewButton::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default

    CButton::OnMouseMove(nFlags, point); if(GetSafeHwnd())
    {
    CRect rc;
    GetClientRect(rc); CPoint ptCursor(0, 0); CPoint pt = rc.CenterPoint();

    int left = abs(point.x - rc.left);
    int right = abs(point.x - rc.right); int top = abs(point.y - rc.top);
    int bottom = abs(point.y - rc.bottom); if(left <= right && top <= bottom) // Left - top
    {
    if(left <= top)
    {
    ptCursor.x = rc.left - 1;
    ptCursor.y = point.y;
    }
    else
    {
    ptCursor.x = point.x; 
    ptCursor.y = rc.top - 1;
    }
    }
    else if(left <= right && top > bottom) // left - bottom
    {
    if(left <= bottom)
    {
    ptCursor.x = rc.left -1;
    ptCursor.y = point.y;
    }
    else
    {
    ptCursor.x = point.x;
    ptCursor.y = rc.bottom + 1;
    }
    }
    else if(left > right && top <= bottom) // right - top
    {
    if(right <= top)
    {
    ptCursor.x = rc.right + 1;
    ptCursor.y = point.y;
    }
    else
    {
    ptCursor.x = point.x;
    ptCursor.y = rc.top -1;
    }
    }
    else if(left > right && top > bottom) // right - bottom
    {
    if(right <= bottom)
    {
    ptCursor.x = rc.right + 1;
    ptCursor.y = point.y;
    }
    else
    {
    ptCursor.x = point.x; 
    ptCursor.y = rc.bottom + 1;
    }
    }
    ClientToScreen(&ptCursor);
    SetCursorPos(ptCursor.x ,ptCursor.y);
    }
    }
      

  16.   

    非常感谢楼上的诸位高手,
    但是小弟还是不太理解14楼visualEleven关于高16低16移位的解释!
    麻烦再讲的详细点好吗?
    其实11楼的功能是实现的差不多了
    如果那位高手有空把代码大致解释下那就感激不尽了!
    再次谢谢各位!
      

  17.   

    XP都是32位运算,一半平分,高16,低16因为以前如windows 3.1都是16位操作系统,为了兼容楼主应该看看windows程序设计方面的书
      

  18.   

    不好意思
    上次解决的方法是把BnttonRect的长和宽都扩大7像素,使鼠标只能移向按钮周围7像素的位置。本来以为解决了,但小弟今天在用这个程序时无意间测试出来按钮还是能被点到的,因为按钮的范围变大的,看似鼠标没在按钮上面,但是如果努力点的话,按钮还是能被偶然点到的。
    麻烦各位大牛再给小弟一个思路,谢谢!
    如果需要源程序可以到http://download.csdn.net/source/2567116下载
    麻烦修改后能来信告知,如果你能为本程序加上必要的注释的话小弟就感激不尽了!
    我的E-mail:[email protected]
    期待你的来信!谢谢!
      

  19.   

    资源下载地址:http://download.csdn.net/source/2567116
    E-mail:[[email protected]][/email]