【问题标题】:WinForms: Open a messagebox from the WndProc method (Form class)WinForms:从 WndProc 方法(Form 类)打开一个消息框
【发布时间】:2011-04-14 09:29:12
【问题描述】:

我想象 WndProc 是在另一个线程而不是主 UI 线程上调用的。

我是对的,所以我认为只需在表单上使用 InvokeRequired 和 Invoke 就足以在 UI 线程上显示消息框。

我错了。我不明白为什么。

我该如何解决这个问题?我在谷歌上四处寻找,但没有找到解决方案。

我要做的只是在剪贴板更改时引发自定义事件 (ClipboardUpdate)

消息框只是一个测试但没有工作,而只是更改字符串(表单的私有字段)之类的东西是有效的,但这种行为不是一件好事,因为它是不安全的跨线程操作方式。

更新 1:

我没有这里的代码,因为我是在朋友的计算机上创建的,但是我可以准确地解释我写的内容,因为很短。 我用visual studio创建了一个基本的winform,没有任何东西。 我使用 AddClipboardFormatListener (互操作,但它作为一个函数很容易,返回 int 并接受 IntPtr)函数(在 Windows 7 操作系统上)只检测 WM_CLIPBOARDUPDATE 消息,在 winproc 内(一个简单的 if,*if (e.Msg == ClipboardExtension .WM_CLIPBOARDUPDATE) DoClipboardUpdate();*).

现在 DoClipboardUpdate 这样做:

if (InvokeRequired)
    Invoke(new VoidDelegate(OnClipboardUpdate));//Void delegate it's a delegate that doesn't take
    // Params and returns void
else
    OnClipboardUpdate();

很简单吧? OnClipboardUpdate 只需这样做:

if (ClipboardUpdate != null) ClipboardUpdate(null,EventArgs.Empty);

ClipboardUpdate 是这样声明的事件:

public event EventHandler<EventArgs> ClipboardUpdate;

最后,订阅 ClipboardUpdate 事件的唯一方法里面有这个:

MessageBox.Show("test");

当我运行代码时会发生什么?该事件被触发(我尝试了一个异常并且它有效)并且消息框没有弹出,但是我不能再与我的表单交互,因为它的行为就像打开了一个弹出窗口(这是“正常”行为时你在不同的线程上打开一个弹出窗口,这就是我这么说的原因。

关于如何解决这个问题的任何建议?

【问题讨论】:

  • 如果您使用 .NET 4,请考虑使用任务库而不是 theads.. 就您而言 - 您不能直接从后台线程显示 MessageBox.. 可能会将其加入 UI 线程首先在 UI 线程上显示 MessageBox...
  • 您是如何得出该表单的 WndProc 是在非 UI 线程上执行的结论的?据我所知(并根据我所做的测试)它在 UI 线程上执行。
  • WndProc 方法在 UI 线程上被调用和执行。从该代码显示消息框不是问题。不存在跨线程问题。发布您拥有的不起作用的代码。
  • @Fredrik 更新了主要问题以解释我的工作

标签: c# winforms multithreading wndproc


【解决方案1】:

我不明白为什么会这样,但我创建了一个新项目并从 WndProc 打开一个消息框工作正常,可能是某些线程损坏了主线程内存,我不知道这一点,但正如其他人所说,wndproc 是 ui 线程和应该工作

【讨论】:

    猜你喜欢
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多