0

我知道如何从 xxx.cur 文件设置系统光标,但我想知道如何将当前系统光标保存到文件中。

在 WPF 中,设置系统光标可以使用以下代码:

[DllImport("user32.dll")]
internal static extern IntPtr LoadCursorFromFile(string lpFileName);
[DllImport("user32.dll")]
internal static extern bool SetSystemCursor(IntPtr hcur, uint id);
internal const uint OCR_NORMAL = 32512;
IntPtr hAni = Win32Api.LoadCursorFromFile("file.cur");
bool b = SetSystemCursor(hAni, Win32Api.OCR_NORMAL);

但我不知道如何将当前系统光标保存到磁盘。

谁能告诉我,谢谢。

4

1 回答 1

0

这可能有点难看,而且我发布的代码没有很好地分解(描述解决方案很粗糙),但是您可以从注册表中拉出当前游标,然后再次将它们保存回来。

public class UserCursors
{
    [Serializable]
    internal enum ImageType
    {
        Bitmap = 0,
        Icon = 1,
        Cursor = 2,
        EnhMetafile = 3,
    }

    [Serializable, Flags]
    internal enum LoadImageFlags
    {
        DefaultColor = 0x0,
        Monochrome = 0x1,
        Color = 0x2,
        CopyReturnOriginal = 0x4,
        CopyDeleteOriginal = 0x8,
        LoadFromFile = 0x10,
        LoadTransparent = 0x20,
        DefaultSize = 0x40,
        VgaColor = 0x80,
        LoadMap3DColors = 0x1000,
        CreateDibSection = 0x2000,
        CopyFromResource = 0x4000,
        Shared = 0x8000,
    }

    [DllImport("user32.dll")]
    static extern IntPtr LoadImage(IntPtr hinst, String lpszName, ImageType uType, Int32 cxDesired, Int32 cyDesired, LoadImageFlags fuLoad);

    public IntPtr hInst = IntPtr.Zero;
    public String lpszName;
    public Int32 width = 0;
    public Int32 height = 0;
    public string regKeyName = String.Empty;
    public bool Changed = false;

    public UserCursors()
    {

    }

    public UserCursors(string cursorLocation, string keyName)
    {
        hInst = LoadImage(IntPtr.Zero, cursorLocation, ImageType.Cursor, width, height, LoadImageFlags.LoadFromFile);
        lpszName = cursorLocation;
        regKeyName = keyName;
    }
}

然后创建一个列表例如

public List<UserCursors> systemCursors;

加载列表

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetSystemCursor(IntPtr hcur, uint id);
const uint OCR_NORMAL = 32512;
const uint OCR_HAND = 32649;
const uint OCR_IBEAM = 32513;

        IntPtr hArrow = LoadImage(IntPtr.Zero, "<my custom cursor file>", ImageType.Cursor, width, height, LoadImageFlags.LoadFromFile);
        IntPtr hHand = LoadImage(IntPtr.Zero, "<my custom cursor file>", ImageType.Cursor, width, height, LoadImageFlags.LoadFromFile);
        IntPtr hBeam = LoadImage(IntPtr.Zero, "<my custom cursor file>", ImageType.Cursor, width, height, LoadImageFlags.LoadFromFile);

        RegistryKey myCursors = Registry.CurrentUser.OpenSubKey(defaultCursors);
        string[] keyCursors = myCursors.GetValueNames();
        bool beamFound = false;
        int lastError = 0;

        foreach (string cursorKey in keyCursors)
        {
            RegistryValueKind rvk = myCursors.GetValueKind(cursorKey);
            switch (rvk)
            {
                case RegistryValueKind.ExpandString:
                    string cursorValue = myCursors.GetValue(cursorKey) as string;
                    if (!String.IsNullOrEmpty(cursorValue))
                    {
                        UserCursors currentSystemCursor = new UserCursors(cursorValue, cursorKey);
                        switch (cursorKey)
                        {
                            case "Arrow":
                                currentSystemCursor.Changed = SetSystemCursor(hArrow, OCR_NORMAL);
                                break;
                            case "Hand":
                                currentSystemCursor.Changed = SetSystemCursor(hHand, OCR_HAND);
                                if (!currentSystemCursor.Changed)
                                {
                                    lastError = Marshal.GetLastWin32Error();
                                    Win32Exception ex = new Win32Exception(lastError);
                                }
                                break;
                            case "IBeam":
                                beamFound = true;
                                currentSystemCursor.Changed = SetSystemCursor(hBeam, OCR_IBEAM);
                                break;
                            default:
                                break;
                        }
                        systemCursors.Add(currentSystemCursor);
                    }
                    break;
                default:
                    break;
            }
        }

        // if a user hasn't customised the IBeam then it doesn't appear in the registry so we still change it
        // and then clear the value to remove it.
        if (!beamFound)
        {
            UserCursors currentSystemCursor = new UserCursors("C:\\Windows\\Cursors\\beam_i.cur", "IBeam");
            currentSystemCursor.Changed = SetSystemCursor(hBeam, OCR_IBEAM);
            systemCursors.Add(currentSystemCursor);
        }

然后在析构函数或 finalize 或类似的

    ~MainWindow()
    {
        int lastError = 0;
        bool changed = false;

        foreach (UserCursors savedCursor in systemCursors)
        {
            if (savedCursor.Changed)
            {
                switch (savedCursor.regKeyName)
                {
                    case "Arrow":
                        changed = SetSystemCursor(savedCursor.hInst, OCR_NORMAL);
                        if (!changed)
                        {
                            lastError = Marshal.GetLastWin32Error();
                            Win32Exception ex = new Win32Exception(lastError);
                        }
                        break;
                    case "Hand":
                        changed = SetSystemCursor(savedCursor.hInst, OCR_HAND);
                        if (!changed)
                        {
                            lastError = Marshal.GetLastWin32Error();
                            Win32Exception ex = new Win32Exception(lastError);
                        }
                        break;
                    case "IBeam":
                        changed = SetSystemCursor(savedCursor.hInst, OCR_IBEAM);
                        if (!changed)
                        {
                            lastError = Marshal.GetLastWin32Error();
                            Win32Exception ex = new Win32Exception(lastError);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
于 2012-05-19T00:44:26.093 回答