我有一个在浏览器中运行提升信任的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输入和其他将控件转换为图像的方法,没有任何运气。
感谢用户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);
答案 0 :(得分: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);