2015-04-11 2 views
1

У меня есть TMyClass, класс, полученный из TObject. Он имеет TTimer. Каждые несколько минут из Timer.OnTimer я просматриваю веб-страницу. Когда веб-страница изменится, я закончил, и я хочу освободить MyClass. Как мне его освободить?Как освободить объект внутри своего обработчика событий?

Мой вопрос похож на this один НО мой «контроль» не является TControl. Это потомок TObject. Таким образом, сообщения не будут работать. Очевидно, что решение будет состоять в том, чтобы получить мой класс от TControl или выше. Но скажем, я не хочу этого делать. Каким будет решение в этом случае?

+1

Подождите, так что вы не держите ссылки на эти объекты (вы просачиваете их, когда приложение завершается)? Если вы это сделаете, и объект освободит себя * изнутри *, то после этого ссылка станет обвисшим указателем (после чего вы попытаетесь вызвать 'Free'). Вы должны рассмотреть какой-то диспетчер объектов и попросить менеджера освободить объект (и удалить его из своей справочной коллекции). – TLama

ответ

5

Для получения сообщений необходимо иметь ручку окна. Вы можете выделить его с помощью AllocateHWnd, что-то вроде

type 
    TMyClass = class(TObject) 
    private 
    FHandle: HWND; 
    procedure MyWndProc(var Msg: TMessage); 
    public 
    constructor Create; virtual; 
    destructor Destroy; override; 
    end; 

constructor TMyClass.Create(); 
begin 
    inherited Create(); 
    FHandle := AllocateHWnd(myWndProc); 
end; 

destructor TMyClass.Destroy; 
begin 
    DeallocateHWnd(FHandle); 
    inherited; 
end; 

procedure TMyClass.MyWndProc(var Msg: TMessage); 
begin 
    case Msg.Msg of 
    CM_RELEASE: begin 
     Free; 
    end; 
    else Msg.Result := DefWindowProc(FHandle, Msg.Msg, Msg.WParam, Msg.LParam); 
    end; 
end; 

Теперь вы можете отправлять сообщения на объект, используя FHandle как показано в посте Youre ВЕ.

+0

Будьте осторожны, хотя 'TMyClass.Create' можно вызывать только из основного потока, потому что' AllocateHWnd' имеет это ограничение. Использование специальной версии 'AllocateHWnd' решило бы это. Конечно, скорее всего, вы хотите, чтобы методы «TMyClass» вызывались в основном потоке, поэтому это почти наверняка не проблема, которая вас беспокоит. –

+0

... и вы создадите висячий указатель. Этот ответ верен, идея саморазрушающих (не сопряженных) объектов плоха. – TLama

6

Основная идея использования сообщения верна: убедитесь, что объект освобожден в более поздней точке, после того, как какой-либо код в настоящее время вызывает его.

Несколько лет назад я написал блок Delayed Action, который дает вам простой способ выполнить этот же эффект без TControl. Вы просто вызываете DelayExec и передаете ему анонимный метод, который освободит объект, и он устанавливает внутреннее сообщение, которое делает это, как только очередь сообщений накачивается.

+1

Как просто получается. Гибкий и универсальный. –

+0

Спасибо Мейсон. Это то, что мне нужно. – Ampere

Смежные вопросы