将事件分配给在运行时动态创建的VCL控件 [英] Assigning events to a VCL control created dynamically at runtime
问题描述
我正在尝试在运行时创建动态VCL控件,并为其分配事件处理程序。
我想我已经尽了一切努力使其正常工作。 ,但不能(我尝试的所有东西都会产生不同的错误)。
如果您可以在下面的代码中填写问号,那将会很有帮助! p>
哦,如果您想知道为什么它是在命名空间
而不是 class
,这是因为这实际上是我一直添加到的大型库。当我将其更改为类
时,您会认为这很好,但是,不会,它会产生大量的怪异错误。
test.h
命名空间TestSpace {
TTimer *时间;
AnsiString文件;
void __fastcall MyFunc(AnsiString f);
?OnTimer事件的声明?
}
test.cpp
void __fastcall TestSpace :: MyFunc(AnsiString f){
TestSpace :: file = f;
TestSpace :: time-> OnTimer =?;
TestSpace :: time-> Enabled = true;
}
TestSpace ::?(TObject * Sender){
TestSpace :: time-> Enabled = false;
DeleteFile(TestSpace :: file);
}
VCL事件处理程序是预期成为课程的非静态成员。您的 OnTimer
处理程序不是类成员,而是一个自由浮动的函数(名称空间并不重要)。
解决此问题的正确方法是为您的 OnTimer
事件处理程序创建一个类,然后将该实例与<$一起实例化。 c $ c> TTimer ,例如:
test.h
命名空间TestSpace {
class TimerEvents {
public:
void __fastcall TimerElapsed(TObject * Sender);
};
TTimer *时间;
TimerEvents time_events;
AnsiString文件;
void __fastcall MyFunc(AnsiString f);
}
test.cpp
void __fastcall TestSpace :: MyFunc(AnsiString f){
TestSpace :: file = f;
TestSpace :: time-> OnTimer =&(time_events.TimerElapsed);
TestSpace :: time-> Enabled = true;
}
void __fastcall TestSpace :: TimerEvents :: TimerElapsed(TObject * Sender){
//'这是TimerEvents对象
//'Sender'是TTimer对象
TestSpace :: time-> Enabled = false;
DeleteFile(TestSpace :: file);
}
话虽这么说,实际上还有一个替代通过使用 System :: TMethod
结构:
test.h
命名空间TestSpace {
TTimer * time;
AnsiString文件;
void __fastcall MyFunc(AnsiString f);
//注意:必须添加一个显式的void *参数才能接收
// //应该是一个类'this'指针...
void __fastcall TimerElapsed(void * This,TObject *发件人);
}
test.cpp
void __fastcall TestSpace :: MyFunc(AnsiString f){
TestSpace :: file = f;
TMethod m;
m.Data = ...; //无论您想传递给 This参数的任何内容,甚至为null ...
m.Code =& TestSpace :: TimerElapsed;
TestSpace :: time-> OnTimer = reinterpret_cast< TNotifyEvent&>(m);
TestSpace :: time-> Enabled = true;
}
void __fastcall TestSpace :: TimerElapsed(void * This,TObject * Sender){
//'这是您分配给TMethod :: Data $ b $的任何内容b //'发件人'是TTimer对象
TestSpace :: time-> Enabled = false;
DeleteFile(TestSpace :: file);
}
I'm trying to create a dynamic VCL control at runtime and assign an event handler to it.
I think I've tried everything to get this to work, but cannot (everything I try generates different errors).
If you could help fill in the question marks in the code below, it would be of great help!
Oh, in case you're wondering why it's in a namespace
instead of a class
, it's because this is actually a large library that I just kept adding to. When I change it to a class
, you'd think it would be fine, but no, it generates a gazillion weird errors.
test.h
namespace TestSpace {
TTimer *time;
AnsiString file;
void __fastcall MyFunc(AnsiString f);
?Declaration for OnTimer event?
}
test.cpp
void __fastcall TestSpace::MyFunc(AnsiString f) {
TestSpace::file = f;
TestSpace::time->OnTimer = ?;
TestSpace::time->Enabled = true;
}
TestSpace::?(TObject* Sender) {
TestSpace::time->Enabled = false;
DeleteFile(TestSpace::file);
}
A VCL event handler is expected to be a non-static member of a class. Your OnTimer
handler is not a class member, it is a free-floating function instead (the namespace is not important).
The correct way to solve this issue is to create a class for your OnTimer
event handler, and then instantiate that class alongside the TTimer
, eg:
test.h
namespace TestSpace {
class TimerEvents {
public:
void __fastcall TimerElapsed(TObject *Sender);
};
TTimer *time;
TimerEvents time_events;
AnsiString file;
void __fastcall MyFunc(AnsiString f);
}
test.cpp
void __fastcall TestSpace::MyFunc(AnsiString f) {
TestSpace::file = f;
TestSpace::time->OnTimer = &(time_events.TimerElapsed);
TestSpace::time->Enabled = true;
}
void __fastcall TestSpace::TimerEvents::TimerElapsed(TObject* Sender) {
// 'this' is the TimerEvents object
// 'Sender' is the TTimer object
TestSpace::time->Enabled = false;
DeleteFile(TestSpace::file);
}
That being said, there is actually an alternative way to use a free-floating function as a VCL event handler like you want, by using the System::TMethod
struct:
test.h
namespace TestSpace {
TTimer *time;
AnsiString file;
void __fastcall MyFunc(AnsiString f);
// NOTE: must add an explicit void* parameter to receive
// what is supposed to be a class 'this' pointer...
void __fastcall TimerElapsed(void *This, TObject *Sender);
}
test.cpp
void __fastcall TestSpace::MyFunc(AnsiString f) {
TestSpace::file = f;
TMethod m;
m.Data = ...; // whatever you want to pass to the 'This' parameter, even null...
m.Code = &TestSpace::TimerElapsed;
TestSpace::time->OnTimer = reinterpret_cast<TNotifyEvent&>(m);
TestSpace::time->Enabled = true;
}
void __fastcall TestSpace::TimerElapsed(void *This, TObject* Sender) {
// 'This' is whatever you assigned to TMethod::Data
// 'Sender' is the TTimer object
TestSpace::time->Enabled = false;
DeleteFile(TestSpace::file);
}
这篇关于将事件分配给在运行时动态创建的VCL控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!