C#获取当前鼠标指针图标

4

我一直在尝试做这件事,但是一直没有成功,以下是我得到的结果:

[DllImport("user32.dll")]
static extern bool SetSystemCursor(IntPtr hcur, uint id);

[DllImport("user32.dll", EntryPoint = "GetCursorInfo")]
public static extern bool GetCursorInfo(out CURSORINFO pci);

[DllImport("user32.dll", EntryPoint = "CopyIcon")]
public static extern IntPtr CopyIcon(IntPtr hIcon);

[StructLayout(LayoutKind.Sequential)]
public struct CURSORINFO
{
    public Int32 cbSize;        // Specifies the size, in bytes, of the structure. 
    public Int32 flags;         // Specifies the cursor state. This parameter can be one of the following values:
    public IntPtr hCursor;          // Handle to the cursor. 
    public POINT ptScreenPos;       // A POINT structure that receives the screen coordinates of the cursor. 
}

public void etc()
{
    IntPtr hwndic = new IntPtr();
    CURSORINFO curin = new CURSORINFO();
    curin.cbSize = Marshal.SizeOf(curin);
    if (GetCursorInfo(out curin))
    {
        if (curin.flags == CURSOR_SHOWING)
        {
            hwndic = CopyIcon(curin.hCursor);
            SetSystemCursor(hwndic, OCR_NORMAL);
        }
    }
}

问题在于复制的图标有时与默认的鼠标图标不同。例如,如果它在等待位置捕获到了鼠标,则可能会给我鼠标等待图标。
我希望能够获取正在运行系统的默认光标图标(空闲时的图标),我该怎么做?
提前感谢。

看一下 LoadCursor 和 IDC_ARROW 常量。 - Pascalz
@Pascalz,那对我没有帮助,它无法检测到系统光标的位置。 - Matan Yashar
你能在复制之前设置 Cursor.Current = Cursors.Default 吗? - obl
@obl 我之前尝试过,但它说成员“cursor.current”无法通过实例引用访问,请改用类型名称限定它。据我所知,光标命令只能在表单设计器文件中使用,而不能在其外部使用。因此,即使我在应用程序启动时成功获取了光标图标,用户可能会在之后更改光标图标,我将无法返回到上一个用户更改的光标图标。 - Matan Yashar
@obl,你说的那个方法即使能够实现,也不会正常工作,因为setsystemcursor函数会将光标粘贴成比应有的更多的阴影。无论如何,我已经解决了这个问题,并会在本帖中回答。 - Matan Yashar
显示剩余2条评论
1个回答

1

经过一些研究,我解决了我的问题,并找到了一种有用的方法,可以始终奏效。

与其尝试保存光标图标并加载它,我想到了一个不同的想法。

我注意到每当我更改光标图标(比如使用代码更改为某个随机图标),然后去到Windows光标设置时,图标并没有在那里改变,但是因为Windows认为我正在使用这些设置,所以没有应用按钮来应用之前的设置。

因此,我将设置更改为其他随机设置,没有应用就返回到之前的设置,并应用,这样就将光标重置为更改之前的原始光标。

因此,Windows只是在“刷新”鼠标,所以我这么做了,也许如果我能强制刷新一切都会完美无缺,于是我发现了一种方法,使用这个函数:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SystemParametersInfo(UInt32 uiAction,UInt32 uiParam, String pvParam, UInt32 fWinIni);

当我浏览msdn时,发现了一个有趣的参数"SPI_SETCURSORS (0x57)",并且我引用它的描述:

"重新加载系统光标。将uiParam参数设置为零,将pvParam参数设置为NULL。"

所以我尝试了一下,它确实有效,以下是此过程的示例:

[DllImport("User32.dll", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern IntPtr LoadCursorFromFile(String str);

uint SPI_SETCURSORS = 0x57;
var NewArrow = LoadCursorFromFile("C:\\Users\\mtnju\\Downloads\\invisible.cur"); // loads some new cursor icon using the LoadCursorFromFile function
SetSystemCursor(NewArrow, OCR_NORMAL); // sets the new cursor icon using the SetSystemCursor function
SystemParametersInfo(SPI_SETCURSORS, 0, null, 0);// reloads all of the system cursors

我本以为能在5分钟内完成类似这样的事情......希望这对你们有所帮助,非常感谢那些试图帮助我的评论。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接