Continuing in my development of a composite component, I am
investigating Custom Events.
Unfortunately I am confused by what I have read.
Basically I want to add an event to a standard control - TPageControl.
I want to fire an event whenever the PageCount changes. From what I have
read it should be possible, but I am starting to think that the only way
to implement this correctly would be to have a timer, and check the
current PageCount value to a previously stored (old)PageCount value in
the timer event.
I don't want to have to implement a timer, and was wondering if it was
otherwise possible.
It is my understanding that adding a page to the TPageControl does not
generate the OnChange event which I could have otherwise used, or is my
understanding incorrect here?
Thanks in advance
Mal
> It is my understanding that adding a page to the TPageControl does not
> generate the OnChange event which I could have otherwise used, or is my
> understanding incorrect here?
Did you try it?
You could try overriding one of the methods of TPageControl like
UpdateActivePage or handle one of the messages (CM_CONTROLLISTCHANGE
and CM_CONTROLCHANGE).
--
Marc Rohloff [TeamB]
marc -at- marc rohloff -dot- com
> Basically I want to add an event to a standard control - TPageControl.
You cannot add events to existing components. You must derive new classes
from them instead. Alternatively, if your events are based on window
messages, you can subclass the WindowProc property of existing components
without deriving new classes.
> I want to fire an event whenever the PageCount changes.
Like Peter suggested, you can intercept the CM_CONTROLLISTCHANGE or
CM_CONTROLCHANGE message for that. Those messages are sent to the
PageControl when the Parent property of a TabSheet changes. For example:
TMyComp = class(TComponent)
private
FPageControl: TPageControl;
FDefPageControlWndProc;
FOnPageCountChange: TNotifyEvent;
procedure PageControlWndProc(var Message: TMessage);
protected
procedure PageCountChanged; virtual;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property OnPageCountChange: TNotifyEvent read FOnPageCountChange
write FOnPageCountChange;
end;
constructor TMyComp.Create(AOwner: TComponent);
begin
inherited;
FPageControl := TPageControl(Self);
//...
FDefPageControlWndProc := FPageControl.WindowProc;
FPageControl.WindowProc := PageControlWndProc;
end;
destructor TMyComp.Destroy;
begin
FPageControl.WindowProc := FDefPageControlWndProc;
FPageControl.Free;
inherited;
end;
procedure TMyComp.PageControlWndProc(var Message: TMessage);
begin
FDefPageControlWndProc(Message);
if (Message.Msg = CM_CONTROLCHANGE) and (TControl(Message.WParam) is
TTabSheet) then
PageCountChanged;
end;
procedure TMyComp.TMyComp.PageCountChanged;
begin
if Assigned(FOnPageCountChanged) then
FOnPageCountChanged(Self);
end;
Gambit
> constructor TMyComp.Create(AOwner: TComponent);
> begin
> inherited;
> FPageControl := TPageControl(Self);
You cast Self, a descendent of TComponent to a TPageControl? IMHO, a road to
disaster.
> destructor TMyComp.Destroy;
> begin
> FPageControl.WindowProc := FDefPageControlWndProc;
> FPageControl.Free;
You destroy self? before inherited?
You may have meant FPageControl := TPageControl.Create(Self); in the
constructor, but would be of no use, since TMyComp does not expose
FPageControl.
>> constructor TMyComp.Create(AOwner: TComponent);
>> begin
>> inherited;
>> FPageControl := TPageControl(Self);
> You cast Self, a descendent of TComponent to a TPageControl?
I meant to call TPageControl.Create()
FPageControl := TPageControl.Create(Self);
> You may have meant FPageControl := TPageControl.Create(Self);
> in the constructor, but would be of no use, since TMyComp does
> not expose FPageControl.
Clearly my example was to demonstrate own to subclass the TPageControl's
message handler, not how to manage the TPageControl object in general.
Gambit