首页 文章

如何使用P / Invoke从提升的信任silverlight应用程序将writeablebitmap复制到剪贴板?

提问于
浏览
0

我有一个在浏览器中运行提升信任的silverlight 5应用程序 . 这允许我们做一些通常在Silverlight中无法实现的事情,比如通过P / Invoke更多地访问剪贴板 .

我需要做的是将控件复制到剪贴板,以便将它们粘贴到Word或Outlook中 . 我可以通过WriteableBitmap将控件转换为图像,但是将数据复制到剪贴板是我遇到的问题 .

来电代码:

WriteableBitmap bmp = new WriteableBitmap(elements[0], new ScaleTransform() { ScaleX = 1.0, ScaleY = 1.0 });
  int[] p = bmp.Pixels;
  int len = p.Length * 4;
  byte[] result = new byte[len];
  Buffer.BlockCopy(p, 0, result, 0, len);

  CopyToClipboardViaPInvoke(result, ClipboardFormat.CF_BITMAP);

复制功能:

private void CopyToClipboardViaPInvoke(byte[] data, ClipboardFormat format)
{
    IntPtr p = IntPtr.Zero;
    if (Native.OpenClipboard(p))
    {
        GCHandle pinnedArray = GCHandle.Alloc(data, GCHandleType.Pinned);
        IntPtr pointer = pinnedArray.AddrOfPinnedObject();
        try
        {
            Native.EmptyClipboard();
            IntPtr result = Native.SetClipboardData(format, pointer);
        }
        finally
        {
            Native.CloseClipboard();
            pinnedArray.Free();
        }
    }
}

结果说它很成功,但粘贴什么也没做 . IsClipboardFormatAvailable 还声明格式在剪贴板上可用 . 我还尝试了各种ClipboardFormat输入和其他将控件转换为图像的方法,没有任何运气 .

更新1

感谢来自用户629926的建议我已经得到了我认为更接近的东西,但我仍然遗漏了一些东西 .

Native.EmptyClipboard();
  IntPtr bmp = IntPtr.Zero;
  GCHandle pinnedArray = GCHandle.Alloc(bytes, GCHandleType.Pinned);
  IntPtr bmpPointer = pinnedArray.AddrOfPinnedObject();
  Native.StartupInput sin = new Native.StartupInput() { GdiplusVersion = 1 };
  Native.StartupOutput sout = new Native.StartupOutput();
  IntPtr gdip = IntPtr.Zero;

  int startup = Native.GdiplusStartup(out gdip, ref sin, out sout);
  int created = Native.GdipCreateBitmapFromScan0(width, height, width * 4, 0x0026200A, bmpPointer, out bmp);
  IntPtr result = Native.SetClipboardData(format, bmp);

  Native.DeleteObject(bmp);
  Native.GdiplusShutdown(ref gdip);

1 回答

  • 0

    使用GdipCreateBitmapFromScan0从您的数组中获取HBitmap并将其传递给剪贴板和DeleteObject以释放它 .

    [DllImport("gdiplus.dll")]
    static extern int GdipCreateBitmapFromScan0(int width, int height, int stride, int format, IntPtr scan0, out IntPtr bitmap); 
    [DllImport("gdi32.dll")]
    public static extern bool DeleteObject(IntPtr hObject);
    

相关问题