| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: ActiveX/СОМ/CORBA > Как правильно закрыть форму в ActiveX-объекте |
| Автор: Voxifer 5.2.2010, 22:20 | ||
| Может быть, не сразу смогу внятно объяснить т.к. тема для меня новая и я в боевом режиме изучаю использование интерфейсов. Проблема в следующем: накатал dll, которая поставляет нужный мне интерфейс. В нем осуществляется вызов обычной VCL-формы. В стороннем приложении вызов моего интерфейса производится по CreateObject("bla-bla"). Затем вызов метода интерфейса приводит к созданию формы (немодальной), осуществляющей некоторые действия, и которая может висеть сама по себе. Но проблема в том, что вызывающее приложение может завершиться, пока моя форма присутствует. В этом случае вываливается AV, впрочем, понятно почему. Непонятно, как с этим бороться? т.к. я еще не слишком глубоко постиг механизм всей этой кухни... P.S. Мой интерфейс - наследник от IDispatch, инкапсулируется классом так:
Что, где проверить\отловить надо, чтобы уничтожить форму в момент завершения вызывающего приложения? |
| Автор: Voxifer 8.2.2010, 13:38 | ||
| В общем, проблему решил. Не так как хотелось бы, но зато понял, что иначе нельзя. Но тут объявилась другая проблема. Вкратце, происходит следующее: внешнее приложение вызывает мой интерфейс, что приводит к созданию формы. Форма порождает дополнительный поток, который уже запускает другой интерфейс вызвавшего форму внешнего приложения и работает с ним, периодически посылая информацию форме на отображение. При освобождении моего интерфейса форма закрывается, в её деструкторе вызывается Terminate для потока и вот тут происходят его зависания (попытки выяснить с помощью MessageBox'ов, где конкретно - привели меня к CoUninitialize). Принудительный TerminateThread помогает частично, форма закрывается, но вызывающее приложение все равно зависает до тех пор, пока я не попытаюсь вызвать его системное меню на панели задач (тогда, видимо, происходит выход из какого-то дедлока). Причем вставка MessageBox'а сразу после команды Terminate почему-то сразу снимает всю проблему - абсолютно все отрабатывает корректно, сколько я ни дергал это окно. Есть подозрение, что я что-то напутал с потоковой моделью COM, но что именно - не знаю. Между потоками интерфейсы не передаю, поэтому маршаллинг тут не использую. (Де)Инициализировать COM пытался где можно и не можно. Надоело тыкаться, как слепому котенку, уже мозг и гугл сломал, может кто подскажет где я налажал? Вот краткие выдержки из моего кода:
|