当前位置: 代码迷 >> 综合 >> MFC 光标设置总结
  详细解决方案

MFC 光标设置总结

热度:43   发布时间:2023-09-27 16:56:29.0

 

引言

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

 

函数功能分析

LoadCursorA

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

语法

HCURSOR LoadCursorA(HINSTANCE hInstance,LPCSTR    lpCursorName
);

参数

- hInstance

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

- lpCursorName

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

 

Value Meaning 翻译
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-beam I型标
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 styleCURSOR_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 styleCURSOR_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 granularitystd::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
?
}

 

  相关解决方案