mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
[PTRun] Drag and drop files (#22409)
* [PTRun] Support drag&drop to other application for files in result list * [PTRun] use file/folder thumbnail as drag image * (fix spellcheck) * [PTRun] use _mouseDownResultViewModel.Image to generate the drag image * fix spelling + refactoring
This commit is contained in:
99
src/modules/launcher/PowerLauncher/Helper/DragDataObject.cs
Normal file
99
src/modules/launcher/PowerLauncher/Helper/DragDataObject.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
namespace PowerLauncher.Helper
|
||||
{
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using DrawingImaging = System.Drawing.Imaging;
|
||||
using MediaImaging = System.Windows.Media.Imaging;
|
||||
|
||||
// based on: https://stackoverflow.com/questions/61041282/showing-image-thumbnail-with-mouse-cursor-while-dragging/61148788#61148788
|
||||
public static class DragDataObject
|
||||
{
|
||||
private static readonly Guid DataObject = new Guid("b8c0bd9f-ed24-455c-83e6-d5390c4fe8c4");
|
||||
|
||||
public static IDataObject FromFile(string filePath)
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(SHCreateItemFromParsingName(filePath, null, typeof(IShellItem).GUID, out IShellItem item));
|
||||
Marshal.ThrowExceptionForHR(item.BindToHandler(null, DataObject, typeof(IDataObject).GUID, out object dataObject));
|
||||
return (IDataObject)dataObject;
|
||||
}
|
||||
|
||||
public static void SetDragImage(this IDataObject dataObject, IntPtr hBitmap, int width, int height)
|
||||
{
|
||||
if (dataObject == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(dataObject));
|
||||
}
|
||||
|
||||
IDragSourceHelper dragDropHelper = (IDragSourceHelper)new DragDropHelper();
|
||||
ShDragImage dragImage = new ShDragImage
|
||||
{
|
||||
HBmpDragImage = hBitmap,
|
||||
SizeDragImage = new Size(width, height),
|
||||
};
|
||||
Marshal.ThrowExceptionForHR(dragDropHelper.InitializeFromBitmap(ref dragImage, dataObject));
|
||||
}
|
||||
|
||||
[DllImport("shell32", CharSet = CharSet.Unicode)]
|
||||
private static extern int SHCreateItemFromParsingName(string path, IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv);
|
||||
|
||||
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
private interface IShellItem
|
||||
{
|
||||
[PreserveSig]
|
||||
int BindToHandler(IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
|
||||
|
||||
// more methods available, but we don't need them
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("4657278a-411b-11d2-839a-00c04fd918d0")] // CLSID_DragDropHelper
|
||||
private class DragDropHelper
|
||||
{
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/ns-shobjidl_core-shdragimage
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct ShDragImage
|
||||
{
|
||||
public Size SizeDragImage;
|
||||
public Point PtOffset;
|
||||
public IntPtr HBmpDragImage;
|
||||
public int CrColorKey;
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-idragsourcehelper
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("DE5BF786-477A-11D2-839D-00C04FD918D0")]
|
||||
private interface IDragSourceHelper
|
||||
{
|
||||
[PreserveSig]
|
||||
int InitializeFromBitmap(ref ShDragImage pShDrawImage, IDataObject pDataObject);
|
||||
|
||||
// more methods available, but we don't need them
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/2897325
|
||||
public static Bitmap BitmapSourceToBitmap(MediaImaging.BitmapSource source)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Bitmap bitmap = new Bitmap(source.PixelWidth, source.PixelHeight, DrawingImaging.PixelFormat.Format32bppArgb);
|
||||
DrawingImaging.BitmapData bitmapData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), DrawingImaging.ImageLockMode.WriteOnly, DrawingImaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
source.CopyPixels(System.Windows.Int32Rect.Empty, bitmapData.Scan0, bitmapData.Height * bitmapData.Stride, bitmapData.Stride);
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user