Delphi - цикл сообщений для формы, созданной в фильтре DirectShow, перестает работать

У меня есть фильтр DirectShow, созданный с помощью Delphi Pro 6 и библиотеки прямого показа DSPACK. Я работаю под Windows XP. Я пробовал создавать форму динамически, когда у класса контейнера для DirectFilter вызывается конструктор, передавая NIL в конструктор в качестве параметра AOwner (TMyForm.Create (nil), а затем вызывая метод Form Show (). Форма показывает но затем, похоже, перестает получать сообщения Windows, потому что он никогда не перерисовывается и не отвечает на ввод. В качестве теста я затем попытался создать свой собственный WndProc () и переопределить WndProc () формы. Мой WndProc () был вызван один раз, но никогда больше .

Я предполагаю, что это потому, что я - DLL, и контекст, в котором я работаю, не "дружественен" обработчику оконных сообщений для формы; возможно, что-то связано с вызывающим его потоком или чем-то еще. Если бы кто-нибудь мог дать мне совет о том, как решить эту проблему или как правильно создать постоянное окно из контекста фильтра DirectShow, я был бы признателен. Обратите внимание, как я уже сказал, окно должно быть постоянным, поэтому я не могу создать его как страницу свойств фильтра.

Спасибо Роберт


person Robert Oschler    schedule 02.04.2010    source источник


Ответы (1)


Я не могу помочь вам со спецификой фильтра DirectShow, но я чувствую, что некоторая общая информация об окнах и обработке сообщений может помочь.

Windows имеет сходство потоков, что означает, что все сообщения для окна будут обрабатываться в контексте потока, который его создал. Это означает, что этот поток должен иметь стандартный цикл обработки сообщений, низкоуровневый эквивалент Application.ProcessMessages(). Оба сообщения от одного и того же и от других потоков будут помещены в очередь сообщений создаваемого потока, и цикл сообщений получит их, (необязательно) переведет их и отправит их обработчику окна целевого окна.

То, что вы описываете, может быть вызвано либо

  • отсутствие очереди обработки сообщений в потоке, который создает окно, или

  • создание окна в неправильном потоке

(Обратите внимание, что это по сути одно и то же, но, как указано ниже, становится очевидным, что могут быть разные проблемы, вызывающие это, которые необходимо исправлять по-разному - либо окно необходимо создать в другом потоке, либо обработка в потоке необходимо создать цикл.)

Вам нужно выяснить, по какой из двух причин ваше окно не обрабатывает сообщения. Вам не обязательно переопределять WndProc(), методы обработки сообщений для отдельных сообщений будут работать (или не работать) одинаково. То, что ваш WndProc() был вызван один раз, на самом деле мало что вам говорит, потому что при некоторых обстоятельствах сообщения, отправленные из того же потока, будут обрабатываться без цикла сообщений, путем прямого вызова процедуры окна.

Поскольку ваш фильтр находится в DLL, я не думаю, что создание собственного цикла сообщений было бы правильным. Это работает для модального диалога, который будет создан, цикл сообщений будет выполняться, пока диалог не будет закрыт, а затем цикл сообщений завершится, и функция DLL вернется. Он не будет работать для экспортируемой функции DLL, которая будет вызываться и должна возвращать все, пока цикл сообщений все еще работает. Я предполагаю, что структура, которая создает и вызывает эти фильтры, также обрабатывает цикл сообщений. Тем не менее, это интуитивное ощущение, не зная о фильтрах DirectShow, это может быть ошибкой.

Что может помочь вам отладить это, так это такой инструмент, как Spy ++ из Visual Studio, с помощью которого вы можете отображать информацию об окнах, регистрировать сообщения, отправленные им или всем окнам в том же процессе или потоке, отображать иерархии окон и многое другое. интересные вещи. Если у вас его нет, в сети есть много клонов (некоторые бесплатные), которые Google должен найти. Попытка показать сообщения, отправленные во все окна одного и того же потока или процесса, должна сказать вам, запущен ли цикл сообщений. Вы также сможете получить дополнительную информацию, запустив SysInternals Process Explorer или аналогичные инструменты.

person mghie    schedule 03.04.2010