1
votes

I have TMyClass, a class derived from TObject. It has a TTimer. Every few minutes, from Timer.OnTimer I check a web page. When the web page changes, I am done and I want to free MyClass. How do I free it?

My question is similar to this one BUT my 'control' is not a TControl. It is descendent of TObject. So, Messages won't work. Obviously, the solution will be to derive my class from TControl or higher. But let's say I don't want to do that. What would be the solution in this case?

2
Wait, so you are not holding references to those objects (you are leaking them when the app. terminates) ? If you do, and the object releases itself from inside then the reference becomes a dangling pointer after that (on which you then try to call Free). You should consider some sort of object manager and ask that manager to release the object (and remove it from its reference collection). - TLama

2 Answers

6
votes

The basic idea behind using a message is correct: ensure that the object gets freed at a later point, after whatever code is currently calling it is finished.

A few years ago, I wrote a Delayed Action unit that gives you a simple way to accomplish this same effect without a TControl. You just call DelayExec and pass an anonymous method to it that will free the object, and it sets up a message internally that makes it happen once the message queue gets pumped.

5
votes

To receive messages you need to have window handle. You can allocate one using AllocateHWnd, something like

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;

Now you can post messages to the object using the FHandle as demonstrated in the post youre reffering to.