📅  最后修改于: 2023-12-03 15:22:32.635000             🧑  作者: Mango
你是否曾遇到过自己购买了多款不同的鼠标,想要将它们的外观统一,却又不想花费大量的金钱去购买特定的鼠标外壳?
本篇文章将为您介绍如何使用C#语言编写一个免费的鼠标外观统一软件,以方便你在不同的场合下使用不同的鼠标,却仍能让它们的外观保持一致。
在开始前,我们需要先明确几个需求:
能够读取当前使用的鼠标的ID号码;
能够将鼠标外观替换为统一的外观;
能够在程序关闭前,恢复原来鼠标的外观。
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
[DllImport("user32.dll")]
static extern bool GetCursorInfo(out CURSORINFO pci);
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINT ptScreenPos;
}
// 获取当前使用的鼠标ID
int GetCursorId()
{
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (!GetCursorInfo(out pci))
{
throw new Exception("GetCursorInfo API failed!");
}
var id = pci.hCursor.ToInt32();
if (id == 65538 || id == 65539)
{
return 0; // 0为系统默认
}
else
{
return id;
}
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);
// 替换鼠标外观
bool ReplaceCursorImage(string fileName)
{
var result = SystemParametersInfo(0x0057, 0, Marshal.StringToHGlobalUni(fileName), 0x01 | 0x02);
if (!result)
{
throw new Exception("SetCursor API failed!");
}
return true;
}
private const string RegPath = @"Control Panel\Cursors";
private readonly string[] _cursorNames = { "Arrow", "Help", "AppStarting", "Wait", "Crosshair", "IBeam", "SizeNS", "SizeWE", "SizeNWSE", "SizeNESW", "UpArrow", "No" };
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetSystemCursor(IntPtr hcur, uint id);
// 恢复鼠标原来的外观
bool ResetCursorImage()
{
var baseKey = Registry.CurrentUser.OpenSubKey(RegPath, true);
if (baseKey == null)
{
throw new Exception($"Cannot open {RegPath} registry key.");
}
foreach (var name in _cursorNames)
{
var file = baseKey.GetValue(name) as string;
if (!string.IsNullOrEmpty(file))
{
var fullPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), file);
SetSystemCursor(System.Windows.Forms.Cursors.Default.Handle, (uint)Enum.Parse(typeof(System.Windows.Forms.Cursors), name));
}
}
return true;
}
将以上三个方法整合到一个程序里:
class Program
{
static void Main(string[] args)
{
try
{
var id = GetCursorId();
var image = "new_cursor_file.cur";
Console.WriteLine($"Current cursor ID: {id}");
ReplaceCursorImage(image);
Console.WriteLine($"Replaced cursor ID: {GetCursorId()}");
Console.ReadKey(true);
ResetCursorImage();
Console.WriteLine($"Reset cursor ID: {GetCursorId()}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
[DllImport("user32.dll")]
static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool SetSystemCursor(IntPtr hcur, uint id);
[StructLayout(LayoutKind.Sequential)]
struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINT ptScreenPos;
}
bool ReplaceCursorImage(string fileName)
{
var result = SystemParametersInfo(0x0057, 0, Marshal.StringToHGlobalUni(fileName), 0x01 | 0x02);
if (!result)
{
throw new Exception("SetCursor API failed!");
}
return true;
}
int GetCursorId()
{
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (!GetCursorInfo(out pci))
{
throw new Exception("GetCursorInfo API failed!");
}
var id = pci.hCursor.ToInt32();
if (id == 65538 || id == 65539)
{
return 0;
}
else
{
return id;
}
}
private const string RegPath = @"Control Panel\Cursors";
private readonly string[] _cursorNames = { "Arrow", "Help", "AppStarting", "Wait", "Crosshair", "IBeam", "SizeNS", "SizeWE", "SizeNWSE", "SizeNESW", "UpArrow", "No" };
bool ResetCursorImage()
{
var baseKey = Registry.CurrentUser.OpenSubKey(RegPath, true);
if (baseKey == null)
{
throw new Exception($"Cannot open {RegPath} registry key.");
}
foreach (var name in _cursorNames)
{
var file = baseKey.GetValue(name) as string;
if (!string.IsNullOrEmpty(file))
{
var fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), file);
SetSystemCursor(Cursors.Default.Handle, (uint)Enum.Parse(typeof(Cursors), name));
}
}
return true;
}
}
到此,我们已经完成了本篇文章的编写,成功实现了一个免费的鼠标外观统一软件。本文所讲述的代码已经实现了所提到的三个需求,并且较为简单易懂,希望能够对大家有所帮助。如果您在使用过程中遇到了问题,欢迎留言,我们会在最短的时间内回复您,祝大家使用愉快!