Board index » cppbuilder » Accessing Methods of Components within a Component

Accessing Methods of Components within a Component

Hello Everyone,
Just when I thought I was beginning to understand this, well... I am trying
to write a component which uses an Indy TCP Client component. My thought was
to have my component  have a  public/published method which in turn would
call the TIdTCPClient->Connect() method.  My attempt at doing this compiles
and installs the component OK, but when I call this method from an
application I get access violations.  Attached is a subset of the component
and header.  Any help would be greatly appreciated. Thanks.

//--------------My_Client.h
file---------------------------------------------

#ifndef My_ClientH
#define My_ClientH
//--------------------------------------------------------------------------
-
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include "IdComponent.hpp"
#include "IdTCPClient.hpp"
#include "IdTCPConnection.hpp"
//--------------------------------------------------------------------------
-
class PACKAGE My_Client : public TCustomPanel
{
private:
    TTimer *WatchDogTimer;
    TTimer *Timer1;
protected:
public:
    TIdTCPClient *IdTCPClient1;
    __fastcall My_Client(TComponent* Owner);
  void __fastcall Timer1Event(TObject *Sender);
  void __fastcall WatchDogEvent(TObject *Sender);
  void __fastcall OneShot(TObject *Sender);
__published:

Quote
};

//--------------------------------------------------------------------------
-
#endif

//------------My_Client.cpp
file-----------------------------------------------

#include <vcl.h>
#include "IdComponent.hpp"
#include "IdTCPClient.hpp"
#include "IdTCPConnection.hpp"
#pragma hdrstop

int Coun{*word*53}chDogs = 0, Count = 0, data[38];
AnsiString logDate, logTime;
bool OneShotFlag = false;

#include "My_Client.h"

#pragma package(smart_init)
//--------------------------------------------------------------------------
-
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(My_Client *)
{
    new My_Client(NULL);

Quote
}

//--------------------------------------------------------------------------
-
__fastcall My_Client::My_Client(TComponent* Owner)
    : TCustomPanel(Owner)
{

    TIdTCPClient *IdTCPClient1 = new TIdTCPClient(Owner);
     IdTCPClient1->Host = "127.0.0.1";
     IdTCPClient1->Port = 6000;
     IdTCPClient1->OnConnected = ConnectedEvent;

     WatchDogTimer = new TTimer(this);
     WatchDogTimer->Interval = 5000;
     WatchDogTimer->Enabled = false;
     WatchDogTimer->OnTimer = WatchDogEvent;

     Timer1 = new TTimer(this);
     Timer1->Interval = 1000;
     Timer1->Enabled = false;
     Timer1->OnTimer = Timer1Event;

Quote
}

//--------------------------------------------------------------------------
-
void __fastcall My_Client::OneShot(TObject *Sender)
{
   IdTCPClient1->Connect();
   OneShotFlag = true;

Quote
}

//--------------------------------------------------------------------------
-
namespace My_client
{
    void __fastcall PACKAGE Register()
    {
         TComponentClass classes[1] = {__classid(My_Client)};
         RegisterComponents("AARE", classes, 0);
    }
Quote
}

//--------------------------------------------------------------------------
-
 

Re:Accessing Methods of Components within a Component


Quote
"glenn" <m...@nowhere.com> wrote in message news:3c4987d3_1@dnews...
> __fastcall My_Client::My_Client(TComponent* Owner)
>     : TCustomPanel(Owner)
> {

>     TIdTCPClient *IdTCPClient1 = new TIdTCPClient(Owner);

Above you've declared a(nother) pointer to TIdTCPClient.  This pointer only
lives here in the ctor.  The pointer you're using in OneShot() is the one
you've declared as a member variable.  Since it's not assigned to a valid
instance an AV will occur when using it.  You should use the same approach
as you did with the TTimers.  Try this:

    IdTCPClient1 = new TIdTCPClient(Owner);

Ralph

Re:Accessing Methods of Components within a Component


Ralph,
First of all thanks for your response!  But I must not understand it.  I am
assuming that I should use your manner of instatiation for "IdTCPClient1" in
the constructor? leaving the pointer declaration as-is in the header? --if
so, (very confused) I get a message in an application that tries to use this
component: "EClassNotFound with message 'Class TIdTCPClient not found' "!
This I don't understand either!  Further help would me much appreciated!!!
Thanks again.
glenn

Re:Accessing Methods of Components within a Component


The problem is that you've declared two variables with the same name.  One
is local to the constructor only, and is the one that is instantiated.  The
second one is accessable to the entire component, but you do not instantiate
it, that's why you get Access Violations.

Change this line:

    TIdTCPClient *IdTCPClient1 = new TIdTCPClient(Owner);

To this instead:

    IdTCPClient1 = new TIdTCPClient(Owner);

Also, it's generally good practice to assign the Panel to be the Owner, not
the Panel's Owner.  Since it's the Panel that contains the component:

    IdTCPClient1 = new TIdTCPClient(this);

Gambit

Quote
"glenn" <m...@nowhere.com> wrote in message news:3c49e183$1_1@dnews...
> Ralph,
> First of all thanks for your response!  But I must not understand it.  I
am
> assuming that I should use your manner of instatiation for "IdTCPClient1"
in
> the constructor? leaving the pointer declaration as-is in the header?

Re:Accessing Methods of Components within a Component


Everyone,

Thanks for all your patience I FINALLY got it.  I need to study this a bit
to TRY to get it to sink in!  Thanks again!!
glenn

Other Threads