我有一个使用Delphi Pro 6和DSPACK直接显示库创建的DirectShow过滤器。我在Windows XP下运行。当DirectFilter的容器类调用其构造函数时,我尝试动态创建表单,将NIL作为AOwner参数(TMyForm.Create(nil))传递给构造函数,然后调用Form的Show()方法。表单确实显示但后来似乎停止接收Windows消息,因为它从不重新绘制并且不响应输入。作为测试我然后尝试创建我自己的WndProc()并覆盖Form的WndProc()。我的WndProc()确实被调用一次但是再也没有
我猜这是因为我是一个DLL,我运行的上下文对窗体的窗口消息处理程序并不“友好”;也许与调用它的线程或其他什么有关。如果有人可以给我一个如何解决这个问题的提示或者创建持久窗口的正确方法来自DirectShow过滤器的上下文我会很感激。请注意,正如我所说,窗口需要持久化,因此我无法将其创建为Filter属性页。
谢谢, 罗伯特
答案 0 :(得分:1)
我无法帮助您使用DirectShow过滤器细节,但我觉得有关Windows和消息处理的一些常规信息可能有所帮助。
Windows具有线程亲和性,这意味着窗口的所有消息都将在创建它的线程的上下文中处理。这意味着该线程需要具有标准的消息处理循环,相当于Application.ProcessMessages()
的低级别。来自相同和来自其他线程的消息将在创建线程的消息队列中排队,消息循环将获取它们(可选)转换它们,并将它们分派到目标窗口的窗口处理程序。
您所描述的内容可能由
引起在创建窗口的线程中没有消息处理队列,或
在错误的帖子中创建窗口
(注意这些基本上是相同的,但是这样说明显然可能存在导致这种情况的不同问题,需要以不同方式修复 - 要么需要在不同的线程中创建窗口,或者需要在线程中创建处理循环。)
您需要找出导致窗口不处理消息的两个原因。您不一定需要覆盖WndProc()
,不同消息的消息处理方法将起作用(或不起作用)。你的WndProc()
被调用了一次并没有真正告诉你多少,因为在某些情况下,通过直接调用window proc,可以在没有消息循环的情况下处理从同一个线程发送的消息。
由于您的过滤器驻留在DLL中,我不认为创建自己的消息循环是正确的。这适用于将创建的模式对话框,消息循环将一直运行直到对话框关闭,然后消息循环将终止并且DLL函数将返回。它将不适用于将被调用的DLL导出函数,并且需要在消息循环仍在运行时返回所有函数。我假设创建和调用这些过滤器的框架也将处理消息循环。然而,这是一种直觉,不知道DirectShow过滤器这可能是错误的。
可以帮助您调试这个是一个像Visual Studio的Spy ++这样的工具,您可以使用它来显示有关窗口的信息,发送给它们的日志消息或同一进程或线程中的所有窗口,显示窗口层次结构并执行很多其他有趣的事情。如果你没有这个,网上有很多克隆(一些免费软件),谷歌应该出现。尝试显示发送到同一线程或进程的所有窗口的消息应该告诉您消息循环是否正在运行。您还应该能够通过运行SysInternals Process Explorer或类似工具来获取更多信息。