My code is:
<Grid AllowDrop="True" Background="Transparent"/> What I see:
What I wish to see:
How to do it?
...">
My code is:
<Grid AllowDrop="True" Background="Transparent"/> What I see:
What I wish to see:
How to do it?
The standard mechanism is the delegation of matching an icon and its rendering to the standard Shell COM object, DragDropHelper .
There is no need for a drag-and-drop drag-and-drop object.
That is what is used when drawing the drag image in Chrome / Chromium .
The standard mechanism involves using the work with the DragDropHelper from both the source and the target side:
WPF’s minimal IDropTargetHelper implementation:
using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Input; using System.Windows.Interop; using IDataObject_Com = System.Runtime.InteropServices.ComTypes.IDataObject; namespace WpfApp2 { [StructLayout(LayoutKind.Sequential)] public struct Win32Point { public int x; public int y; } [ComImport] [Guid("4657278A-411B-11d2-839A-00C04FD918D0")] public class DragDropHelper { } [ComVisible(true)] [ComImport] [Guid("4657278B-411B-11D2-839A-00C04FD918D0")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IDropTargetHelper { void DragEnter( [In] IntPtr hwndTarget, [In, MarshalAs(UnmanagedType.Interface)] IDataObject_Com dataObject, [In] ref Win32Point pt, [In] int effect); void DragLeave(); void DragOver( [In] ref Win32Point pt, [In] int effect); void Drop( [In, MarshalAs(UnmanagedType.Interface)] IDataObject_Com dataObject, [In] ref Win32Point pt, [In] int effect); void Show( [In] bool show); } /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private IDropTargetHelper ddHelper = (IDropTargetHelper)new DragDropHelper(); private void Window_DragEnter(object sender, DragEventArgs e) { e.Effects = DragDropEffects.Copy; e.Handled = true; Point p = this.PointToScreen(e.GetPosition(this)); Win32Point wp; wp.x = (int)pX; wp.y = (int)pY; ddHelper.DragEnter(new WindowInteropHelper(this).Handle, e.Data as IDataObject_Com, ref wp, (int)e.Effects); } private void Window_DragOver(object sender, DragEventArgs e) { e.Effects = DragDropEffects.Copy; e.Handled = true; Point p = this.PointToScreen(e.GetPosition(this)); Win32Point wp; wp.x = (int)pX; wp.y = (int)pY; ddHelper.DragOver(ref wp, (int)e.Effects); } private void Window_DragLeave(object sender, DragEventArgs e) { e.Handled = true; ddHelper.DragLeave(); } private void Window_Drop(object sender, DragEventArgs e) { e.Effects = DragDropEffects.Copy; e.Handled = true; Point p = this.PointToScreen(e.GetPosition(this)); Win32Point wp; wp.x = (int)pX; wp.y = (int)pY; ddHelper.Drop(e.Data as IDataObject_Com, ref wp, (int)e.Effects); } } } XAML:
<Window x:Class="WpfApp2.MainWindow" ... AllowDrop="True" DragEnter="Window_DragEnter" DragOver="Window_DragOver" DragLeave="Window_DragLeave" Drop="Window_Drop"> ... </Window> I used Shell Style Drag and Drop in .NET (WPF and WinForms) as a basis. Unfortunately, there is no code for WFP in it. Perhaps there are some subtleties specific to WFP (for example, mapping Effect -> Effects), so let me know if you need some refinement :)
this.PointToScreen(e.GetPosition(this)); 2. To e.Effects = DragDropEffects.Copy; actually applied, you need to set e.Handled = true; after that e.Handled = true; - MSDN.WhiteKnightWell, the answer @PashaPash is quite comprehensive. But, as I understand it, you are not interested in inserting icons, but getting the original one.
Having a little studied a question. That's what I got. The image itself can be obtained by regular means. Simply use e.Data.GetData ("DragImageBits"), where e is DragEventArgs.
In this case, you will get the image itself in a very primitive format. At the beginning there is a heading of 6 int in size, where the first two are width and height, the second is the point of capture by the X and Y cursor, and the last ones seem to be either MagicNumber or some kind of service info. Then comes the image itself in the BGRA format.
Code for image:
BitmapSource bitmapSource = null; int Xpos = 0; int Ypos = 0; var stream = e.Data.GetData("DragImageBits") as MemoryStream; if(stream == null) return; using (BinaryReader reader = new BinaryReader(stream, Encoding.ASCII, true)) { // Чтение заголовка reader.BaseStream.Position = 0; int width = reader.ReadInt32(); int height = reader.ReadInt32(); Xpos = reader.ReadInt32(); Ypos = reader.ReadInt32(); // Получение исходного изображения reader.BaseStream.Position = 24; byte[] data = reader.ReadBytes(width * height * 4); PixelFormat pixelFormat = PixelFormats.Pbgra32; int stride = 4 * ((width * pixelFormat.BitsPerPixel + 31) / 32); bitmapSource = BitmapSource.Create(width, height, 96, 96, pixelFormat, null, data, stride); // Трансформация, поскольку исходное изображение перевёрнуто и отражено TransformGroup transformGroup = new TransformGroup(); transformGroup.Children.Add(new RotateTransform(180)); transformGroup.Children.Add(new ScaleTransform(-1, 1)); bitmapSource = new TransformedBitmap(bitmapSource, transformGroup); } As a result, you have BitmapSource - the original image with the icon and title, Xpos and Ypos - the coordinates of the point where the cursor holds the image.
How to use all this apparently will figure it out.
Source: https://ru.stackoverflow.com/questions/707931/
All Articles