Что бы изучить получше оконную систему Windows решил я написать более-менее сложный контрол на чистом WinApi. Для одного из проектов мне нужно было дерево, отображающее себя несколько иначе по сравнению со стандартным SysTreeView32, его и решил реализовать. Контрол я успешно написал,
оформил по взрослому, но осталась у меня одна не решенная проблема.
Приличный контрол должен уметь UI Automation. Его я тоже реализовал. Но возникло одно но. Сам контрол реализован в dll (для использования в проекте на любом языке). Когда какое-нибудь приложение типа Narrator желает поработать с моим контролом через UI Automation, то в контрол начинают посылаться сообщения WM_GETOBJECT (OBJID_CLIENT), в ответ на которое я возвращаю экземпляр объекта, реализующего IAccessible. И как бы все работает, Narrator видит отдельные ноды дерева, произносит человеческим голосом текст ноды, и т.д. Проблема возникает при завершении хост приложения. Хост приложение ничего не знает о том, что были запросы WM_GETOBJECT и есть живые объекты из dll, и может выгрузить dll, а лишь затем вызвать OleUninitialize. Соответственно при OleUninitialize, когда вызывается последний Release объекта, происходит AV.
Вопрос – как то можно это исправить в самой dll?
(Я нашел временный workaround – в ответ на WM_GETOBJECT (OBJID_QUERYCLASSNAMEIDX) я возвращаю 65536+25, это позволяет системе создавать собственный внутренний прокси, реализующий IAccessible, который общается с моим деревом на чистом WinApi, но мне нужна имена моя реализация.)