Board index » cppbuilder » Using VCL components in Non-VCL components

Using VCL components in Non-VCL components

Hello again,
I have a large project that management wishes to be ANSI as much as
possible/practical.  Realizing that the Windows/GUI portion is not practical
to be ANSI, we wish to segregate the VCL/GUI stuff from that  that does not
require windows interface, then compile those sections enforcing ANSI
standards.  My question is this:  Can I include VCL components (non-visual
ones of course, like TTimer, TIdTCPClient etc.) in non-VCL (ie ordinary
classes - not PACKAGES) components?  Using the Borland's TCounter example as
a guide, I tried, only to get errors when trying to instantiate the VCL
components in the constructor (using the same format that works using
PACKAGES).  Below is an example of what I tried.  Can this be done?  Thanks
in advance.

glenn

//-------------------------------------------------------------------------
//    counter.h. - example of a small, non-visual counter component
//-------------------------------------------------------------------------
class TCounter;         // forward

typedef void (__closure *TCounterEvent)(TCounter *Sender);
//-------------------------------------------------------------------------
class TCounter
{
private:
  TCounterEvent FOnMultiple;
  int FVal;
  int FMultiple;
  TTimer *Timer1;   // Added this
  IdTCPClient *IdTCPClient1;  // and this
public:
  __property int Val = {read=FVal, write=FVal};
  __property int Multiple = {read=FMultiple};
  __property TCounterEvent OnMultiple = {read=FOnMultiple,
write=FOnMultiple};
  void Clear();
  void Increment();
  TCounter(int Multiple);

Quote
};

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

//-------------------------------------------------------------------------
//    counter.cpp - example of a small, non-visual counter component
//-------------------------------------------------------------------------
#include "counter.h"
//-------------------------------------------------------------------------
TCounter::TCounter(int Multiple)
{
  Timer1 = new TTimer(this);   // can't instaniate?
  IdTCPClient1 = new TIdTCPClient(this); // can't instaniate?
  FMultiple = Multiple;

Quote
}

//-------------------------------------------------------------------------
void TCounter::Clear()
{
  FVal = 0;
Quote
}

//-------------------------------------------------------------------------
void TCounter::Increment()
{
  if (((++FVal) % FMultiple) == 0)
      OnMultiple(this);
Quote
}

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

Re:Using VCL components in Non-VCL components


Quote
glenn wrote:

> class TCounter
> {

[snip]

Quote
> TCounter::TCounter(int Multiple)
> {
>   Timer1 = new TTimer(this);   // can't instaniate?

The ctor of TTimer expects an 'TComponent *' but your
class TCounter is *not* derived form TComponent.

Quote
>   IdTCPClient1 = new TIdTCPClient(this); // can't instaniate?
>   FMultiple = Multiple;
> }

Frank

Re:Using VCL components in Non-VCL components


Quote
glenn wrote:
> Hello again,
> I have a large project that management wishes to be ANSI as much as
> possible/practical.  Realizing that the Windows/GUI portion is not practical
> to be ANSI, we wish to segregate the VCL/GUI stuff from that  that does not
> require windows interface, then compile those sections enforcing ANSI
> standards.  My question is this:  Can I include VCL components (non-visual
> ones of course, like TTimer, TIdTCPClient etc.) in non-VCL (ie ordinary
> classes - not PACKAGES) components?  Using the Borland's TCounter example as
> a guide, I tried, only to get errors when trying to instantiate the VCL
> components in the constructor (using the same format that works using
> PACKAGES).  Below is an example of what I tried.  Can this be done?  Thanks
> in advance.
> //-------------------------------------------------------------------------
> //    counter.cpp - example of a small, non-visual counter component
> //-------------------------------------------------------------------------
> #include "counter.h"
> //-------------------------------------------------------------------------
> TCounter::TCounter(int Multiple)
> {
>   Timer1 = new TTimer(this);   // can't instaniate?

Timer1 = new TTimer(0);

Quote
>   IdTCPClient1 = new TIdTCPClient(this); // can't instaniate?

IdTCPClient1 = new TIdTCPClient(0);

Also:

TCounter::~TCounter()
{
delete Timer1;
delete IdTCPClient1;

Quote
}

or use std::auto_ptr<> for each one instead.

Re:Using VCL components in Non-VCL components


Edward,
using the form you suggested: Timer1 = new TTimer(0) does get through the
initialization but trying to use the OnTimer event causes the compiler
error: Cannot convert 'void (* (_closure )())()' to 'void (_fastcall *
(_closure )(TObject *))(TObject *)'.  I can't seem to find the right syntax
for the std::auto_ptr<> either.  Can you give me some more help?
glenn

Quote
"Edward Diener" <eddie...@tropicsoft.com> wrote in message

news:3C6D5272.6030502@tropicsoft.com...
Quote
> glenn wrote:

> > Hello again,
> > I have a large project that management wishes to be ANSI as much as
> > possible/practical.  Realizing that the Windows/GUI portion is not
practical
> > to be ANSI, we wish to segregate the VCL/GUI stuff from that  that does
not
> > require windows interface, then compile those sections enforcing ANSI
> > standards.  My question is this:  Can I include VCL components
(non-visual
> > ones of course, like TTimer, TIdTCPClient etc.) in non-VCL (ie ordinary
> > classes - not PACKAGES) components?  Using the Borland's TCounter
example as
> > a guide, I tried, only to get errors when trying to instantiate the VCL
> > components in the constructor (using the same format that works using
> > PACKAGES).  Below is an example of what I tried.  Can this be done?
Thanks
> > in advance.

//-------------------------------------------------------------------------
Quote
> > //    counter.cpp - example of a small, non-visual counter component

//-------------------------------------------------------------------------
Quote
> > #include "counter.h"

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

- Show quoted text -

Quote
> > TCounter::TCounter(int Multiple)
> > {
> >   Timer1 = new TTimer(this);   // can't instaniate?

> Timer1 = new TTimer(0);

> >   IdTCPClient1 = new TIdTCPClient(this); // can't instaniate?

> IdTCPClient1 = new TIdTCPClient(0);

> Also:

> TCounter::~TCounter()
> {
> delete Timer1;
> delete IdTCPClient1;
> }

> or use std::auto_ptr<> for each one instead.

Re:Using VCL components in Non-VCL components


Your OnTimer handler must be handled like the following:

    class TCounter
    {
        ...
        TCounter(int Multiple);
        void __fastcall TimerHandler(TObject *Sender);
    };

    TCounter::TCounter(int Multiple)
    {
        Timer1 = new TTimer(NULL);
        Timer1->OnTimer = TimerHandler;
    ...
    }

    void __fastcall TCounter::TimerHandler(TObject *Sender)
    {
        // your timer code here
    }

As for auto_ptr, it's like this (though auto_ptr is NOT required, it was
only suggested):

    #include <memory>

    class TCounter
    {
        ...
        std::auto_ptr<TTimer*> Timer1;
        std::auto_ptr<TIdTCPClient*> IdTCPClient1;
        TCounter(int Multiple);
    };

    TCounter::TCounter(int Multiple)
    {
        Timer1 = std::auto_ptr<TTimer*>(new TTimer(0));
        IdTCPClient1 = std::auto_ptr<TIdTCPClient*>(new TIdTCPClient(0));
        ...
    }

Gambit

Quote
"glenn" <gbarke...@comcast.net> wrote in message news:3c6dce31$1_2@dnews...
> using the form you suggested: Timer1 = new TTimer(0) does get through the
> initialization but trying to use the OnTimer event causes the compiler
> error: Cannot convert 'void (* (_closure )())()' to 'void (_fastcall *
> (_closure )(TObject *))(TObject *)'.  I can't seem to find the right
syntax
> for the std::auto_ptr<> either.  Can you give me some more help?

Re:Using VCL components in Non-VCL components


Quote
Remy Lebeau [TeamB] wrote:
> As for auto_ptr, it's like this (though auto_ptr is NOT required, it was
> only suggested):

>     #include <memory>

>     class TCounter
>     {
>         ...
>         std::auto_ptr<TTimer*> Timer1;
>         std::auto_ptr<TIdTCPClient*> IdTCPClient1;

No, Remy. std::auto_ptr<> does not require the * syntax unles you are
encapsulating a ** to object. Instead it is:

           std::auto_ptr<TTimer> Timer1;
           std::auto_ptr<TIdTCPClient> IdTCPClient1;

Quote
>         TCounter(int Multiple);
>     };

>     TCounter::TCounter(int Multiple)
>     {
>         Timer1 = std::auto_ptr<TTimer*>(new TTimer(0));
>         IdTCPClient1 = std::auto_ptr<TIdTCPClient*>(new TIdTCPClient(0));
>         ...
>     }

And this should be:

TCounter::TCounter(int Multiple) :
      Timer1(new TTimer(0)),
      IdTCPClient1(new TIdTCPClient(0))
     {
     ...
     }

Re:Using VCL components in Non-VCL components


Edward & Remy,

First of all, thanks for all the help.  But, I am not sure that this is
going to accomplish the main purpose of building a  non-VCL component (you
guys have already helped me build the ordinary VCL components correctly).
That is, I was hoping to create and compile a new non-VCL version of these
components using the "ANSI" tag for compiler options.  From earlier postings
regarding BCB's __fastcall modifier, and the results I see when I invoke the
"ANSI" option, it appears that __fastcall itself, plus its implementation
include a raft of non-ANSI stuff.  What I was hoping to do was break up my
code into small simple ANSI components and segregate the non-ANSI stuff into
GUI sections.  For most of the  code I write that is possible, however, it
would still be nice to be able to use some VCL  components (non-visual ones)
in an ANSI compliant manner --is this possible?

glenn

Re:Using VCL components in Non-VCL components


Once you turn on ANSI, VCL component code won't compile. This is because
the VCL components use non-ANSI extensions to the C++ language to do
their property, event, and visual RAD magic. You will also find that the
standard Windows header files include in windows.h will not compile
correctly with ANSI turned on. I suggest you just drop your ideas of
using ANSI with Windows GUI or VCL components and only attempt to use it
with console modules which strictly uses just the C++ standard library
routines.

Even with ANSI turned off, your code can be ANSI compliant except for
the VCL extensions.

Quote
glenn wrote:
> Edward & Remy,

> First of all, thanks for all the help.  But, I am not sure that this is
> going to accomplish the main purpose of building a  non-VCL component (you
> guys have already helped me build the ordinary VCL components correctly).
> That is, I was hoping to create and compile a new non-VCL version of these
> components using the "ANSI" tag for compiler options.  From earlier postings
> regarding BCB's __fastcall modifier, and the results I see when I invoke the
> "ANSI" option, it appears that __fastcall itself, plus its implementation
> include a raft of non-ANSI stuff.  What I was hoping to do was break up my
> code into small simple ANSI components and segregate the non-ANSI stuff into
> GUI sections.  For most of the  code I write that is possible, however, it
> would still be nice to be able to use some VCL  components (non-visual ones)
> in an ANSI compliant manner --is this possible?

Re:Using VCL components in Non-VCL components


Edward,
Thanks for your opinion...I was slowly coming to that conclusion as well.
Now I need to somehow present this message to those who insist on ANSI, and
hope that they don't force me to abandon BCB altogether!

glenn

Quote
"Edward Diener" <eddie...@tropicsoft.com> wrote in message

news:3C6E7BF8.2070907@tropicsoft.com...
Quote
> Once you turn on ANSI, VCL component code won't compile. This is because
> the VCL components use non-ANSI extensions to the C++ language to do
> their property, event, and visual RAD magic. You will also find that the
> standard Windows header files include in windows.h will not compile
> correctly with ANSI turned on. I suggest you just drop your ideas of
> using ANSI with Windows GUI or VCL components and only attempt to use it
> with console modules which strictly uses just the C++ standard library
> routines.

> Even with ANSI turned off, your code can be ANSI compliant except for
> the VCL extensions.

> glenn wrote:

> > Edward & Remy,

> > First of all, thanks for all the help.  But, I am not sure that this is
> > going to accomplish the main purpose of building a  non-VCL component
(you
> > guys have already helped me build the ordinary VCL components
correctly).
> > That is, I was hoping to create and compile a new non-VCL version of
these
> > components using the "ANSI" tag for compiler options.  From earlier
postings
> > regarding BCB's __fastcall modifier, and the results I see when I invoke
the
> > "ANSI" option, it appears that __fastcall itself, plus its
implementation
> > include a raft of non-ANSI stuff.  What I was hoping to do was break up
my
> > code into small simple ANSI components and segregate the non-ANSI stuff
into
> > GUI sections.  For most of the  code I write that is possible, however,
it
> > would still be nice to be able to use some VCL  components (non-visual
ones)
> > in an ANSI compliant manner --is this possible?

Other Threads