1

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

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

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

——罗舍尔

4

2 回答 2

2

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

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

于 2010-07-26T04:26:08.663 回答
0

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

罗伯特。

于 2010-07-27T04:52:54.953 回答