views:

213

answers:

1

What is the correct place/time to start subclassing a control?

What is the proper time to restore the original window proc?

Right now i subclass during form creation:

procedure TForm1.FormCreate(Sender: TObject);
begin
   FOldPanel1WindowProc := Panel1.WindowProc;
   Panel1.WindowProc := Panel1WindowProc;
end;

and i restore the subclassing during form destruction:

procedure TForm1.FormDestroy(Sender: TObject);
begin
   Panel1.WindowProc := FOldPanel1WindowProc;
end;

This works fine, as long as i don't use ThemeManager, which subclasses controls itself. As soon as a try to subclass a control that ThemeManager also sub-classes, i get very nasty errors.

i assume it's becuase i should not start the subclass during Create and restore it during Destroy. So what is the properly documented time to subclass and unsubclass a control in Delphi?

+2  A: 

It's not clear from your question but I assume you get the errors when you're trying to restore the old window procedure in the form's OnDestroy event handler.

ThemeManager reverts its subclassing when processing WM_DESTROY for a control. Therefore you probably have to do the same: watch for WM_DESTROY in your new window procedure and revert your subclassing first, then call the old window procedure (and let ThemeManager do the same thing).

I haven't tested this but I think it should work.

TOndrej
You are right. More investigation shows that it *is* an ordering issue. Order of events now: 1. FormCreate (my sublcass) 2. ThemeManager subclass 3. FormDestroy (my unsubclass) 4. ThemeManager unsubclass. Since my subclass happens before ThemeManager's i need to unsubclass after; or i need to make ThemeManager subclass before my FormCreate.
Ian Boyd
Your solution worked. Having the sub-class handle the WM_DESTROY, and restore the original sub-class at that time fixes an error. i also found some undocumented methods in the TThemeManager (RegisterListener, UnregisterListener), which basically give you a WindowProc hook - just like a subclass.Marked as answer.
Ian Boyd