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

我正在尝试将多个游标更改为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,OCR_IBEAM);
}

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

如果我只使用SetSystemCursor(LoadCursor(IntPtr.Zero,OCR_NORMAL);,一切正常. Normal游标被Cross游标替换.

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

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

>如果软件启动时光标为“正常”,则它将变为“交叉”(这很好).此外,I-beam被Normal替换(这很糟糕,它应该是Cross).
>如果在软件启动时光标是工字梁,它会保持工字梁(这很糟糕,因为它应该是十字形).然后,通过将光标悬停到之前光标应该是Normal的位置,它现在是Cross(这很好).然后,如果我在1秒前将鼠标悬停在光标所在的位置,它会神奇地变为正常(这很奇怪)并保持这种状态.

所以,我的问题是,如何使用SetSystemCursor()将2个或更多游标更改为交叉游标?

解决方法

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

首先

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

您指定正常=交叉

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

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

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,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);
    }
}

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString(&quot;x2&quot;));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable&lt;Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include &quot;WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...