Multi-Platform Package Manager for Stable Diffusion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.0 KiB

using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Avalonia.Media.Imaging;
namespace StabilityMatrix.Avalonia.Helpers;
[SupportedOSPlatform("windows")]
public static class WindowsClipboard
{
public static void SetBitmap(Bitmap bitmap)
{
if (bitmap == null)
throw new ArgumentNullException(nameof(bitmap));
// Convert from Avalonia Bitmap to System Bitmap
var memoryStream = new MemoryStream();
bitmap.Save(memoryStream); // this returns a png from Skia (we could save/load it from the system bitmap to convert it to a bmp first, but this seems to work well already)
var systemBitmap = new System.Drawing.Bitmap(memoryStream);
var hBitmap = systemBitmap.GetHbitmap();
var screenDC = GetDC(IntPtr.Zero);
var sourceDC = CreateCompatibleDC(screenDC);
var sourceBitmapSelection = SelectObject(sourceDC, hBitmap);
var destDC = CreateCompatibleDC(screenDC);
var compatibleBitmap = CreateCompatibleBitmap(
screenDC,
systemBitmap.Width,
systemBitmap.Height
);
var destinationBitmapSelection = SelectObject(destDC, compatibleBitmap);
BitBlt(destDC, 0, 0, systemBitmap.Width, systemBitmap.Height, sourceDC, 0, 0, 0x00CC0020); // SRCCOPY
try
{
OpenClipboard(IntPtr.Zero);
EmptyClipboard();
var result = SetClipboardData(
(uint) Win32ClipboardFormat.CF_BITMAP,
compatibleBitmap
);
if (result == IntPtr.Zero)
{
var errno = Marshal.GetLastWin32Error();
throw new Win32Exception(errno, $"SetClipboardData failed");
}
}
finally
{
CloseClipboard();
}
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool CloseClipboard();
[DllImport("user32.dll")]
static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool EmptyClipboard();
[DllImport("user32.dll", ExactSpelling = true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int cx, int cy);
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true)]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr h);
[DllImport("gdi32.dll", SetLastError = true, ExactSpelling = true)]
public static extern bool BitBlt(
IntPtr hdc,
int x,
int y,
int cx,
int cy,
IntPtr hdcSrc,
int x1,
int y1,
uint rop
);
}