Тотальная неудачница и убийца жёстких дисков.
#post-id: 2805-00-38
#original-date: 31.03.2008 Mon
#original-time: 12:38 AM
#original-day:  2805
#original-host: WinXP Prof SP2 (Build 2600)

Победила!!! Короче, у меня есть структура, которая содержит ссылку на сам контрол. Тоесть объявлено вот так:

Type SYSTRAY_SUBCLASS_INFO
 PrevWndProc As Long
 SysTray As SysTray
End Type



Вторая переменная - это и есть ссылка. Когда мы присваеваем ей объект, Visual Basic автоматом получает интерфейс IUnknown и вызывает AddRef() - он автоматом ведёт учёт ссылок чтобы объект случайно не освободился. Это правильно, так и должно быть.

Когда я делаю субклассинг окна контрола, я связываю с этим окном указатель на экземпляр этой структуры. В оконной процедуре, которая живёт в модуле, этот получается этот указатель (ведь манипулятор окна известен), а потом на локальную переменную копируются данные структуры. VB не позволяет по манипулятору получить объект окна, так что приходится так вот поступать. Код форвардит сообщение контролу, используя функцию (объявленную как Friend, тоесть видимую только в проекте, но не за его пределами) SendEvent, а потом возвращает ответ системе.

Поскольку экземпляр структуры объявлен на уровне модуля класса контрола, имеется ссылка на сам класс, которая не позволяет вызвать деструктор. А прячется иконки именно в деструкторе, там же освобождается и ссылка на контрол. И что делать?

Нужно чтобы эта ссылка работала, но не считалась. Как это сделать? Можно копировать указатель через CopyMemory() или что ещё - тогда ссылка не будет считаться, хотя переменная будет того же типа (Object и подобные - это указатель, 4 байта). Но я сделала хитрее. Вот код начала субклассинга и присвоения переменной ссылки на контрол:

Set Info.SysTray = Me
asObjectRelease Info.SysTray



А вот освобождение:

asObjectAddRef Info.SysTray
Set Info.SysTray = Nothing



asObjectAddRef() вызывает AddRef() и увеличивает количество ссылок на единицу, а asObjectRelease() вызывает Release(), и уменьшает количество ссылок. Тоесть несмотря на то что ссылка у нас есть, количество ссылок на контрол остаётся таким же. Деструктор прекрасно вызывается, а при обнелении ссылки я просто увеличиваю количество ссылок, чтобы опять ни чего не поменялось.

Не делайте так ^^

Но главное что работает, и мне ни чего переделывать не пришлось ^^ Просто дописала две строчки ^^