Can C ++ templates play well with VCL classes?

I am trying to use the C ++ Template 'mixins' to create new VCL components with common additional functionality. Example...

template <class T> class Mixin : public T
{
private:
  typedef T inherited;

// ...additional methods

public:
  Mixin(TComponent *owner) : inherited(owner)
  {
  // .. do stuff here
  };
};

Used as follows:

class MyLabel : public Mixin<TLabel>
{
  ....
}

class MyEdit : public Mixin<TEdit>
{
  ....
}

Now everything compiles fine, and mixin stuff works until I try to save the component to the stream using TStream-> WriteComponent, where the inherited properties (for example, TLabel.Width / Height / etc.) Do not allow, write t. This is even with "zero" mixing, as shown above.

My code works fine when it simply outputs classes directly from TForm, TEdit, etc. - and the class is correctly registered in the streaming system.

+3
1

/ : no; . , , , , . , . .

Delphi. , :

void testing()
{
  __classid(Mixin<Stdctrls::TLabel>); // Error Here
}

...

" E2242 test.cpp 53: __classid Delphi ( , __declspec (delphiclass) System:: TObject) ()"

, / Delphi- [. , TObject]. , , delphi- . , delphi-style, . , , . , :

void testing()
{
  typedef Mixin<Stdctrls::TLabel> __ttype;
  std::auto_ptr<__ttype> c2(new __ttype(0));
  __classid(Mixin<Stdctrls::TLabel>); // No more errors here
}

__declspec (delphiclass) , :

template <class T> 
class __declspec(delphiclass) Mixin : public T {
private:
  int i;
  typedef T inherited;
public:
  __fastcall Mixin(TComponent *owner) : inherited(owner) {};
};

, , delphi- , , , , : Delphi TTypeData.PropCount - http://docwiki.embarcadero.com/VCL/en/TypInfo.TTypeData - , . - , , "0" : (

, PropCount, :

#include <Stdctrls.hpp>
#include <cstdio>
#include <memory>
#include <utilcls.h>

class TCppComp : public Classes::TComponent {
  int i;
public:
  __fastcall TCppComp(TComponent* owner): Classes::TComponent(owner) {};
__published:
  __property int AAAA = {read=i, write=i};
};

template <class T> 
class __declspec(delphiclass) Mixin : public T {
private:
  int i;
  typedef T inherited;
public:
  __fastcall Mixin(TComponent *owner) : inherited(owner) {};
};

typedef Mixin<TCppComp> TMixinComp;

void showProps(TClass meta) {
  PTypeInfo pInfo = PTypeInfo(meta->ClassInfo());
  int Count = GetPropList(pInfo, tkAny, NULL);
  TAPtr<PPropInfo> List(new PPropInfo[Count]);
  std::printf("Class: %s - Total Props:%d\n", 
                   AnsiString(pInfo->Name).c_str(), Count);  
  GetPropList(pInfo, tkAny, *(reinterpret_cast<PPropList*>(&List)));
  for (int i = 0; i < Count; i++) {
    AnsiString propName(List[i]->Name);
    std::printf("\t%s\n", propName.c_str());
  }
}

void test() {
  showProps(__classid(TCppComp));
  showProps(__classid(TMixinComp));
}

int main() {
  test();
  return 0;
}

:

  Class: TCppComp - Total Props:3
    AAAA
    Name
    Tag
  Class: @%Mixin$8TCppComp% - Total Props:0

IOW, Mixin "0", 3: (

, .

, _TEXT, DEP.

, PropCount, , . , , QC : , , , , , .

,

PS: , Mixin , ; , .

+8

Source: https://habr.com/ru/post/1781326/


All Articles