Delphi 6:在非 VCL 线程上触发的断点停止主线程重绘

发布于 2024-09-11 17:08:58 字数 614 浏览 9 评论 0原文

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

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

有没有人在类似的情况下经历过这种情况,如果是的话,您采取了什么措施来解决它?

——罗谢尔

I have a multi-threaded Delphi 6 Pro application that I am currently working on heavily. If I set a breakpoint on any code that runs in the context of the Main thread (VCL thread) I don't have any problems. However, if a breakpoint is triggered on any code in one of my other threads, after I continue the application from the breakpoint, all repaints to the VCL components on the main thread (including the main form) don't happen anymore. The application isn't dead because other background code keeps running, just the main thread. It's as if the windows message dispatcher has been corrupted or rendered dormant.

Note, in this application I allocate my own WndProc() via allocateHwnd() on the main form because I need to catch certain registered messages. From that WndProc() I dispatch any custom messages I handle and if the current message is not handled by my code, I pass the message on by calling the main form's inherited WndProc(). If I do handle the current message I simply return from my WndProc() with Msg.Result set to 1 to tell the dispatcher that the message was handled. I can't simply override the TForm WndProc() instead of allocating my own WndProc() because for some reason the Delphi VCL does not pass through registered messages instantiated with the Windows API RegisterWindowMessage() call.

Has anybody experienced this in similar context and if so, what did you do to fix it?

-- roscherl

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

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

发布评论

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

评论(2

海之角 2024-09-18 17:08:58

由于您调用了AllocateHWnd,这意味着您已经创建了另一个窗口。您不能只获取发送到该窗口的消息并将它们转发到您的表单窗口。这样做,你肯定会把程序搞砸,尽管我不确定到底是怎么做的。绘画问题听起来似乎合理。您应该确保这实际上只是绘画问题,而不是您的主线程仍然挂起。调试器应该能够告诉你这一点。 (您应该调用 DefWindowProc 来让您分配的窗口处理您不准备自行处理的消息。返回 1 不会告诉调度程序任何信息;调度程序并不关心 — 无论是谁调用 SendMessage 想知道结果。)

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

Since you call AllocateHWnd, that means you've created another window. You mustn't just take the messages that were addressed to that window and forward them to your form's window. Doing that, you're bound to screw things up in your program, although I'm not sure exactly how. Painting problems sound plausible. You should make sure it's really just painting problems and not that your main thread is still suspended. The debugger should be able to tell you that. (You should call DefWindowProc to make your allocated window handle messages you're not prepared to handle yourself. And returning 1 doesn't tell the dispatcher anything; the dispatcher doesn't care — whoever called SendMessage wants to know the result.)

I promise you that forms are completely capable of receiving registered window messages. Override WndProc or assign a new value to the WindowProc property (and remember to save the old value so you can call it after handling your own messages). The source of your problem lies elsewhere.

北笙凉宸 2024-09-18 17:08:58

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

罗伯特.

UPDATE: I'm not saying the way I got past the problem is a good solution. I need to take Rob Kennedy's notes and do some refactoring. However, to get past the problem for now I gave the thread it's own Window and WndProc() and at the top of the thread Execute loop I have a PeekMessage() while loop with calls to TranslateMessage() and DispatchMessage(). I no longer have a problem with setting breakpoints in the thread, but obviously this compounding of WndProc() methods indicates a structural problem in my code. I wanted to add this reply to fill out the discussion. I'm hoping that once I put Rob's suggestions to work when I clean up my WndProc() methods on the relevant forms, especially the main form, I can get rid of the this new WndProc() that I just added to the thread.

Robert.

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