Вызов метода компонента
TTimer *ttt=new TTimer(this);
ttt->Interval=1000;
ttt->Enabled=true;
Как теперь вызвать метод OnTimer?
void __fastcall TForm1::tttOnTimer(TObject *Sender)
{
ShowMessage("ontimer");
}
это не работает.
Помогайте.
Цитата: docjohn
Создаю новый экземпляр таймера:
TTimer *ttt=new TTimer(this);
ttt->Interval=1000;
ttt->Enabled=true;
Как теперь вызвать метод OnTimer?
void __fastcall TForm1::tttOnTimer(TObject *Sender)
{
ShowMessage("ontimer");
}
это не работает.
Помогайте.
TTimer *ttt=new TTimer(this);
ttt->Interval=1000;
ttt->Enabled=true;
Как теперь вызвать метод OnTimer?
void __fastcall TForm1::tttOnTimer(TObject *Sender)
{
ShowMessage("ontimer");
}
это не работает.
Помогайте.
Код:
ttt->onTimer=tttOnTimer;
ttt->OnTimer = this->tttOnTimer;
И ещё, метод-обработчик может называться по любому, а не только tttOnTimer. Главное - чтобы результат, способ вызова и список параметров совпадал - в данном случае __fastcall метод получает указатель на TObject и возвращает void
"Стандартные" названия типа Button1Click назначаются визуальным редактором формы для удобства чтения кода и всегда могут быть переименованы, а создание метода с "соответствующим" именем "ручками" автоматически назначение не произведёт.
А вообще "событие" (свойство объекта с именем OnЧтото) - это "указатель на метод конкретного объекта", реализованный в виде структуры (размер 8 байт) из двух неименованных полей: Адрес_Объекта и Адрес_Метода_Класса
class TMyThread : public TThread
{
private:
protected:
void __fastcall Execute();
public:
TTimer *ttt;
};
при его вызове создавать каждый раз новый таймер:
void __fastcall TMyThread::Execute()
{
.................
ttt=new TTimer(this);
.................
}
Но TTimer не виден из этого метода.
Выдается ошибка: E2285 Could not find a match for ‘argument(s)’.
Что не так?
Код:
class TMyThread : public TThread
{
private:
TTimer *FTimer;
protected:
void __fastcall Execute();
public:
__published:
__property TTimer *Timer = {read = FTimer};
};
{
private:
TTimer *FTimer;
protected:
void __fastcall Execute();
public:
__published:
__property TTimer *Timer = {read = FTimer};
};
Теперь поле класса доступно только для чтения и его (адрес объекта) нельзя будет изменить извне (случайно, например)
Цитата:
Выдается ошибка: E2285 Could not find a match for ‘argument(s)’.
Что не так?
Что не так?
Дело в том, что конструктор объекта TTimer требует указатель на объект типа TComponent, но используемый здесь TThread не является производным от оного.
Таким образом, создаём таймер без "владельца" (FTimer = new TTimer (NULL)). Но теперь, во избежание утечек памяти, нужно написать метод (например, Deactivate), который будет удалять объект таймера перед созданием нового.
P.S.
Обычно компоненты VCL (производные от TComponent) удаляются автоматически своим "владельцем" - объектом, адрес которого передаётся параметром конструктора. В данном примере параметр Owner будет равен NULL.
class TMyThread : public TThread
{
private:
TTimer *ttt;
protected:
void __fastcall Execute();
public:
__fastcall TMyThread(bool CreateSuspended);
__published:
void __fastcall tttTimer(TObject *Sender);
__property TTimer *Timer = {read = ttt};
};
В методе Execute потока создаем таймер и вызваем метод OnTimer:
void __fastcall TMyThread::Execute()
{
FreeOnTerminate = true;
ttt=new TTimer(NULL);
ttt->Interval=5000;
ttt->Enabled=true;
ttt->onTimer=tttTimer;
}
Обработчик OnTimer:
void __fastcall TMyThread::tttTimer(TObject *Sender)
{
ShowMessage("thread started");
}
А в ответ тишина.
Ошибки нет, но обработчик tttTimer не вызывается.
Не пойму где ошибка.
"САМОЛИКВИДАЦИЯ ПОСЛЕ ЗАВЕРШЕНИЯ ВЫПОЛНЕНИЯ Execute()"
Метод ТАЙМЕРА - это метод объекта TMyThread, который "САМОЛИКВИДИРОВАЛСЯ" ;)
Объясни, для чего такой хитроумный код с потоками и таймерами?
У меня вопрос не о потоках. Поток создается и работает.
У меня проблема с созданием экземпляра объекта и вызовом метода объекта при запуске потока.
В качестве примера я выбрал объект TTimer.
Метод ТАЙМЕРА - это метод объекта потока TMyThread, который "САМОЛИКВИДИРОВАЛСЯ"
Попробуй не удалять поток ( FreeOnTerminate = false ) и всё заработает!
Далее, поговорим о таймере:
1) сначала инициализируй метод таймера, а затем разрешай его выполнение.
Код:
ttt->onTimer=tttTimer;
ttt->Enabled=true;
ttt->Enabled=true;
А если справку внимательно прочитаешь: Enabled по умолчанию true. ;)
2) Для таймера указан интервал 5 секунд. Нет гарантий, что метод таймера
будет запущен сразу после разрешения, т.е. после ttt->Enabled=true;
А через 5 секунд - уже как 5 секунд не существует объекта TMyThread и
обработчика таймера!