• 实现文字跟随鼠标移动--[转]


    可能首先会想到SetROP2()函数,利用这个函数在鼠标移动的时候将上次的文字擦除再显示当前文字,可SetROP2()对于DrawText()输出文本不起作用,因
    为其没有用到画笔,所以SetROP2()可以用来当作“橡皮线”而不是整块“橡皮”......

    一种实现方法:在鼠标移动事件函数中绘制文字,首次产生鼠标移动事件的时候先保存要输出的文字区域的背景,然后在文字区域输出文字,以后的鼠标
    事件发生后则先利用保存的原文字区域的背景去除原文字区域的文字(即绘制原文字区域背景到原文字区域),然后再保存要输出的文字区域的背景,然
    后在文字区域输出文字。

    多说一点,鼠标移动事件函数OnMouseMove的第一个参数nFlags为一些特定的按键是否被按下的标志,

    MK_CONTROL Set if the CTRL key is down.

    MK_LBUTTON Set if the left mouse button is down.

    MK_MBUTTON Set if the middle mouse button is down.

    MK_RBUTTON Set if the right mouse button is down.

    MK_SHIFT Set if the SHIFT key is down.

    eg:

    void Cmfc_testDlg::OnMouseMove(UINT nFlags, CPoint point)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        if(nFlags == MK_LBUTTON)
        {
            ......
        }
        if(nFlags == (MK_CONTROL | MK_SHIFT))
        {
                ......
        }
        
        ......
    
        CDialogEx::OnMouseMove(nFlags, point);
    }

    以下为实现代码:

    //保存指定区域的背景到参数MemBitmap
    void ScreenShot(CBitmap *MemBitmap, CDC* pDC, int Xcoords, int Ycoords, int Width, int Height)
    {    
        CDC memDC; 
        memDC.CreateCompatibleDC(pDC);        
        MemBitmap->CreateCompatibleBitmap(pDC, Width, Height);    
        memDC.SelectObject(MemBitmap);    
        memDC.BitBlt(0, 0, Width, Height, pDC, Xcoords, Ycoords, SRCCOPY);      
        memDC.DeleteDC();    
    }
    
    //鼠标移动事件函数
    void CXXXDlg::OnMouseMove(UINT nFlags, CPoint point)
    {    
        // TODO: 在此添加消息处理程序代码和/或调用默认值   
    
        CClientDC cdc(this); 
        
        if(!m_first_show_flag)        
        {          
            m_OldX = point.x+10;            
            m_OldY = point.y-20;   
    
            m_MemBitmap.DeleteObject();            
            ScreenShot(&cdc, &m_MemBitmap, m_OldX, m_OldY, 110, 50);//保存要输出的文字区域的背景图片 
    
            cdc.SetBkMode(TRANSPARENT);
            CString strPointMove;
            strPointMove.Format(_T("%d, %d"), point.x, point.y);
            cdc.DrawText(strPointMove, CRect(m_OldX,m_OldY, m_OldX+110, m_OldY+50), DT_LEFT);//在文字区域输出坐标 
    
            m_first_show_flag = true;    
        }        
        else        
        {                 
            BITMAP bm;            
            m_MemBitmap.GetObject (sizeof(BITMAP), &bm);            
            CDC MemDC;      
            MemDC.CreateCompatibleDC(&cdc);            
            CBitmap *pOldBitmap=MemDC.SelectObject(&m_MemBitmap);             
            cdc.BitBlt(m_OldX, m_OldY, bm.bmWidth , bm.bmHeight, &MemDC, 0, 0, SRCCOPY);//利用保存的原文字区域的背景图片去除原来文字区域的
    
    文字                
            MemDC.SelectObject(pOldBitmap);            
            MemDC.DeleteDC();
    
            m_OldX = point.x+10;//新坐标作为下次使用的前一次坐标            
            m_OldY = point.y-20;            
            m_MemBitmap.DeleteObject();            
            ScreenShot(&cdc, &m_MemBitmap, m_OldX, m_OldY, 110, 50);//保存要输出的文字区域的背景图片 
    
            cdc.SetBkMode(TRANSPARENT);
            CString strPointMove;
            strPointMove.Format(_T("%d, %d"), point.x, point.y);
            cdc.DrawText(strPointMove, CRect(m_OldX, m_OldY, m_OldX+110, m_OldY+50), DT_LEFT);//在文字区域输出坐标                   
        }
        
        CDialog::OnMouseMove(nFlags, point);
    }

    在实际运行中发现,如果窗口为自绘,比如在OnPaint()中整个窗口被绘制成了白色,那么窗口显示的时候,如果鼠标在当前窗口区域则会出现文字区域
    背景没有自绘的情况,我猜是窗口显示的时候如果鼠标在当前窗口则会产生鼠标移动事件,而窗口重绘事件在其后产生,即先进入OnMouseMove(),再进
    入OnPaint(),所以才导致这种情况。一个解决方法就是设置一个全局或成员标志,当自绘完成后设置该标志为真,在OnMouseMove中先判断该标志,如果
    为假的话则什么都不做。

    参考原文:http://www.cnblogs.com/lcyty/p/3327237.html#commentform,作者Ginsan

  • 相关阅读:
    读取 classes下的配置文件
    java中Class.getResource用法(用于配置文件的读取)
    windows 中 到底是用的哪个java.exe??? 删除了PATH变量的Java设置还是可以运行java.exe windows/system32
    mysql中null与“空值”的坑
    innodb架构理解
    mysql5.7性能提升一百倍调优宝典
    servlet 3.0笔记之servlet的动态注册
    前端性能优化建议
    了解CSRF攻击原理和预防
    vue的热更新配置
  • 原文地址:https://www.cnblogs.com/milanleon/p/5489554.html
Copyright © 2020-2023  润新知