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

C# Winform Aot发布DataGridView复制问题

dgx6664个月前 (03-14)文章中心19

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

vivo Pad优缺点对比,还有啥是没有的

【优点】买它之前平板产品只有一台mini5,没有用过安卓平板,下面说说我自己的感受。1. 44瓦的充电感觉满意。40分钟可以把25%的电量充到85%,后面涓流慢一点,我估计从0完全充满总共需要一个半左右吧,我一般冲到八九十就行了。所以我认为充电还可以.我手里这台mini5电池贼小充电还要差不多三个小...

CAD高版本图纸打不开,用它解决

相信用过autoCAD的人都遇见过高版本打不开低版本的图纸这个情况,这个时候通常就需要找一个版本转换器,这里就告诉大家一个不用找转换器的方式用到的操作软件:CAD梦想画图,点此进入官网。解决的问题操作步骤1.打开需要转换的图纸,点击上方“功能-高级工具”随后弹出高级工具条在里面找到“DWG版本转换”...

「AutoCAD之快捷工具」CAD自带黑科技Express Tools (ET)概述

【AutoCAD之快捷工具】CAD自带黑科技Express Tools (ET)概述神秘的安装选项CAD中有一个"犹抱琵琶半遮面"的家伙从AutoCAD 2006开始在安装软件时出现了一个叫做"express tools"的拓展选项在安装的过程之默认为:"不安装"(在此顺便鄙视一下那些强制安装、隐藏...

《丧尸围城》DirectX Error错误解决方法 DX错误进不去游戏怎么办

不少玩家打开《丧尸围城》的时候都弹出DirectX Error错误框、进不去游戏,下面为大家带来《丧尸围城》DirectX Error错误解决方法,告诉大家《丧尸围城》DX错误进不去游戏怎么办,一起来看看吧。问:WIN7点了报错DirectX Error,一个大红叉我系统是WIN7的,乱七八糟的插件...

日常生活中事情太多,记录很重要,win10电脑桌面如何添加备忘录

电脑桌面备忘录Win10如何给桌面添加备忘录?在我们的日常生活中,我们经常记录重要的事情来提醒我们不要忘记。在Win10系统中,我们还可以在桌面上添加备忘录,时刻提醒我们。那么我们该怎么办呢?下面,小编给大家分享一下Win10桌面添加备忘录的具体操作方法。1.点击开始菜单,点击设置图标,进入设置界面...

office安装程序找不到office.zh-cn\msvcr80.dll解决方法

近期在安装office2007程序的时候,出现了一个错误,提示了“安装程序找不到office.zh-cn/msvcr80.dll,请浏览确定有效的安装源,然后单击确定”,这可能是因为“Visual Studio Authoring Component组件”的问题导致的,那么要如何解决呢?下面峰哥分享...