【问题标题】:Delphi 6 : breakpoint triggered on non-VCL thread stops main thread repaintsDelphi 6:在非 VCL 线程上触发的断点停止主线程重绘
【发布时间】:2011-03-20 21:14:40
【问题描述】:

我有一个多线程的 Delphi 6 Pro 应用程序,我目前正在大量工作。如果我在主线程(VCL 线程)上下文中运行的任何代码上设置断点,我没有任何问题。但是,如果在我的其他线程之一中的任何代码上触发了断点,则在我从断点继续应用程序之后,对主线程(包括主窗体)上的 VCL 组件的所有重绘都不会再发生。应用程序没有死,因为其他后台代码一直在运行,只是主线程。就好像 Windows 消息调度程序已损坏或处于休眠状态。

注意,在这个应用程序中,我通过主窗体上的 allocateHwnd() 分配我自己的 WndProc(),因为我需要捕获某些已注册的消息。我从那个 WndProc() 发送我处理的任何自定义消息,如果我的代码没有处理当前消息,我通过调用主窗体的继承 WndProc() 来传递消息。如果我确实处理了当前消息,我只需从 WndProc() 返回并将 Msg.Result 设置为 1,以告诉调度程序该消息已被处理。我不能简单地覆盖 TForm WndProc() 而不是分配我自己的 WndProc(),因为由于某种原因,Delphi VCL 不会通过使用 Windows API RegisterWindowMessage() 调用实例化的注册消息。

有没有人在类似的情况下遇到过这种情况,如果有,你做了什么来解决它?

-- 罗舍尔

【问题讨论】:

  • 我从未遇到过在被覆盖的 WndProc 中处理 Windows 消息的问题。也许代码示例将有助于查看问题所在。
  • 我唯一的想法是通过覆盖和揭开它来检查窗口实际上是否没有刷新。可能是窗口不知道需要更新。
  • 这不是一个修复,但是当你强制更新/绘制/刷新时会发生什么?

标签: multithreading delphi vcl repaint wndproc


【解决方案1】:

更新:我并不是说我解决问题的方式是一个好的解决方案。我需要记下 Rob Kennedy 的笔记并进行一些重构。但是,为了暂时解决这个问题,我给了线程它自己的 Window 和 WndProc(),并且在线程执行循环的顶部,我有一个 PeekMessage() while 循环,其中调用了 TranslateMessage() 和 DispatchMessage()。我不再有在线程中设置断点的问题,但显然这种 WndProc() 方法的复合表明我的代码中存在结构问题。我想添加此回复以填写讨论。我希望一旦我在相关表单(尤其是主表单)上清理我的 WndProc() 方法时将 Rob 的建议付诸实施,我可以摆脱我刚刚添加到线程中的这个新的 WndProc()。

罗伯特。

【讨论】:

    【解决方案2】:

    由于您调用AllocateHWnd,这意味着您已经创建了另一个窗口。您不能只接收发送到该窗口的消息并将它们转发到您的表单窗口。这样做,你一定会在你的程序中搞砸了,虽然我不知道到底是怎么回事。绘画问题听起来很合理。你应该确保它真的只是绘画问题,而不是你的主线程仍然被挂起。调试器应该能够告诉你。 (你应该调用 DefWindowProc 来让你分配的窗口处理你自己不准备处理的消息。返回 1 不会告诉调度员任何事情;调度员不在乎——谁打电话给SendMessage 想知道结果。)

    我向你保证,表单完全能够接收已注册的窗口消息。覆盖WndProc 或为WindowProc 属性分配一个新值(并记住保存旧值,以便在处理自己的消息后调用它)。您的问题的根源在于其他地方。

    【讨论】:

    • 谢谢 Rob,你提出的这些观点都很好。关于已注册的消息,我运行了两次相同的测试,我恢复到对表单的 WndProc() 进行子分类。注册的消息从未出现,但它们总是通过我用 allocateHwnd() 设置的 WndProc() 出现。我不知道还能说什么或尝试什么。
    • 也许您存储了表单的 Handle 属性,同时表单重新创建了它的窗口。然后,您将被留下一个陈旧的窗口句柄,因此您将向虚空发送或发布您的注册消息。
    猜你喜欢
    • 1970-01-01
    • 2012-05-06
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2012-02-22
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多