Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在Windows中显示水平翻转的箭头光标?_C++_Winapi_Mfc_Mouse Cursor - Fatal编程技术网

C++ 如何在Windows中显示水平翻转的箭头光标?

C++ 如何在Windows中显示水平翻转的箭头光标?,c++,winapi,mfc,mouse-cursor,C++,Winapi,Mfc,Mouse Cursor,我注意到有几个应用程序使用水平翻转的箭头光标。例如,在Microsoft Word和写字板中,出现在段落左侧空白处的水平翻转箭头光标表示可以选择整行: 我想在我自己的应用程序中显示这个光标。但是,对于这种类型的游标,似乎没有预定义的常量 如何以编程方式在WinAPI或MFC中创建此光标?没错,这是Windows应用程序中相当常见的鼠标光标样式。令人费解的是,它没有作为标准游标之一包括在内,这使得应用程序开发人员的工作更加困难 评论中建议您可以自己在Paint中创建该游标(或下载其他人创建的游标

我注意到有几个应用程序使用水平翻转的箭头光标。例如,在Microsoft Word和写字板中,出现在段落左侧空白处的水平翻转箭头光标表示可以选择整行:

我想在我自己的应用程序中显示这个光标。但是,对于这种类型的游标,似乎没有预定义的常量


如何以编程方式在WinAPI或MFC中创建此光标?

没错,这是Windows应用程序中相当常见的鼠标光标样式。令人费解的是,它没有作为标准游标之一包括在内,这使得应用程序开发人员的工作更加困难

评论中建议您可以自己在Paint中创建该游标(或下载其他人创建的游标),然后将其作为资源包含在应用程序二进制文件中,但这有一些非常明显的缺点。它不仅使二进制文件膨胀,而且还意味着光标样式本质上是硬编码的。默认的箭头鼠标光标甚至在Windows版本中已经更改了好几次,因此您需要在不同版本的“翻转”光标之间动态地进行维护和选择,以便与默认光标兼容,更不用说自定义光标或选择不同内置主题的用户了(如“倒置”)。因此,我强烈反对这种做法

正确的解决方案是以编程方式简单地翻转用户当前的箭头光标。这可确保翻转的光标与用户首选的光标样式匹配。定义以下函数:

///创建基于指定游标资源的游标(la LoadCursor),
///但是已经被水平翻转了。
/// 
///@param hInstance可执行文件所在模块实例的句柄
///包含光标模板。
///@param pCursorName要加载的模板游标资源的名称,或
///使用MAKEINTRESOURCE宏创建的整数资源
///标识要加载的光标。
///@返回
///返回新创建的光标的句柄。
///@备注
///请注意,返回的游标必须在使用完毕后销毁
///通过调用@c销毁图标。
///@备注
///此函数接受错误,确保始终返回一些游标,
///即使尚未翻转。如果需要,客户端可以修改
///实现抛出异常或返回NULL以响应错误。
HCURSOR CreateCursorFlipped(HINSTANCE HINSTANCE,LPCTSTR pCursorName)
{
//加载指定的光标以用作模板。
HCURSOR HCURSOR=LoadCursor(hInstance,pCursorName);
//获取光标模板的基础位图。
ICONINFO ii;
if(GetIconInfo(hCursor和ii))
{
//检索有关位图的信息。
位图bm;
if(GetObject(ii.hbmMask,sizeof(bm),&bm)=sizeof(bm))
{
//创建与屏幕兼容的设备上下文,并将光标位图绘制到
//它在X轴上翻转,以创建新的光标位图。
HDC HDC=CreateCompatibleDC(空);
如果(hDC)
{
HBITMAP hBmpOriginal=(HBITMAP)SelectObject(hDC,ii.hbmMask);
拉伸BLT(hDC,
bm.bmWidth-1,
0,
-bm.bm宽度,
bm.bm身高,
hDC,
0,
0,
bm.bm宽度,
bm.bm身高,
复印件);
if(二、hbmColor)
{
选择对象(hDC,ii.hbmColor);
拉伸BLT(hDC,
bm.bmWidth-1,
0,
-bm.bm宽度,
bm.bm身高,
hDC,
0,
0,
bm.bm宽度,
bm.bm身高,
复印件);
}
选择对象(hDC、hBmpOriginal);
DeleteDC(hDC);
}
//水平翻转新光标的热点。
ii.xHotspot=(bm.bmWidth-1-ii.xHotspot);
//创建一个新光标。
HCURSOR hCursorNew=CreateIconIndirect(&ii);
如果(hCursorNew)
{
hCursor=hCursorNew;
}
}
//删除不需要的位图。
删除对象(ii.hbmMask);
if(二、hbmColor)
{
删除对象(ii.hbmColor);
}
}
返回hCursor;
}
(如果您使用的是MFC,那么可以使用包装类和RAII进一步简化此代码。)

要获取问题中描述的水平翻转箭头光标,用法如下:

CreateCursorFlipped(nullptr,IDC_箭头);

但是请记住,因为
CreateCursorFlipped
实际上创建了一个新的游标(而不仅仅是加载一个系统游标),您必须在使用完光标后通过调用
destroy icon

来销毁光标。您可以使用一些图像编辑器创建自己的光标以加载,就像图标或其他资源一样。在“画笔”中创建自己的光标-这是我想要避免的:-)但是如果没有更好的方法,我将把时间花在这个解决方案上;-)没有股票光标,如果你用谷歌搜索左手光标,有很多现有的光标,例如下载:一种方法是加载IDC_箭头光标并创建翻转光标。使用StretchBlt反转宽度+CreateIConDirect创建新光标的测试: