简体   繁体   English

如何使用图像列表在自己的窗口之外绘制C#拖动

[英]How can I use an Image List to draw C# dragging outside of my own windows

I am using C#'s inbuilt drag and drop via Control.DoDragDrop(). 我正在通过Control.DoDragDrop()使用C#的内置拖放功能。 I use an Image List and ImageList_DragMove and friends to move a semi-transparent image around, tracking with the mouse. 我使用图像列表和ImageList_DragMove和朋友来移动一个半透明的图像,并用鼠标进行跟踪。 (See my reply in this thread for more information). (有关更多信息,请参见我在此线程中的答复)。 How can I make the ImageList track the mouse when it is outside my windows? 当窗口不在窗口中时,如何使ImageList跟踪鼠标? I only receive mouse position messages in OnDragOver(), and only when the mouse is over one of my Windows. 我仅在OnDragOver()中收到鼠标位置消息,并且仅当鼠标悬停在我的Windows之一上时才收到。 The drag is going to another instance of my application, and I would like the ImageList to go the whole way, including over the desktop. 拖到我应用程序的另一个实例,我希望ImageList贯穿整个过程,包括在桌面上。 I guess the basic problem is that DoDragDrop runs its own little message loop. 我想基本的问题是DoDragDrop运行自己的小消息循环。

Windows Explorer gets this done so I know it is possible. Windows资源管理器已完成此操作,因此我知道这是可能的。 I suppose I could start a thread to keep track of the mouse or write my own drag/drop message loop, but I am hoping for an easier way. 我想我可以启动一个线程来跟踪鼠标或编写自己的拖放消息循环,但是我希望有一种更简单的方法。

You cannot draw outside your own windows. 您不能在自己的窗户外面画画。 The way to do this is by changing the mouse cursor. 完成此操作的方法是更改​​鼠标光标。 That's what the GiveFeedback event is available, set e.UseDefaultCursors to false and set the Cursor.Current. 这就是GiveFeedback事件可用的功能,将e.UseDefaultCursors设置为false并设置Cursor.Current。

Just to give you an idea what this looks like, here's a sample form that drags visible text. 只是为了让您了解一下它的外观,下面是一个示例表格,它拖动可见的文本。 Alter it to draw the bitmap the way you want it, from your ImageList for example. 对其进行更改以按照所需方式绘制位图,例如从ImageList。 Beware that Bitmap.GetHicon() does not create great icons, the color mapping is poor. 注意,Bitmap.GetHicon()不会创建出色的图标,因此颜色映射很差。

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        this.GiveFeedback += Form1_GiveFeedback;
    }

    void Form1_GiveFeedback(object sender, GiveFeedbackEventArgs e) {
        string txt = "Dragging text";
        SizeF sz;
        using (var gr = this.CreateGraphics()) {
            sz = gr.MeasureString(txt, this.Font);
        }
        using (var bmp = new Bitmap((int)sz.Width, (int)sz.Height)) {
            using (var gr = Graphics.FromImage(bmp)) {
                gr.Clear(Color.White);
                gr.DrawString(txt, this.Font, Brushes.Black, 0, 0);
            }
            bmp.MakeTransparent(Color.White);
            e.UseDefaultCursors = false;
            IntPtr hIcon = bmp.GetHicon();
            Cursor.Current = new Cursor(hIcon);
            DestroyIcon(hIcon);
        }
    }
    protected override void OnMouseDown(MouseEventArgs e) {
        this.DoDragDrop("example", DragDropEffects.Copy);
    }
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    extern static bool DestroyIcon(IntPtr handle);

}

I suggest that you create a special form and drag it instead of using an ImageList. 我建议您创建一个特殊的表单并拖动它,而不要使用ImageList。 We have done this in our products (for example, XtraGrid) to allow the end-user arrange columns. 我们已经在我们的产品(例如XtraGrid)中做到了这一点,以允许最终用户排列列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM