Search code examples
eventsoverridingcomponentsprotecteddelphi-xe8

Overload an Event from TNetHTTPClient (private method not virtual)


I'm creating a component from TNetHTTPClient, and i like to overload the events (procedure declared in private section in TNetHTTPClient) :

  TNetHTTPClient = class(TComponent)
  private
    procedure DoOnRequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
    procedure DoOnRequestError(const Sender: TObject; const AError: string);
    procedure DoOnReceiveData(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean);

But i can't call them from my class : like this.

  TRequestAccess = class(TNetHTTPClient)
  private
    procedure ShowLoadAnimation ;
    procedure HideLoadAnimation ;

    procedure DoOnRequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse); override;
    procedure DoOnRequestError(const Sender: TObject; const AError: string); override;
    procedure DoOnReceiveData(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean); override;

...

    procedure TRequestAccess.DoOnReceiveData(const Sender: TObject; AContentLength,
      AReadCount: Int64; var Abort: Boolean);
    begin
      self.HideLoadAnimation ;
      inherited;
    end;

    procedure TRequestAccess.DoOnRequestCompleted(const Sender: TObject;
      const AResponse: IHTTPResponse);
    begin
      self.HideLoadAnimation ;
      inherited;
    end;

    procedure TRequestAccess.DoOnRequestError(const Sender: TObject;
      const AError: string);
    begin
      self.HideLoadAnimation ;
      inherited;
    end;

ShowLoadAnimation and HideLoadAnimation are 2 functions to automatically show and hide a TAniIndicator.

Seems i can't override because it's declared in private and non virtual ?

how can i do this ?

I think i can't rewrite my own function because there is a thread..

procedure TNetHTTPClient.DoOnRequestError(const Sender: TObject; const AError: string);
begin
  if Assigned(FOnRequestError) then
    TThread.Synchronize(nil, procedure
    begin
      FOnRequestError(Sender, AError);
    end);
end;

Solution

  • this work properly. official method from embarcadero.

    unit NetHTTPClientUnit;
    
    interface
    
    uses
      System.SysUtils, System.Classes, System.Net.HttpClientComponent,System.Net.HttpClient,System.Net.URLClient;
    
    type
      TNewNetHTTPClient = class(TNetHTTPClient)
      private
        FOnAuthEventInternal        : TCredentialsStorage.TCredentialAuthevent;
        FOnReceiveDataInternal      : TReceiveDataEvent;
        FOnRequestCompletedInternal : TRequestCompletedEvent;
        FOnRequestErrorInternal     : TRequestErrorEvent;
    
        function GetAuthEventOverride: TCredentialsStorage.TCredentialAuthevent;
        procedure SetAuthEventOverride(const Value: TCredentialsStorage.TCredentialAuthevent);
        function GetOnReceiveData: TReceiveDataEvent;
        function GetOnRequestCompleted: TRequestCompletedEvent;
        function GetOnRequestError: TRequestErrorEvent;
        procedure SetOnReceiveData(const Value: TReceiveDataEvent);
        procedure SetOnRequestCompleted(const Value: TRequestCompletedEvent);
        procedure SetOnRequestError(const Value: TRequestErrorEvent);
        { Private declarations }
        procedure InternalReceiveDataEvent(const Sender: TObject; AContentLength: Int64; AReadCount: Int64; var Abort: Boolean);
        procedure InternalRequestErrorEvent(const Sender: TObject; const AError: string);
        procedure InternalRequestCompletedEvent(const Sender: TObject; const AResponse: IHTTPResponse);
        procedure InternalAuthEvent(const Sender: TObject;
          AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,
          APassword: string; var AbortAuth: Boolean;
          var Persistence: TAuthPersistenceType);
    
      protected
        { Protected declarations }
      public
        constructor Create(AOwner: TComponent); override;
      published
        /// <summary> UserName needed to be authenticated to the proxy</summary>
        property OnAuthEvent: TCredentialsStorage.TCredentialAuthevent read GetAuthEventOverride write SetAuthEventOverride;
        /// <summary> Event fired when a request finishes</summary>
        property OnRequestCompleted: TRequestCompletedEvent read GetOnRequestCompleted write SetOnRequestCompleted;
        /// <summary> Event fired when a request has an error</summary>
        property OnRequestError: TRequestErrorEvent read GetOnRequestError write SetOnRequestError;
        /// <summary>Property to manage the ReceiveData Event</summary>
        property OnReceiveData: TReceiveDataEvent read GetOnReceiveData write SetOnReceiveData;
      end;
    
    procedure Register;
    
    implementation
    
    Uses WinApi.Windows;
    
    procedure Register;
    begin
      RegisterComponents('Net', [TNewNetHTTPClient]);
    end;
    
    { TNewNetHTTPClient }
    
    constructor TNewNetHTTPClient.Create(AOwner: TComponent);
    begin
      inherited;
      inherited OnAuthEvent        := InternalAuthEvent;
      inherited OnRequestCompleted := InternalRequestCompletedEvent;
      inherited OnRequestError     := InternalRequestErrorEvent;
      inherited OnReceiveData      := FOnReceiveDataInternal;
    end;
    
    function TNewNetHTTPClient.GetAuthEventOverride: TCredentialsStorage.TCredentialAuthevent;
    begin
      Result := FOnAuthEventInternal;
    end;
    
    function TNewNetHTTPClient.GetOnReceiveData: TReceiveDataEvent;
    begin
      result := FOnReceiveDataInternal;
    end;
    
    function TNewNetHTTPClient.GetOnRequestCompleted: TRequestCompletedEvent;
    begin
       Result := FOnRequestCompletedInternal;
    end;
    
    function TNewNetHTTPClient.GetOnRequestError: TRequestErrorEvent;
    begin
       Result := FOnRequestErrorInternal;
    end;
    
    procedure TNewNetHTTPClient.InternalAuthEvent(const Sender: TObject;
      AnAuthTarget: TAuthTargetType; const ARealm, AURL: string; var AUserName,
      APassword: string; var AbortAuth: Boolean;
      var Persistence: TAuthPersistenceType);
    begin
       OutputDebugString('InternalAuthEvent');
       if Assigned(FOnAuthEventInternal) then
           FOnAuthEventInternal(Sender, AnAuthTarget, ARealm, AURL,AUserName,APassword,AbortAuth,Persistence);
    end;
    
    procedure TNewNetHTTPClient.InternalReceiveDataEvent(const Sender: TObject;
      AContentLength, AReadCount: Int64; var Abort: Boolean);
    begin
       OutputDebugString('InternalReceiveDataEvent');
       if Assigned(FOnReceiveDataInternal) then
              FOnReceiveDataInternal(Sender, AContentLength, AReadCount, Abort);
    end;
    
    procedure TNewNetHTTPClient.InternalRequestCompletedEvent(const Sender: TObject;
      const AResponse: IHTTPResponse);
    begin
      OutputDebugString('RequestCompletedEvent');
      if AResponse <> nil then
           OutputDebugString( PChar(AResponse.ContentEncoding));
      if Assigned(FOnRequestCompletedInternal) then
          FOnRequestCompletedInternal(Sender,AResponse);
    end;
    
    procedure TNewNetHTTPClient.InternalRequestErrorEvent(const Sender: TObject;
      const AError: string);
    begin
      OutputDebugString(PChar('RequestErrorEvent ' + AError));
      if Assigned(FOnRequestErrorInternal)  then
             FOnRequestErrorInternal(Sender,AError);
    end;
    
    procedure TNewNetHTTPClient.SetAuthEventOverride(
      const Value: TCredentialsStorage.TCredentialAuthevent);
    begin
        FOnAuthEventInternal := Value;
    end;
    
    procedure TNewNetHTTPClient.SetOnReceiveData(const Value: TReceiveDataEvent);
    begin
      FOnReceiveDataInternal := Value;
    end;
    
    procedure TNewNetHTTPClient.SetOnRequestCompleted(
      const Value: TRequestCompletedEvent);
    begin
       FOnRequestCompletedInternal := Value;
    end;
    
    procedure TNewNetHTTPClient.SetOnRequestError(const Value: TRequestErrorEvent);
    begin
      FOnRequestErrorInternal := Value;
    end;
    
    end.