Реализация нестандартных обработчиков событий
Кто-нибудь пробовал делать обработчики под BCB?
Код на паскале из документации:
{ TfsKeyPressEvent }
procedure TfsKeyPressEvent.DoEvent(Sender: TObject; var Key: Char);
begin
CallHandler([Sender, Key]);
Key := String(Handler.Params[1].Value)[1];
end;
function TfsKeyPressEvent.GetMethod: Pointer;
begin
Result := @TfsKeyPressEvent.DoEvent;
end;
Аналогичный код на C++:
template<class P0>
struct fs_notify< TYPELIST_1(P0) > : public TfsCustomEvent
{
enum {size=1};
__fastcall fs_notify(TObject* AObject,TfsProcVariable* AHandler) :
TfsCustomEvent(AObject,AHandler){}
void __fastcall DoEvent(P0 p0)
{
using namespace FunctionDispatch;
Variant v[size];
vartype <P0> v0;v0.to_variant(v[0],p0);
CallHandler(ARRAYOFCONST((v[0])));
}
virtual void* __fastcall GetMethod()
{
union
{
void __fastcall (__closure * f)(P0);
void* p;
} a;
a.f=DoEvent;
return a.p;
}
};
Если опустить шаблоны и сосредоточиться на GetMethod():
то видно что указатель DoEvent просто так не конвертиться в void*
Приходиться это делать через извраты:
union
{
void __fastcall (__closure * f)(P0);
void* p;
} a;
a.f=DoEvent;
return a.p;
К сожалению такой подход компилируется, но не работает
Падает в
procedure TfsEventHelper.SetValue(const Value: Variant)
{
...
SetMethodProp(Instance, p, m);
...
}
Что делать?
Код на паскале из документации:
{ TfsKeyPressEvent }
procedure TfsKeyPressEvent.DoEvent(Sender: TObject; var Key: Char);
begin
CallHandler([Sender, Key]);
Key := String(Handler.Params[1].Value)[1];
end;
function TfsKeyPressEvent.GetMethod: Pointer;
begin
Result := @TfsKeyPressEvent.DoEvent;
end;
Аналогичный код на C++:
template<class P0>
struct fs_notify< TYPELIST_1(P0) > : public TfsCustomEvent
{
enum {size=1};
__fastcall fs_notify(TObject* AObject,TfsProcVariable* AHandler) :
TfsCustomEvent(AObject,AHandler){}
void __fastcall DoEvent(P0 p0)
{
using namespace FunctionDispatch;
Variant v[size];
vartype <P0> v0;v0.to_variant(v[0],p0);
CallHandler(ARRAYOFCONST((v[0])));
}
virtual void* __fastcall GetMethod()
{
union
{
void __fastcall (__closure * f)(P0);
void* p;
} a;
a.f=DoEvent;
return a.p;
}
};
Если опустить шаблоны и сосредоточиться на GetMethod():
то видно что указатель DoEvent просто так не конвертиться в void*
Приходиться это делать через извраты:
union
{
void __fastcall (__closure * f)(P0);
void* p;
} a;
a.f=DoEvent;
return a.p;
К сожалению такой подход компилируется, но не работает
Падает в
procedure TfsEventHelper.SetValue(const Value: Variant)
{
...
SetMethodProp(Instance, p, m);
...
}
Что делать?
Комментарии
Я не объявил событие как __property
Я пробовал несколько иначе , тоже компилится но в скрипте возникает сообщение
Pure virtual function call , после чего программа закрывается.
Вот мой код:
class TfsOnGetContentStyle : TfsCustomEvent
{
public:
void __fastcall DoEvent(TObject *Sender, TObject *AItem, TcxTreeListNode *ANode, TcxStyle *&AStyle);
HIDESBASE void* GetMethod();
};
void __fastcall TfsOnGetContentStyle::DoEvent(TObject *Sender, TObject *AItem, TcxTreeListNode *ANode, TcxStyle *&AStyle)
{
CallHandler(OPENARRAY(TVarRec,(Sender,AItem,ANode,AStyle)));
AItem = (TObject*)(int)Handler->Params[1]->Value;
ANode = (TcxTreeListNode *)(int)Handler->Params[2]->Value;
AStyle = (TcxStyle *)(int)Handler->Params[2]->Value;
}
//
void* TfsOnGetContentStyle::GetMethod()
{
typedef void (__fastcall TfsOnGetContentStyle::*PFUNC)(TObject *Sender, TObject *AItem, TcxTreeListNode *ANode, TcxStyle *&AStyle);
PFUNC pFunc = &TfsOnGetContentStyle::DoEvent;
return (void*)&pFunc;
}
//