0

我有一个使用 Delphi Pro 6 和 DSPACK 直接显示库创建的 DirectShow 过滤器。我在 Windows XP 下运行。我尝试在 DirectFilter 的容器类调用其构造函数时动态创建表单,将 NIL 作为 AOwner 参数(TMyForm.Create(nil) 传递给构造函数,然后调用 Form 的 Show() 方法。表单确实显示但随后似乎停止接收 Windows 消息,因为它从不重新绘制并且不响应输入。作为测试,我然后尝试创建自己的 WndProc() 并覆盖表单的 WndProc()。我的 WndProc() 确实被调用过一次但再也不会.

我猜这是因为我是一个 DLL,而我正在运行的上下文对窗体的窗口消息处理程序并不“友好”;也许与调用它的线程有关。如果有人能给我一个关于如何解决这个问题的提示,或者从 DirectShow 过滤器的上下文中创建持久窗口的正确方法是什么,我将不胜感激。请注意,正如我所说,窗口需要保持不变,因此我无法将其创建为过滤器属性页。

谢谢,罗伯特

4

1 回答 1

1

我无法帮助您了解 DirectShow 过滤器的细节,但我觉得一些关于窗口和消息处理的一般信息可能会有所帮助。

Windows 具有线程关联性,这意味着窗口的所有消息都将在创建它的线程的上下文中处理。这意味着这个线程需要有标准的消息处理循环,相当于Application.ProcessMessages(). 来自同一线程和来自其他线程的消息都将在创建线程的消息队列中排队,消息循环将获取它们,(可选)翻译它们,并将它们分派给目标窗口的窗口处理程序。

您所描述的可能是由以下任一原因引起的

  • 在创建窗口的线程中没有消息处理队列,或者

  • 在错误的线程中创建窗口

(请注意,这些本质上是相同的,但这样表述很明显,可能存在不同的问题导致这种情况,需要以不同的方式修复 - 需要在不同的线程中创建窗口,或者在处理需要在线程中创建循环。)

您需要找出两者中的哪一个导致您的窗口不处理消息。您不一定需要覆盖WndProc(),不同消息的消息处理方法将工作(或不工作)相同。你WndProc()被调用一次并不能真正告诉你太多,因为在某些情况下,从同一线程发送的消息将在没有消息循环的情况下通过直接调用窗口 proc 来处理。

由于您的过滤器位于 DLL 中,因此我认为创建自己的消息循环不是正确的事情。这适用于模态对话框,它将被创建,消息循环将运行直到对话框关闭,然后消息循环将终止并且 DLL 函数将返回。它不适用于将调用的 DLL 导出函数,并且在消息循环仍在运行时需要全部返回。我假设创建和调用这些过滤器的框架也将处理消息循环。然而,这是一种直觉,不知道 DirectShow 过滤器这很可能是错误的。

可以帮助您调试的是 Visual Studio 中的 Spy++ 之类的工具,您可以使用它显示有关窗口的信息,记录发送给它们或同一进程或线程中的所有窗口的消息,显示窗口层次结构并执行许多其他操作有趣的东西。如果你没有那个,网上有很多克隆(一些免费软件),谷歌应该出现。尝试显示发送到同一线程或进程的所有窗口的消息应该告诉您消息循环是否正在运行。您还应该能够通过运行 SysInternals Process Explorer 或类似工具来获取更多信息。

于 2010-04-03T06:40:13.683 回答