SetSystemCursor()用于多个游标行为

dim*_*s93 6 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;
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

我的问题是当我尝试将多个游标更改为Cross cursor.如果我打电话ChangeCursors(),预期结果将被Normal cursorAND I-beam cursor取代Cross cursor.但结果真是奇怪.

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

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

所以,我的问题是,我怎么能更改2个或更多CursorsCross cursor使用SetSystemCursor()

Say*_*yka 5

不要对这种奇怪的行为感到困惑.每次分配时,只是游标被交换.

首先

Normal  ==  Normal
IBeam   ==  IBeam
Cross   ==  Cross
Run Code Online (Sandbox Code Playgroud)

您指定正常=交叉

Normal  ==  Cross
IBeam   ==  IBeam
Cross   ==  Normal
Run Code Online (Sandbox Code Playgroud)

现在分配IBeam = Cross(现在是正常的)

Normal  ==  Cross
IBeam   ==  Normal
Cross   ==  IBeam
Run Code Online (Sandbox Code Playgroud)

因此,为了不让它被交换,你必须保留所有游标的副本.我将举例说明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);
    }
}
Run Code Online (Sandbox Code Playgroud)