来自另一个线程的 DoDragDrop()

发布于 2024-09-15 21:52:42 字数 647 浏览 8 评论 0原文

每次我想让用户拖动一个控件时,我都会调用该控件的 DoDragDrop 。

拖动& drop 工作正常,但我对周围的事情有问题:

  1. DoDragDrop 完全阻塞表单,没有计时器事件跳转,没有处理绘制消息。

  2. DoDragDrop 阻止不仅适用于拖动,还可以阻止拖动。 drop操作,但直到目标程序完成drop事件(IE explorer.exe的suck代码)。依赖于其他程序的代码很糟糕。

我想从新线程调用 DoDragDrop 。

尝试过这个:

Thread dragThread = new Thread(() =>
{
    Form frm = new Form();
    frm.DoDragDrop("data", DragDropEffects.All);
});

dragThread.SetApartmentState(ApartmentState.STA);
dragThread.IsBackground = true;
dragThread.Start();

但它似乎不起作用。我的意思是:当像这样从其他线程执行 DoDragDrop 时,我的程序或其他程序中的其他控件不会接收拖放消息。

还有其他解决方案吗?

Every time i want let the user to drag an control, i calling DoDragDrop of that control.

The drag & drop works fine, but i have problem with things around:

  1. DoDragDrop completely blocking the form, no timer events jumps, no paint messages handled.

  2. DoDragDrop blocking not only for the drag & drop operation, but until target program finishing with the drop event (I.E. explorer.exe's suck code). Depending on other program's code is sucks.

I thought to call DoDragDrop from a new thread.

tried this:

Thread dragThread = new Thread(() =>
{
    Form frm = new Form();
    frm.DoDragDrop("data", DragDropEffects.All);
});

dragThread.SetApartmentState(ApartmentState.STA);
dragThread.IsBackground = true;
dragThread.Start();

but it doesn't seems to work. I mean: when doing DoDragDrop from other thread like this, other controls within my program or other programs does not receiving drag&drop messages.

Any other solutions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寒冷纷飞旳雪 2024-09-22 21:52:42

DoDragDrop 方法停止处理事件,直到出现第一个鼠标事件(例如鼠标移动)。所以我发现的解决方法非常简单 - 您只需要在调用 DoDragDrop 之前使用相同的鼠标位置模拟鼠标事件:


void XYZControl_MouseDown(object sender, MouseEventArgs e)
{
    var senderControl = (Control) sender;
    ...
    Cursor.Position = senderControl.PointToScreen(new Point(e.X, e.Y));   // Workaround!
    if (DoDragDrop(senderControl, DragDropEffects.Move) == DragDropEffects.Move)
    {
    ...
    }
....
}

The DoDragDrop method stops processing of events until first mouse event (for example mouse move). So the workaround I found is very simple - you just need to simulate mouse event with the same mouse position just before calling DoDragDrop:


void XYZControl_MouseDown(object sender, MouseEventArgs e)
{
    var senderControl = (Control) sender;
    ...
    Cursor.Position = senderControl.PointToScreen(new Point(e.X, e.Y));   // Workaround!
    if (DoDragDrop(senderControl, DragDropEffects.Move) == DragDropEffects.Move)
    {
    ...
    }
....
}
寂寞清仓 2024-09-22 21:52:42

您需要忘记使用线程,它只会将 D+D 通知传递到在该线程上创建的窗口。这不会是你的控制。

对于“代码很糟糕”的诊断,我无能为力。 DoDragDrop() 调用本身确实会阻塞,直到释放鼠标按钮。 COM 代码内部的另一个消息循环将接管并传递 Windows 消息。计时器和绘画消息应正常传递。除非您发布一些重现代码,否则很难进行诊断。

You need to forget about using a thread, that's only going to deliver D+D notifications to the windows that were created on that thread. Which will not be your controls.

I can't do much with a "code is sucks" diagnostic. The DoDragDrop() call itself will indeed block until the mouse button is released. Another message loop, internal to COM code will take over and deliver the Windows messages. Timer and paint messages should be delivered as normal. A diagnostic is very hard to come by until you post some repro code.

薆情海 2024-09-22 21:52:42

您可能希望 DoDragDrop 退出并异步完成工作。

这是答案。

You probably want the DoDragDrop to quit and do the job asynchronously.

Here is the answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文