c# - 用于多个游标行为的 SetSystemCursor()

标签 c# winforms

我正在尝试将多个光标更改为 Cross cursor。这是我为此使用的代码:

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

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

//Normal cursor
private static uint OCR_NORMAL = 32512;
//The text selection (I-beam) cursor.
private static uint OCR_IBEAM = 32513;
//The cross-shaped cursor.
private static uint OCR_CROSS = 32515;

然后我使用我制作的这两个函数:

static public void ChangeCursors() {
    SetSystemCursor(LoadCursor(IntPtr.Zero, (int)OCR_CROSS), OCR_NORMAL);
    SetSystemCursor(LoadCursor(IntPtr.Zero, (int)OCR_CROSS), OCR_IBEAM);
}

static public void RevertCursors() {
    SystemParametersInfo(0x0057, 0, null, 0);
}

如果我只使用 SetSystemCursor(LoadCursor(IntPtr.Zero, (int)OCR_CROSS), OCR_NORMAL);,一切正常。 Normal cursor 被替换为 Cross cursor

我的问题是当我尝试将多个光标 更改为Cross cursor 时。如果我调用 ChangeCursors(),预期结果将是 Normal cursor 并且 I-beam cursor 被替换为 Cross cursor。但是结果真的很奇怪。

当软件启动时根据程序启动时光标的当前状态,会发生以下奇怪的事情:

  • 如果软件启动时光标是Normal,它会变为Cross(这很好)。此外,I-beam 被替换为 Normal(这很糟糕,应该是 Cross)。
  • 如果软件启动时光标是I-beam,它将保持I-beam(这很糟糕,因为它应该是Cross) .然后,将鼠标悬停在之前光标应该是 Normal 的位置,现在是 Cross(很好)。然后,如果我将鼠标悬停在 1 秒前光标所在的位置 I-beam,它会神奇地变为 Normal(这很奇怪)并保持这种状态。

所以,我的问题是,如何使用 SetSystemCursor() 将 2 个或更多 Cursors 更改为 Cross cursor

最佳答案

不要对奇怪的行为感到困惑。只是每次分配时光标都会交换。

一开始

Normal  ==  Normal
IBeam   ==  IBeam
Cross   ==  Cross

你分配 Normal = Cross

Normal  ==  Cross
IBeam   ==  IBeam
Cross   ==  Normal

现在分配 IBeam = Cross(现在是 Normal)

Normal  ==  Cross
IBeam   ==  Normal
Cross   ==  IBeam

所以为了不让它被交换,你必须保留所有游标的副本。我会给你一个将 Normal 和 IBeam 更改为 CROSS 的示例。

Program.cs

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

    [DllImport("user32.dll")]
    static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);

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

    [DllImport("user32.dll")]
    public static extern IntPtr CopyIcon(IntPtr pcur);

    private static uint CROSS = 32515;
    private static uint NORMAL = 32512;
    private static uint IBEAM = 32513;
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        uint[] Cursors = {NORMAL, IBEAM};

        for (int i = 0; i < Cursors.Length; i++)
            SetSystemCursor(CopyIcon(LoadCursor(IntPtr.Zero, (int)CROSS)), Cursors[i]);

        Application.Run(new Form1());
        SystemParametersInfo(0x0057, 0, null, 0);
    }
}

关于c# - 用于多个游标行为的 SetSystemCursor(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29781271/

相关文章:

c# - 间隔调度算法 : Earliest Finish Time

c# - COM 组件中的 Server.MapPath

C# 从字典中获取键 <string, Stream>

c# - 从 for 循环更新进度条

C# WinForms 在新表单中选择 ComboBox 项

c# - 这是对 'dynamic' 的滥用吗?

c# - 将对象转换为不带 header 的 CSV 字符串 Servicestack CSVSerializer

c# - 覆盖 ProcessCmdKey C#

.net - 重置 GDI+ 转换矩阵中的比例

c# - 什么更好用: a DataGrid or ListView for displaying large amounts of data?