首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 設置鼠標為自定義動畫光標:API 調用完整指南

     編輯:關於C#

一、為什麼需要 API 調用

Windows Forms 控件的 Cursor 屬性僅支持靜態 .cur 文件,不支持動畫光標 .ani。需調用 Win32 API:LoadCursorFromFile 加載光標文件,SetSystemCursor 設置系統類光標。

二、API 簽名與常量

using System.Runtime.InteropServices;

public static class NativeMethods {
    // 從文件加載光標(支持 .cur 和 .ani)
    [DllImport("user32.dll", EntryPoint = "LoadCursorFromFileW", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr LoadCursorFromFile(string lpFileName);
    
    // 設置系統光標
    [DllImport("user32.dll", EntryPoint = "SetSystemCursor", SetLastError = true)]
    public static extern bool SetSystemCursor(IntPtr hcur, uint id);
    
    // 系統光標 ID 常量
    public const uint OCR_NORMAL = 32512;       // 普通箭頭
    public const uint OCR_IBEAM = 32513;        // 文本輸入
    public const uint OCR_WAIT = 32514;         // 等待(沙漏)
    public const uint OCR_CROSS = 32515;        // 十字
    public const uint OCR_UP = 32516;           // 向上箭頭
    public const uint OCR_SIZENWSE = 32517;     // 雙向調整大小
    public const uint OCR_SIZENESW = 32518;
    public const uint OCR_SIZEWE = 32519;
    public const uint OCR_SIZENS = 32520;
    public const uint OCR_SIZEALL = 32521;
    public const uint OCR_NO = 32648;           // 禁止
    public const uint OCR_HAND = 32649;         // 手形
    public const uint OCR_APPSTARTING = 32650;  // 應用啟動中
}

三、窗體級應用:進入窗體顯示動畫光標,離開恢復默認

public partial class MainForm : Form {
    private IntPtr _customCursor = IntPtr.Zero;
    private IntPtr _originalCursor = IntPtr.Zero;
    private const string CursorFileName = "custom_cursor.ani"; // 放在輸出目錄
    
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        string path = Path.Combine(Application.StartupPath, CursorFileName);
        if (File.Exists(path)) {
            // 保存原始系統光標(可選,這裡演示加載默認箭頭作為恢復)
            _originalCursor = NativeMethods.LoadCursorFromFile(@"C:\Windows\Cursors\arrow.cur");
            // 加載自定義動畫光標
            _customCursor = NativeMethods.LoadCursorFromFile(path);
            if (_customCursor != IntPtr.Zero) {
                NativeMethods.SetSystemCursor(_customCursor, NativeMethods.OCR_NORMAL);
            }
        }
    }
    
    protected override void OnFormClosing(FormClosingEventArgs e) {
        // 恢復系統默認光標
        if (_originalCursor != IntPtr.Zero) {
            NativeMethods.SetSystemCursor(_originalCursor, NativeMethods.OCR_NORMAL);
        }
        base.OnFormClosing(e);
    }
}

四、關鍵注意事項

  1. 全局影響:SetSystemCursor 修改的是**系統級**光標,影響所有應用程序。僅在窗體激活時設置,關閉時恢復,否則用戶離開程序後光標仍為動畫。
  2. 文件路徑:.ani 文件需設置「複製到輸出目錄」為「較新時複製」或「始終複製」。
  3. 權限:Vista+ 需管理員權限才能設置系統光標,普通權限調用會失敗(返回 false,Marshal.GetLastWin32Error() 為 5/ERROR_ACCESS_DENIED)。
  4. 替代方案:若不想全局影響,可在窗體 MouseEnter 設置 this.Cursor = new Cursor(cursorStream)(僅支持靜態 .cur),或用 SetClassLongPtr 修改窗體類光標(僅影響該窗體類實例)。
  5. 資源釋放:LoadCursorFromFile 返回的句柄由系統管理,無需手動 DestroyCursor,但最好在應用退出時恢復原狀。

五、僅影響當前窗體的替代實現

[DllImport("user32.dll", EntryPoint = "SetClassLongPtr", SetLastError = true)]
private static extern IntPtr SetClassLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

[DllImport("user32.dll", EntryPoint = "GetClassLongPtr", SetLastError = true)]
private static extern IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex);

private const int GCLP_HCURSOR = -12;

public void SetFormCursor(string aniPath) {
    IntPtr hCursor = NativeMethods.LoadCursorFromFile(aniPath);
    if (hCursor != IntPtr.Zero) {
        // 修改窗體類光標,僅影響該窗體實例
        SetClassLongPtr(this.Handle, GCLP_HCURSOR, hCursor);
        // 強制重繪
        this.Invalidate();
    }
}

此法無需管理員權限,僅影響當前窗體類的所有實例,體驗更好。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved