是的,我确实知道有很多这样的问题,但没有一个对我有用。 我需要检查系统光标是否被隐藏。
我试过了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
大部分时间都有效)。这涵盖了大多数浏览器。
老实说,我认为在检测隐藏光标方面我们无能为力。在极少数情况下,光标未隐藏但我的应用程序认为它是隐藏的或相反,我决定只让用户单击设置中的按钮,在设定的时间后将当前光标句柄添加到异常(exception)情况。
最佳答案
检测光标是否隐藏的方法不止一种。有时,系统会被告知不要渲染它,有时软件本身不会渲染它,有时它会将其渲染为不是光标的东西(例如数字艺术画笔轮廓)。
在最常见的情况下,当系统本身不呈现光标时,您所要做的就是检查光标标志是否为 0(隐藏)。 (或者走捷径检查 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;
}
现在,我们几乎完成了,但不要忘记会有异常(exception)。例如,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 可能意味着 A 指向软件 B,但 C 指向软件 D。这不太可能,但如果你想更加安全,异常(exception)列表应该是应用程序和句柄的列表.
关于C#检测光标是否隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58652184/