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

C# Winform Aot发布DataGridView复制问题

dgx6663个月前 (03-14)文章中心11

这几天使用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复制问题” 的相关文章

楼上邻居弹琴跑调到“离谱”,楼下的操作亮了

俗话说“远亲不如近邻”邻里间的互动有时候可谓非常有趣近日,山东菏泽“致楼上邻居的一封信”在网上走红一位热心又专业的邻居老王写信对邻居练钢琴提出了一些“指导意见”指出了两首曲子中的错误还附上了自己精心准备的乐谱谁还没有一个练琴的邻居了网友们纷纷分享了自己或者邻居的“陪练”经历这封“钢琴指导”信张贴后...

行政牛马生存指南之:如何在公文写作上修炼成精

作为在神秘东方大国某500强公文流水线上拧过6年螺丝的老黄牛,今天带各位行政牛马见识下,如何在公文写作上修炼成精之--原来拟定一篇公文管理制度这么简单。【首先:要看懂公文江湖黑话】"请相关部门协同推进"=甩锅接力赛开始"原则同意但需完善"=重写十遍起"拟同意呈领导阅示"=你的死活与我无关【其次:要掌...

公文写作:格式篇(一)——你的材料字体不对

你的材料字体不对很多人,尤其是刚毕业的新打工人,尤其是在国企和体制内的新打工人,相信很多都面临过这样一个场景:领导说我的材料格式不对。当我把打印好的材料拿给领导时,领导只看了一眼就对我说:“字体不对。”这在当时让我对领导敬畏不已。直到大概一年后我发现自己好像也能一眼看出别人的材料字体不对,才明白这个...

中文版AutoCAD 2014机械图形设计

《中文版AutoCAD 2014机械图形设计》介绍了AutoCAD 2014在机械图形绘制方面的应用,内容丰富翔实,具有很高的参考价值。《中文版AutoCAD 2014机械图形设计》分基础篇和实践篇两部分。基础篇介绍了AutoCAD 2014的基本概念与基本操作。其中包括:绘制与编辑二维图形、图层设...

cad2010~2014闪退的原因和解决方法(绝对有效)

在win10中,CAD2010~2014软件安装后,用注册机后,一打开就闪退是什么原因呢?遇到这类问题,我们该如何解决呢?一起来我的经验吧!。首先,CAD软件一打开就闪退,这种情况可能是ADLM文件已经被破坏,需要我们重新修复。具体步骤如下:第一步:打开电脑C盘。第二步:输入flexnet进行搜索。...

CAD2014到2023版哪个版更稳定好用?

CAD软件的发展是一个持续的过程,每个版本都在不断地改进和优化。因此,无法简单地回答CAD2014到2023版哪个版本更稳定好用这个问题,因为每个版本都有其自身的优点和缺点。CAD2014:是一款经典的设计软件,具有简单易用的界面和强大的功能。它支持多种文件格式,包括DWG和DXF。CAD2014提...