Results 1 to 9 of 9

Thread: Overnemen events van TIdHTTP in eigen component

  1. #1
    Senior Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    101

    Question Overnemen events van TIdHTTP in eigen component

    Hallo,

    Ik heb een eigen compont voor het updaten/downloaden via internet.
    Hierbij ondervind ik teveel problemen bij het maken van de verbinding en downloaden. (proxy, firewall, htaccess)

    Indy, IdHTTP blijkt hier de oplossing!
    Standalone werkt alles prima, nu nog onderbrengen in mijn eigen component...

    Ik wil de events van IdHTTP (OnConnected, OnWorkBegin, OnWork etc.) door de evenknie van mijn eigen component laten uitvoeren.

    Code:
    constructor TXWebUpdate.Create(AOwner: TComponent);
    //*************************************************
    begin
    
      Inherited Create(AOwner);
    
      FProductInfo := TProductInfo.Create;
    
      FTagInfo := TTagInfo.Create;
      FInfo      := TStringList.Create;
      FVersion := WebUpdateVersion;
    
      FIdHTTP := TIdHTTP.Create(nil);
      with FIdHTTP do
      begin
        FIdHTTP.OnConnected := OnAfterConnect;
        FIdHTTP.OnWorkBegin := OnStartDownload;
        FIdHTTP.OnWork := OnDownload;
      end;
    
      FOptions  := [];
      FHTTPPort := 80;
    
      FDebug     := False;
      FDebugFile := 'c:\Temp\XWebUpdate_Debug.html';
    
      // Create
    end;
    Dit blijkt niet te werken...
    Wanneer ik dezelfde code in een procedure zet werkt het wel?

    Code:
    procedure TXWebUpdate.GetFile(FURL: String;
                                  FUserName: String; FPassword: String;
                                  FProxyName: String; FProxyPort: Integer; FProxyUserName: String; FProxyPassword: String;
                                  var FHTMLString: String;
                                  FSaveToFile: Boolean; FFileName: String);
    //********************************************************************************************************************
    var
      HostName, FileName: String;
    
      HttpCode: Integer;
      Flags: OleVariant;
    
      HTMLDocument: IHTMLDocument2;
      HTMLBodyElem: IHTMLBodyElement;
      oleTekst    : OleVariant;
      F: TextFile;
    
    begin
    
      while True do
      begin
        try
          FIdHTTP.OnConnected := OnAfterConnect;
          FIdHTTP.OnWorkBegin := OnStartDownload;
          FIdHTTP.OnWork := OnDownload;
    ...
    Mijn eigen OnAfterConnect wordt nu wel aangeroepen en uitgevoerd.

    Declaraties:
    Code:
      TXWebUpdate = class(TComponent)
      Private
        FUserName: String;
        FPassword: String;
        FProxyName: String;
        FProxyPort: Integer;
        FProxyUserName: String;
        FProxyPassword: String;
        FFileName: String;
    
        FErrorStr: String;
        FHTMLString: String;
        FInfo: TstringList;
    
        FOnBeforeConnect: TNotifyEvent;
        FOnAfterConnect: TNotifyEvent;
        FOnConnectError: TConnectErrorEvent;
    
        FOnStartDownload: TWorkBeginEvent;
        FOnDownload: TWorkEvent;
        FOnEndDownload: TWorkEndEvent;
        FOnDownloadError: TDownloadErrorEvent;
        FOnNoUpdateFound: TNotifyEvent;
    ...
      protected
        procedure DoBeforeConnect; virtual;
        procedure DoAfterConnect; virtual;
        procedure DoConnectError(Const ErrorStr: String); virtual;
    
        procedure DoStartDownload(AWorkMode: TWorkMode; const ASize: Int64 = 0); virtual;
        procedure DoDownload(AWorkMode: TWorkMode; const ACount: Int64); virtual;
        procedure DoDownloadComplete(AWorkMode: TWorkMode); virtual;
        procedure DoDownloadError(Const ErrorStr: String); virtual;
    
        procedure GetFile(FURL: String;
                          FUserName: String; FPassword: String;
                          FProxyName: String; FProxyPort: Integer; FProxyUserName: String; FProxyPassword: String;
                          var FHTMLString: String;
                          FSaveToFile: Boolean; FFileName: String);
    ...
      public
        Constructor Create(AOwner: TComponent); Override;
        Destructor Destroy; Override;
    
        property HTMLString: String read FHTMLString;
    
        procedure GetInfoFile;
    ...
      published
        property UserName: String read FUserName write FUserName;
        property Password: String read FPassword write FPassword;
        property ProxyName: String read FProxyName write FProxyName;
        property ProxyPort: Integer read FProxyPort write FProxyPort;
        property ProxyUserName: String read FProxyUserName write FProxyUserName;
        property ProxyPassword: String read FProxyPassword write FProxyPassword;
        property Options: TUpdateOptions read FOptions write FOptions;
    
        property OnBeforeConnect: TNotifyEvent read FOnBeforeConnect write FOnBeforeConnect;
        property OnAfterConnect: TNotifyEvent read FOnAfterConnect write FOnAfterConnect;
        property OnConnectError: TConnectErrorEvent read FOnConnectError write FOnConnectError;
    
        property OnStartDownload: TWorkBeginEvent read FOnStartDownload write FOnStartDownload;
        property OnDownload: TWorkEvent Read FOnDownload write FOnDownload;
        property OnEndDownload: TWorkEndEvent read FOnEndDownload write FOnEndDownload;
        property OnDownloadError: TDownloadErrorEvent Read FOnDownloadError Write FOnDownloadError;
    ...
      end;
    Aanroepen:
    Code:
    procedure TXWebUpdate.DoAfterConnect;
    //***********************************
    begin
    
      if Assigned(FOnAfterConnect) then FOnAfterConnect(Self);
    
      // DoAfterConnect
    end;
    Wat er gebeurt zal wel logisch zijn, maar kan iemand me dat uitleggen?

    Gr.
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  2. #2
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Haal regel 14 (with FIdHTTP do) eens weg.
    TMemoryLeak.Create(Nil);

  3. #3
    Senior Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    101
    Quote Originally Posted by VideoRipper View Post
    Haal regel 14 (with FIdHTTP do) eens weg.
    Bedankt voor het meekijken, maar dat was 'm niet. Was wel dubbelop...

    Gr.
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  4. #4
    Jan
    Join Date
    Oct 2007
    Location
    Mijdrecht
    Posts
    906
    Ik zou mijn component laten erven van IdHTTP en vervolgens de event procedures met een override declaren.
    In de procedure zelf roep je dan nog eens inherited aan.

  5. #5
    Senior Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    101

    Smile

    Ik ben eruit...

    Tijdens testen vond ik dat OnAfterConnect etc nog niet assigned waren in Create();
    Ik heb de hooks verplaatst naar een nieuw aangemaakte procedure Loaded;

    Code:
    procedure TXIdWebUpdate.Loaded;
    //*****************************
    begin
    
      Inherited;
    
      FIdHTTP.OnConnected := OnAfterConnect;
      FIdHTTP.OnWorkBegin := OnStartDownload;
      FIdHTTP.OnWork      := OnDownload;
    
      // Loaded
    end;
    Nu werkt alles naar behoren!



    Bedankt iedereen voor het meedenken;

    Grtz.
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  6. #6
    Dit betekent dan ook dat je die events niet meer zomaar kunt wijzigen in code, want jouw component verwijst er dan wel naar, maar het Indy component dat het event triggert niet. Je kunt dat op twee manieren oplossen, de makkelijkste is een setter voor je event:

    Delphi Code:
    1. property OnAfterConnect: TNotifyEvent read FOnAfterConnect write SetOnAfterConnect;
    2.  
    3. procedure TXIdWebUpdate.SetOnAfterConnect(Value: TNotifyEvent);
    4. begin
    5.   FOnAfterConnect := Value;
    6.   FIdHTTP.OnConnected  := Value;
    7. end;
    Maar beter is het om een eigen event handler te maken die aangeroepen wordt als het Indy component een event uitvoert. Op die manier koppel je het nog wat losser van elkaar, want in je huidige opzet zul je ook merken dat de Sender van het OnAfterConnect event niet jouw component is, maar de IdHTTP!

    Ik zou er dus liever voor kiezen om event handlers te maken die specifiek voor het Indy component zijn, die op hun beurt dan weer DoAfterConnect aanroepen. Op die manier kun je als gebruiker van jouw component een OnAfterConnect event koppelen, of een afgeleide maken waarin je DoAfterConnect override, zonder geconfronteerd te worden met het achterliggende TIdHTTP component.

    Delphi Code:
    1. class TXIdWebUpdate
    2.   private
    3.     // Dit is de event handler voor het Indy component. Deze kan private zijn.
    4.     procedure DoIndyConnected(Sender: TComponent);
    5.   protected
    6.     // Dit is waar afgeleiden van jouw component weer hun eigen gedrag in kunnen stoppen.
    7.     procedure DoAfterConnect; virtual;
    8. end;
    9.  
    10. constructor TXIdWebUpdate.Create(AOwner: TComponent);
    11. begin
    12.   Inherited Create(AOwner);
    13.  
    14.   FIdHTTP := TIdHTTP.Create(nil);
    15.   FIdHTTP.OnConnected := DoIndyConnected;
    16.   // Andere events dito
    17. end;
    18.  
    19. procedure TXWebUpdate.DoIndyConnected(Sender: TComponent);
    20. begin
    21.   DoAfterConnect;
    22. end;
    23.  
    24. procedure TXWebUpdate.DoAfterConnect;
    25. begin
    26.   if Assigned(OnAfterConnect) then
    27.     OnAfterConnect(Self);
    28. end;
    Last edited by GolezTrol; 23-Dec-14 at 15:03.
    1+1=b

  7. #7
    Senior Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    101
    Hallo GolezTrol!

    Maar beter is het om een eigen event handler te maken die aangeroepen wordt als het Indy component een event uitvoert. Op die manier koppel je het nog wat losser van elkaar, want in je huidige opzet zul je ook merken dat de Sender van het OnAfterConnect event niet jouw component is, maar de IdHTTP!
    Dit was precies mijn opzet. IdHTTP hard gekoppeld aan mijn OnAfterConnect! IdHTTP.OnConnected vuurt, en voert OnAfterConnect uit.
    OnAfterConnect staat bij de events van mijn component, niet OnConnected van IdHTTP...


    Ik zal jouw suggesties zeker ook nog doorspitten ter lering ende vermaak. Dank!



    Grtz.
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  8. #8
    Senior Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    101
    Senks GolezTrol!

    Quote Originally Posted by GolezTrol View Post
    Dit betekent dan ook dat je die events niet meer zomaar kunt wijzigen in code, want jouw component verwijst er dan wel naar, maar het Indy component dat het event triggert niet. Je kunt dat op twee manieren oplossen, de makkelijkste is een setter voor je event:

    Delphi Code:
    1. property OnAfterConnect: TNotifyEvent read FOnAfterConnect write SetOnAfterConnect;
    2.  
    3. procedure TXIdWebUpdate.SetOnAfterConnect(Value: TNotifyEvent);
    4. begin
    5.   FOnAfterConnect := Value;
    6.   FIdHTTP.OnConnected  := Value;
    7. end;
    Maar beter is het om een eigen event handler te maken die aangeroepen wordt als het Indy component een event uitvoert. Op die manier koppel je het nog wat losser van elkaar, want in je huidige opzet zul je ook merken dat de Sender van het OnAfterConnect event niet jouw component is, maar de IdHTTP!

    Ik zou er dus liever voor kiezen om event handlers te maken die specifiek voor het Indy component zijn, die op hun beurt dan weer DoAfterConnect aanroepen. Op die manier kun je als gebruiker van jouw component een OnAfterConnect event koppelen, of een afgeleide maken waarin je DoAfterConnect override, zonder geconfronteerd te worden met het achterliggende TIdHTTP component.

    Delphi Code:
    1. class TXIdWebUpdate
    2.   private
    3.     // Dit is de event handler voor het Indy component. Deze kan private zijn.
    4.     procedure DoIndyConnected(Sender: TComponent);
    5.   protected
    6.     // Dit is waar afgeleiden van jouw component weer hun eigen gedrag in kunnen stoppen.
    7.     procedure DoAfterConnect; virtual;
    8. end;
    9.  
    10. constructor TXIdWebUpdate.Create(AOwner: TComponent);
    11. begin
    12.   Inherited Create(AOwner);
    13.  
    14.   FIdHTTP := TIdHTTP.Create(nil);
    15.   FIdHTTP.OnConnected := DoIndyConnected;
    16.   // Andere events dito
    17. end;
    18.  
    19. procedure TXWebUpdate.DoIndyConnected(Sender: TComponent);
    20. begin
    21.   DoAfterConnect;
    22. end;
    23.  
    24. procedure TXWebUpdate.DoAfterConnect;
    25. begin
    26.   if Assigned(OnAfterConnect) then
    27.     OnAfterConnect(Self);
    28. end;
    Ik heb mijn component zo omgebouwd, 2e methode.
    De enige aanpassing: procedure DoIndyConnected(Sender: TObject); omdat IdHTTP.OnConnected een TObject is.

    Soow. Er gaat geen dag voorbij zonder wat te leren
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  9. #9
    Quote Originally Posted by DaSteelMan View Post
    De enige aanpassing: procedure DoIndyConnected(Sender: TObject);
    Ah ja. Dat krijg je ervan als je het uit je hoofd probeert.
    1+1=b

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •