MFC 光标设置总结

 

引言

软件之前光标设置,在其他模块都会涉及设置鼠标光标,实现比较随意,出现问题排查起来比较困难,耽误时间。现在涉及到软件的鼠标光标设置,统一封装成统一的接口函数,设置光标统一放在统一模块实现。

 

函数功能分析

LoadCursorA

从与应用程序实例关联的可执行文件(. exe)加载指定的游标资源。

语法

HCURSOR LoadCursorA(
  HINSTANCE hInstance,
  LPCSTR    lpCursorName
);

参数

- hInstance

模块实例的句柄,其可执行文件包含要加载的游标。

- lpCursorName

要加载的游标资源的名称。或者,该参数可以由低序字中的资源标识符和高序字中的零组成。也可以使用MAKEINTRESOURCE宏来创建这个值。要使用一个预定义的游标,应用程序必须将hInstance参数设置为NULL,并将lpCursorName参数设置为以下值之一。

 

ValueMeaning翻译
IDC_APPSTARTING MAKEINTRESOURCE(32650)Standard arrow and small hourglass标准箭头和小沙漏
IDC_ARROW MAKEINTRESOURCE(32512)Standard arrow标准的箭头
IDC_CROSS MAKEINTRESOURCE(32515)Crosshair十字准线
IDC_HAND MAKEINTRESOURCE(32649)Hand
IDC_HELP MAKEINTRESOURCE(32651)Arrow and question mark箭头和问号
IDC_IBEAM MAKEINTRESOURCE(32513)I-beamI型标
IDC_ICON MAKEINTRESOURCE(32641)Obsolete for applications marked version 4.0 or later.对于标记为4.0或更高版本的应用程序来说是过时的。
IDC_NO MAKEINTRESOURCE(32648)Slashed circle斜切圆
IDC_SIZE MAKEINTRESOURCE(32640)Obsolete for applications marked version 4.0 or later. Use IDC_SIZEALL.对于标记为4.0或更高版本的应用程序来说是过时的。对于标记为4.0或更高版本的应用程序来说是过时的。使用* * IDC_SIZEALL * *。
IDC_SIZEALL MAKEINTRESOURCE(32646)Four-pointed arrow pointing north, south, east, and west四个箭头指向北、南、东、西
IDC_SIZENESW MAKEINTRESOURCE(32643)Double-pointed arrow pointing northeast and southwest双箭头指向东北和西南
IDC_SIZENS MAKEINTRESOURCE(32645)Double-pointed arrow pointing north and south指向南北的双箭头
IDC_SIZENWSE MAKEINTRESOURCE(32642)Double-pointed arrow pointing northwest and southeast指向西北和东南的双尖箭头
IDC_SIZEWE MAKEINTRESOURCE(32644)Double-pointed arrow pointing west and east双箭头,指向西方和东方
IDC_UPARROW MAKEINTRESOURCE(32516)Vertical arrow垂直的箭头
IDC_WAIT MAKEINTRESOURCE(32514)Hourglass沙漏

 

返回值

Type: HCURSOR

  • 如果函数成功,返回值是新加载的游标的句柄。

  • 如果函数失败,返回值为NULL。要获取扩展的错误信息,请调用 GetLastError

设置光标类型函数封装

设置鼠标光标类型

//鼠标操作类型
enum BtnDrag
{
    L_BTNDRAG = 0, //鼠标左键
    M_BTNDRAG,     //鼠标中键
    R_BTNDRAG,     //鼠标右键
    Move_BTNDRAG   //鼠标移动
};

 

光标样式

//光标样式
enum CursorType
{
    CURSOR_NULL,        //用于取消当前设置光标,恢复之前默认光标设置
    //cursor style
    CURSOR_APPSTARTING, //标准箭头和小沙漏
    CURSOR_ARROW,        //标准箭头
    CURSOR_CROSS,        //十字线
    CURSOR_HAND,         //手型
    CURSOR_HELP,         //帮助
    CURSOR_IBEAM,        //工字符
    CURSOR_ICON,         //对于标记为版本4.0或更高版本的应用程序已过时。
    CURSOR_NO,           //斜切圆
    CURSOR_SIZE,         //对于标记为版本4.0或更高版本的应用程序已过时。使用**IDC_SIZEALL**
    CURSOR_SIZEALL,      //指向北、南、东和西的四尖箭头
    CURSOR_SIZENESW,     //指向东北和西南的双尖箭头
    CURSOR_SIZENS,       //指向南北的双尖箭头
    CURSOR_SIZENWSE,     //指向西北和东南的双尖箭头
    CURSOR_SIZEWE,       //指向西方和东方的双尖箭头
    CURSOR_UPARROW,      //垂直箭头
    CURSOR_WAIT,         //等待/沙漏
​
    //custom  cursor style
    CURSOR_PICK_COLOR,    //取色器
    CURSOR_Pan,           //平移
    CURSOR_Rotate,        //旋转
    CURSOR_Survey         //环视
};
​
map<BtnDrag,HCURSOR>    m_mapCursorptr;

 

设置鼠标光标类型

// 设置鼠标光标类型
void DCameraHandler::SetCrossingByStyle(CursorType _eCursorType, BtnDrag _eBtnDrag)
{
    HCURSOR _cursor = NULL;
    switch (_eCursorType)
    {
    case CURSOR_NULL:
        break;
    case CURSOR_APPSTARTING:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING));
        break;
    }
    case CURSOR_ARROW:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
        break;
    }
    case CURSOR_CROSS:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_CROSS));
        break;
    }
    case CURSOR_HAND:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND));
        break;
    }
    case CURSOR_HELP:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HELP));
        break;
    }
    case CURSOR_IBEAM:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM));
        break;
    }
    case CURSOR_ICON:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ICON));
        break;
    }
    case CURSOR_NO:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO));
        break;
    }
    case CURSOR_SIZE:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZE));
        break;
    }
    case CURSOR_SIZEALL:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEALL));
        break;
    }
    case CURSOR_SIZENESW:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW));
        break;
    }
    case CURSOR_SIZENS:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS));
        break;
    }
    case CURSOR_SIZENWSE:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE));
        break;
    }
    case CURSOR_SIZEWE:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE));
        break;
    }
    case CURSOR_UPARROW:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_UPARROW));
        break;
    }
    case CURSOR_WAIT:
    {
        _cursor = ::LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
        break;
    }
    case CURSOR_PICK_COLOR:
    {
        StringAnsi tempAppDataPath = m_plantInterface->GetModulPath();
        StringWide tempCursorPath = StringUtf8ToWide(tempAppDataPath) + L"\\Resources\\cursor\\dropcurs.cur";
        _cursor = ::LoadCursorFromFile(tempCursorPath.c_str());
        break;
    }
    case CURSOR_Pan:
    {
        StringAnsi tempAppDataPath = m_plantInterface->GetModulPath();
        StringWide tempCursorPath = StringUtf8ToWide(tempAppDataPath) + L"\\Resources\\cursor\\LBtnDrag.cur";
        _cursor = ::LoadCursorFromFile(tempCursorPath.c_str());
        break;
    }
    case CURSOR_Rotate:
    {
        StringAnsi tempAppDataPath = m_plantInterface->GetModulPath();
        StringWide tempCursorPath = StringUtf8ToWide(tempAppDataPath) + L"\\Resources\\cursor\\RBtnDrag.cur";
        _cursor = ::LoadCursorFromFile(tempCursorPath.c_str());
        break;
    }
    case CURSOR_Survey:
    {
        StringAnsi tempAppDataPath = m_plantInterface->GetModulPath();
        StringWide tempCursorPath = StringUtf8ToWide(tempAppDataPath) + L"\\Resources\\cursor\\MBtnDrag.cur";
        _cursor = ::LoadCursorFromFile(tempCursorPath.c_str());
        break;
    }
            
    default:
        break;
    }
​
    {//Reduces lock granularity
        std::lock_guard<std::mutex> guard(m_cameraOperMutex);
        if (nullptr != _cursor)
        {
            m_mapCursorptr[_eBtnDrag] = _cursor;
        }
        else
        {
            map<BtnDrag, HCURSOR>::iterator item = m_mapCursorptr.find(_eBtnDrag);
            if (item != m_mapCursorptr.end())
            {
                m_mapCursorptr.erase(item);
            }
        }
    }
}

 

函数的使用

bool DCameraHandler::OnMouseMove(const UserInputEvent& uie)
{
    m_bMouseMoved = true;
    if (m_bCrossingSelect)
    {
        if (m_bLButtonDown)
        {   
            SetCrossingByStyle(CursorType::CURSOR_SIZEWE, L_BTNDRAG);   
        }
    }
    
    if (m_bLButtonDown && m_bMouseMoved)//左键
    {
        if (m_mapCursorptr.count(L_BTNDRAG) != 0)
        {
            m_hCur = m_mapCursorptr[L_BTNDRAG];
            SetCursor(m_hCur);
        }
        else
        {
            SetCrossingByStyle(CursorType::CURSOR_Pan, L_BTNDRAG);
        }
    }
    if (m_bRButtonDown && m_bMouseMoved)//右键
    {
        if (m_mapCursorptr.count(R_BTNDRAG) != 0)
        {
            m_hCur = m_mapCursorptr[R_BTNDRAG];
            SetCursor(m_hCur);
        }
        else
        {
            SetCrossingByStyle(CursorType::CURSOR_Rotate, R_BTNDRAG);
        }
        m_bRButtonDownAndMoved = true;
    }
    else if (m_bMButtonDown && m_bMouseMoved)//鼠标中键
    {
        if (m_mapCursorptr.count(M_BTNDRAG) != 0) //鼠标移动
        {
            m_hCur = m_mapCursorptr[M_BTNDRAG];
            SetCursor(m_hCur);
        }
        else
        {
            SetCrossingByStyle(CursorType::CURSOR_Survey, M_BTNDRAG);
        }
    }
    else //鼠标移动
    {
        if (m_mapCursorptr.count(Move_BTNDRAG) != 0) //鼠标移动
        {
            m_hCur = m_mapCursorptr[Move_BTNDRAG];
            SetCursor(m_hCur);
        }
        else
        {
            SetCrossingByStyle(CursorType::CURSOR_ARROW, Move_BTNDRAG);
        }
    }
    
    return false;   // need always return false
​
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值