0

ブラウザー内で高信頼度を実行しているSilverlight5アプリケーションがあります。これにより、P / Invokeを介してクリップボードにアクセスしやすくなるなど、Silverlightでは通常は不可能なことを実行できます。

私ができる必要があるのは、コントロールをクリップボードにコピーして、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

user629926からの提案のおかげで、私は少し近いと思うものを手に入れましたが、まだ何かが欠けています。

  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);
4

1 に答える 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);
于 2012-06-28T00:17:00.280 に答える