当前位置:首页 > 文章中心 > 正文内容

C# Winform Aot发布DataGridView复制问题

dgx6669个月前 (03-14)文章中心60

这几天使用winform开发一个小工具,用了datagridview,但是发现当时使用复制时候,会弹出报错。

经过分析,理解 Clipboard并没办法 COM,没办法。

首先想到办法,那就是拦截 复制功能,正常来说,操作都是 按Ctrl +C。

那就直接拦截 按键操作,可是当用户处于编辑状态情况,不能拦截,需要还是正常操作。

首先需要操作剪切板,又不能使用Clipboard ,那唯一办法就是自己写api调用。分析官方文档。然后使用.NET调用

完整代码如下

internal class WindowsClipboard
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool CloseClipboard();

    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool EmptyClipboard();

    [DllImport("kernel32.dll")]
    private static extern IntPtr GlobalAlloc(uint uFlags, UIntPtr dwBytes);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GlobalLock(IntPtr hMem);

    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GlobalUnlock(IntPtr hMem);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);

    private const uint CF_UNICODETEXT = 13;
    private const uint GMEM_MOVEABLE = 0x0002;
    private const uint GMEM_ZEROINIT = 0x0040;

    public static void SetText(string text)
    {
        if (!OpenClipboard(IntPtr.Zero))
        {
            throw new Exception($"打开剪贴板失败 (错误代码: {Marshal.GetLastWin32Error()})");
        }

        try
        {
            EmptyClipboard();

            // 计算字节长度(包含终止空字符)
            var bufferSize = (text.Length + 1) * 2;
            var hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (UIntPtr)bufferSize);

            if (hGlobal == IntPtr.Zero)
            {
                throw new Exception("内存分配失败");
            }

            try
            {
                var pGlobal = GlobalLock(hGlobal);

                if (pGlobal == IntPtr.Zero)
                {
                    throw new Exception("内存锁定失败");
                }

                try
                {
                    // 将字符串复制到非托管内存
                    var bytes = Encoding.Unicode.GetBytes(text);
                    Marshal.Copy(bytes, 0, pGlobal, bytes.Length);
                }
                finally
                {
                    GlobalUnlock(hGlobal);
                }

                if (SetClipboardData(CF_UNICODETEXT, hGlobal) == IntPtr.Zero)
                {
                    throw new Exception($"设置剪贴板数据失败 (错误代码: {Marshal.GetLastWin32Error()})");
                }

                // 成功设置后,hGlobal 所有权已转移给剪贴板
                hGlobal = IntPtr.Zero;
            }
            finally
            {
                if (hGlobal != IntPtr.Zero)
                {
                    GlobalFree(hGlobal);
                }
            }
        }
        finally
        {
            CloseClipboard();
        }
    }

    [DllImport("kernel32.dll")]
    private static extern IntPtr GlobalFree(IntPtr hMem);
}

使用时候即

WindowsClipboard.SetText(clipboardText);

经过测试,aot发布后可以使用

处理DataGridView中的拦截和数据

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.KeyCode == Keys.C && e.Control)
        {
            if (!this.IsCurrentCellInEditMode)
            {
                this.EndEdit();
                if (this.SelectedCells.Count == 0)
                    return;
                // 获取所有选中的单元格并按行列排序
                var clipboardText = string.Join(Environment.NewLine,
                    this.SelectedCells.Cast()
                    .GroupBy(c => c.RowIndex)// 按行分组
                    .OrderBy(g => g.Key)// 按行号排序
                    .Select(g => string.Join("\t", 
                    g.OrderBy(c => c.ColumnIndex)
                    .Select(c => c.FormattedValue?.ToString() ?? "")))); // 使用格式化后的值

                WindowsClipboard.SetText(clipboardText);
                return;
            }
        }
        base.OnKeyDown(e);
    }

保存发布后完全没问题

扫描二维码推送至手机访问。

版权声明:本文由第六芝士网发布,如需转载请注明出处。

本文链接:http://www.dgx666.com/post/262.html

分享给朋友:

“C# Winform Aot发布DataGridView复制问题” 的相关文章

AMD Software Adrenalin Edition 24.12.1驱动:支持《潜行者2》等新游戏

AMD Software Adrenalin Edition 24.12.1驱动程序发布,支持《漫威争锋(Marvel Rivals)》、《微软模拟飞行2024》、《龙腾世纪:影障守护者(Dragon Age:The Veilguard)》、《野狗子(Slitterhead)》、《三角洲行动(Del...

已下架的腾讯 QQ HD iPadOS 版无法登录账号,提示当前版本过低

IT之家 7 月 13 日消息 去年 3 月,适用于 iPad 设备的 QQ HD 应用从苹果 App Store 下架。据IT之家网友反馈,目前使用 QQ HD iPadOS 版时会提示账号暂时无法登录,“当前版本过低,请升级到 QQ 最新版本”。这也意味着,原 QQ HD 用户需转移至通用版 Q...

AutoCAD 2014系列自学教程(1)

本期分享AutoCAD 2014中文版实用教程之《第1章 基本概念、基本操作》,下载方式见文末。...

AUTO CAD2014 激活错误处理办法

我们在安装CAD的时候,在序列号和产品密钥都正确的情况下,但就是激活不了,这是怎么回事呢?下面的方法可以给以参考,实验是可以的。这种情况的出现,多数是因为我们安装了两套或多套CAD软件造成的,第一套CAD软件可以正常激活,第二套为什么就不可以了呢....方法如下:针对证书授权错误0015.111的解...

Microsoft Office 2010办公软件详细安装教程(附安装包)

Microsoft Office乃广大用户常用办公软件,而Microsoft office 2010版本目前仍广泛应用。其全新界面便携简练,标志则转为全橙色。此版将采用新的用户界面主题,与Microsoft office 2003、2007相比,2010版改进颇多,LOGO亦有所更新,新界面更显清爽...

如何才能激活office2010?Office 2010安装及激活的详细图文教程

现在office办公用得比较多的还是office 2010,但是有很多的小伙伴不知道怎么安装和激活,我把自己的一套方法共享给大家,希望可以帮到各位小伙伴们,不走冤枉路,我还是以图片文字的形式展示出来。第一步、安装方法首先下载microsoft Office2010,然后将下载的office2010压...