c# - C#检测光标是否隐藏
问题描述
是的,我确实意识到有很多这样的问题,但没有一个对我有用。我需要检查系统光标是否隐藏。
我试过了Cursor.Current == null
。它从来没有做任何事情。(我用全屏 Youtube、Discord 和 Krita 隐藏了光标)。
我还尝试使用GetCursorInfo
user32.dll 并检查标志是否为 0(隐藏)。没有什么。
[StructLayout( LayoutKind.Sequential )]
struct POINT {
public Int32 x;
public Int32 y;
}
[StructLayout( LayoutKind.Sequential )]
struct CURSORINFO {
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINT ptScreenPos;
}
[DllImport( "user32.dll" )]
static extern bool GetCursorInfo ( out CURSORINFO pci );
public static bool CursorHidden () {
CURSORINFO cinfo;
cinfo.cbSize = Marshal.SizeOf( typeof( CURSORINFO ) );
GetCursorInfo( out cinfo );
return cinfo.flags == 0;
}
我的目标是在光标隐藏时隐藏屏幕覆盖 UI。
那么,如何检查系统光标是否以其他方式隐藏?
编辑:
好的,我在 Ahmed Abdelhameed 的帮助下有了一个发现。基本上,浏览器等不会呈现光标,但系统仍然认为它是可见的。但是,手柄发生了变化。系统默认提供的句柄数量有限(Cursors.<Name>.Handle
),并且不可见的浏览器光标不使用它们。
enum CursorTypes { ... }
...
CURSORINFO cinfo;
... // see code above
Cursor[] cursors = new Cursor[] { ... }; // listed all of them in the same order as CursorTypes
int type = 1;
foreach ( Cursor cursor in cursors ) {
if ( cinfo.hCursor == cursor.Handle ) {
return (CursorTypes)type;
}
type++;
}
return CursorTypes.Other;
然而,这不是一个完整的解决方案,因为浏览器和其他软件可以创建一种新类型的光标,而不是不可见的(如在 VS 中向后倾斜),它也会返回CursorTypes.Other
。
正如 Herohtar 指出的那样,隐藏游标通常具有较大的指针值(在我的情况下,Math.Abs( pointer ) > 10000000
大部分时间都有效)。这涵盖了大多数浏览器。
老实说,我认为在检测隐藏光标方面我们能做的不多。在极少数情况下,光标没有隐藏,但我的应用程序认为它是隐藏的,或者相反,我决定只选择让用户单击设置中的一个按钮,该按钮在一段时间后将当前光标句柄添加到例外。
解决方案
检测光标是否隐藏的方法不止一种。有时,系统会被告知不要渲染它,有时软件本身不会渲染它,有时它会将它渲染为不是光标的东西(例如数字艺术画笔轮廓)。
在最常见的情况下,当系统本身不渲染光标时,您所要做的就是检查光标标志是否为 0(隐藏)。(或采取 shrotcut 并检查是否Cursor.Current == null
)
[StructLayout( LayoutKind.Sequential )]
struct POINT {
public Int32 x;
public Int32 y;
}
[StructLayout( LayoutKind.Sequential )]
struct CURSORINFO {
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINT ptScreenPos;
}
[DllImport( "user32.dll" )]
static extern bool GetCursorInfo ( out CURSORINFO pci );
CURSORINFO GetCinfo () {
CURSORINFO cinfo;
cinfo.cbSize = Marshal.SizeOf( typeof( CURSORINFO ) );
GetCursorInfo( out cinfo );
return cinfo;
}
public bool FlagHidden () {
CURSORINFO cinfo = GetCinfo();
return cingo.flags == 0 || Cursor.Current == null; // using both for extra safety
}
现在我们遇到网络浏览器。浏览器不会呈现隐藏的光标,但它们会更改光标句柄。大多数时候,但不一定总是句柄的值会很大。
public bool BrowserHidden () {
CURSORINFO cinfo = GetCinfo();
return Math.Abs( cinfo.hCursor.ToInt64() ) > 10000000;
}
现在,我们差不多完成了,但不要忘记会有例外。例如,Krita 在隐藏光标的同时渲染画笔的轮廓,但就系统而言,光标仍然可见。没有一种简单、通用的方法来处理这个问题,因此我们几乎必须明确告诉我们的软件注意这些特定情况。
List<IntPtr> exceptions = new List<IntPtr>{ ... }; // put all the common exceptions here, implement some way to add / remove them
public bool IsException () {
CURSORINFO cinfo = GetCinfo();
return exceptions.Contains( cinfo.hCursor );
}
public bool CursorHidden () {
bool hidden = FlagHidden() || BrowserHidden();
return hidden != IsException(); // hidden xor exception ( inverts hidden if its an exception )
}
可能存在指针 X 对软件 B 表示 A 而对软件 D 表示 C 的情况。这不太可能,但如果您想更加安全,例外列表应该是应用程序和句柄的列表。
推荐阅读
- javascript - $ajax 不工作,但 $post 工作
- azure - Azure CDN - 图像响应 404 到 CURL
- python - 如何用pynput按windows键?
- html - VF:是否可以只显示数据表中的特定行?
- mongodb - Golang中创建mongodb索引的方法
- python - Conda 使用 .yml 文件创建环境失败
- python - on_message 问题时未向用户发送消息
- python - 有没有办法阻止 rpy2 自动转换所有内容?
- python - Seaborn 热图混淆矩阵显示未按预期显示
- javascript - 在 ChartJS 中将两个折线图合二为一