【问题标题】:Cursor Application Issues游标应用问题
【发布时间】:2023-01-30 00:09:20
【问题描述】:

所以我正在尝试创建一个应用程序,它显示文件夹 C:\Windows\Cursors 中的所有光标,并允许用户单击他们想要的光标图像并应用它。谢谢阅读。

我一直在尝试将 .cur 文件转换为 .jpeg,因为我认为这是它没有显示在 flowLayoutPanel1 下但仍然无法正常工作的原因。

using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;
using ImageMagick;

namespace CrossHare
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool SystemParametersInfo(int uiAction, int uiParam, IntPtr pvParam, int fWinIni);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern IntPtr LoadCursorFromFile(string lpFileName);

        private const int SPI_SETCURSORS = 0x0057;
        private const int SPIF_UPDATEINIFILE = 0x01;
        private const int SPIF_SENDCHANGE = 0x02;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Get the file paths of all files in the directory
            string[] files = Directory.GetFiles(@"C:\Windows\Cursors");

            // Iterate through the file paths
            foreach (string file in files)
            {
                // Check if the file is an image file
                if (!file.EndsWith(".cur")) continue;

                try
                {
                    // Create a new button
                    Button btn = new Button();
                    //Convert cur file to jpeg
                    using (MagickImage image = new MagickImage(file))
                    {
                        string jpegFile = Path.ChangeExtension(file, ".jpeg");
                        image.Format = MagickFormat.Jpeg;
                        image.Write(jpegFile);
                        using (Image img = Image.FromFile(jpegFile))
                        {
                            btn.Tag = file;
                            btn.Image = img;
                        }
                    }
                    btn.Size = new Size(100, 100);
                    btn.Click += Button_Click;
                    flowLayoutPanel1.Controls.Add(btn);
                }
                catch (FileNotFoundException ex)
                {
                    // Handle file not found exception
                    MessageBox.Show("Error: " + ex.Message);
                }
                catch (OutOfMemoryException ex)
                {
                    // Handle out of memory exception
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }

        private void Button_Click(object sender, EventArgs e)
        {
            // Handle button click event
            MessageBox.Show("Button clicked!");
            // Get the selected file's path
            string filePath = ((Button)sender).Image.Tag as string;

            // Set the selected file as the "normal select" pointer in "Mouse properties"
            RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Cursors", true);
            key.SetValue("Arrow", filePath);
            key.Close();
            IntPtr hCursor = new IntPtr((int)LoadCursorFromFile(filePath));
            SystemParametersInfo(SPI_SETCURSORS, 0, hCursor, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);

        }

        private void UploadButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Cursor files (*.cur)|*.cur|All files (*.*)|*.*";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                // Get the selected file's path
                string filePath = openFileDialog.FileName;
                // Do something with the file (e.g. upload it to a server)
                string destinationPath = @"C:\Windows\Cursors";
                string destinationFilePath = Path.Combine(destinationPath, Path.GetFileName(filePath));
                if (File.Exists(destinationFilePath))
                {
                    DialogResult result = MessageBox.Show("File already exists, do you want to overwrite it?", "File Exists", MessageBoxButtons.YesNo);
                    if (result == DialogResult.No)
                    {
                        return;
                    }
                }
                File.Copy(filePath, destinationFilePath, true);
            }
        }
    }
}

【问题讨论】:

  • 您是否真的在尝试更改文件的扩展名,希望它也更改其格式? -- 你可以用new Cursor([Path of cursor])加载一个游标,然后使用它的Draw()方法把它绘制成一个大小为[Cursor].Size的位图
  • 请注意,处置/销毁(如 hCursor 所指向的)您创建的资源不是可选的。你真的必须

标签: c# winforms imagemagick jpeg


【解决方案1】:

仔细阅读您的代码,如果我的理解正确的话,您的目标是让 FlowLayoutPanel 显示所有可用的光标。我们在这里得到的结果可以被认为是X-Y Problem,因为这样做很简单,但您尝试解决问题的方式却并非如此。

请允许我将其引导回到您开始尝试做的事情:


为了实现这个目标,使用反射从Cursors类中获取光标,绘制每一个,并在FlowLayoutPanel中放置一个相应的按钮。

public partial class MainForm : Form
{
    public MainForm()=>InitializeComponent();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        foreach (var pi in typeof(Cursors).GetProperties(BindingFlags.Static | BindingFlags.Public))
        {
            if(pi.GetValue(null) is Cursor cursor)
            {
                var image = new Bitmap(100, 100);
                using (var graphics = Graphics.FromImage(image))
                {
                    cursor.DrawStretched(
                        graphics,
                        new Rectangle(new Point(), new Size(100, 100)));
                }
                var button = new Button
                {
                    Size = image.Size,
                    BackgroundImage = image,
                    BackgroundImageLayout = ImageLayout.Stretch,
                    Margin = new Padding(5),
                    Tag = cursor,
                };
                button.Click += onAnyClickCursorButton;
                button.MouseHover += (sender, e) => Cursor = Cursors.Default;
                flowLayoutPanel.Controls.Add(button);
            }
        }
    }

通过将 Click 事件附加到每个按钮,我们可以将当前的 Cursor 更改为单击的按钮,如果将鼠标悬停在不同的按钮上,则返回默认值。

    private void onAnyClickCursorButton(object? sender, EventArgs e)
    {
        if((sender is Button button) && (button.Tag is Cursor cursor)) 
        {
            Cursor = cursor;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多