Текущий архив: 2005.07.11;
Скачать: CL | DM;
Внизне срабатывает таймер Найти похожие ветки
← →
RagE © (2004-07-07 15:13) [0]Добрый день. Пишу свой компонент со встроенным таймером. Задача такая, нужно поставить на событие таймера процедуру моего компонента. В дебаггере смотрю FTimer.OnTimer присваивается адрес процедуры но событие не срабатывает.
Привожу полный текст модуля.
// Клиент на основе TClientSocket с проверкой получения данных и ведения истории в базе данных
unit DBClientSocket;
interface
uses
SysUtils, Classes, ScktComp, ExtCtrls, Protocol;
type
TDBClientSocket = class(TClientSocket)
private
FTimeOut:integer; // Время ожидания подтверждения
FTimer:TTimer;
FTimeIsOut:boolean; // Сигнализирует о завершении времени на таймаут
FDataReceived:boolean; // Сигнализирует об успешном получении данных
FTimeIsOutOnTimer:TNotifyEvent;
procedure TimeIsOutOnTimer(Sender:TObject);
// Установка свойств
procedure SetTimeOut (const Value: integer);
procedure SetTimer (const Value: TTimer);
protected
function Waiting:TSendResult;
public
constructor Create(AOwner:TComponent);override;
function SendTextAndWait(Text:string):TSendResult;virtual; // Отсылает данные и ждет подтверждения
published
property TimeOut:integer read FTimeOut write SetTimeOut;
property Timer:TTimer read FTimer write SetTimer;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents("My", [TDBClientSocket]);
end;
// Конструктор
constructor TDBClientSocket.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FTimer := TTimer.Create(Self);
FTimer.Name:="Timer1";
FTimer.Enabled := False;
FTimeIsOutOnTimer:=TimeIsOutOnTimer;
end;
// Сигнал о том что время вышло
procedure TDBClientSocket.TimeIsOutOnTimer(Sender:TObject);
begin
FTimeIsOut:=true;
end;
// Функция ожидания
function TDBClientSocket.Waiting:TSendResult;
begin
// Устанавливаем таймер
if FTimer=nil then
begin
Result:=srWithoutWait;
Exit;
end;
FTimer.Interval:=FTimeOut;
FTimeIsOut:=false;
FTimer.OnTimer:=FTimeIsOutOnTimer;
FTimer.Enabled:=true;
// FDataReceived:=true;
// Ждем подтверждения или окончания таймаута
while (not FTimeIsOut) and (not FDataReceived) do
begin { TODO : Сделать ожидание таймаута }
end;
// Определяем результат и останавливаем таймер
if FDataReceived then Result:=srOk;
if FTimeIsOut then Result:=srTimeOut;
FTimer.Enabled:=false;
end;
// Отсылка данных с ожиданием подтверждения
function TDBClientSocket.SendTextAndWait(Text:string):TSendResult;
begin
// Посылаем текcт
Socket.SendText(Text);
Result:=Waiting;
end;
// Установка свойств --------------------------
procedure TDBClientSocket.SetTimeOut (const Value: integer);
begin
FTimeOut:=Value;
end;
procedure TDBClientSocket.SetTimer (const Value: TTimer);
begin
// if Value<>nil then
// FTimer.Assign(Value);
end;
end.
← →
MBo © (2004-07-07 15:19) [1]Неплохо было бы просмотреть этот форум чуть ниже.
← →
RagE © (2004-07-07 15:35) [2]Дело в том что смотрел. Не работает. В том случае там событие на таймер задается как property. В моем случае нужно чтобы оно было определено в компоненте и пользователь не догадывался даже о таком.
← →
MBo © (2004-07-07 15:50) [3]событие таймера связано НЕ с методом TimeIsOutOnTimer, а с переменной FTimeIsOutOnTimer, которая, собственно говоря, никуда не указывает.
Кроме того, настораживает, мягко говоря, метод ожидания.
← →
RagE © (2004-07-07 15:59) [4][3]
FTimeIsOutOnTimer:=TimeIsOutOnTimer;
Пробовал и FTimer.OnTime:=TimeIsOutOnTimer;
Метод ожидания такой что когда сработает таймер переменная YimeIsOut установитя в true и цикл прекратится. Вобщем то здесь он не важен. Все равно он будет не такой. Мне важно чтобы событие таймера срабатывало.
И такой еще вопрос возможно ли прямо в компоненте на событие OnRead установить свою процедуру опять же из компонента. Чтобы когда прийдут данные вызвался не событие пользователя а мое, которое уже потом и будет вызывать событие пользователя?
← →
MBo © (2004-07-08 07:06) [5]> такой еще вопрос возможно ли прямо в компоненте на событие OnRead установить свою процедуру опять же из компонента. Чтобы когда прийдут данные вызвался не событие пользователя а мое, которое уже потом и будет вызывать событие пользователя?
Так обычно и делается - в нужном месте вызывается (обычно динамический) метод, в котором делается нужная работа, и выполняется
if Assigned(FOnSomeEvent) then
FOnSomeEvent(Self[,ParamList]);
А вообще рекомендую скачать компонент CPort Dejan Crnila. Он для работы с компортом (с сокетами я просто не работал и не знаю, что посоветовать) и разобраться в логике работы - там сделано весьма грамотно.
← →
RagE © (2004-07-08 09:40) [6]Ты меня не так понял. Про
if Assigned(FOnSomeEvent) then
FOnSomeEvent(Self[,ParamList]);
я знаю. Мне вот что нужно. У класса есть событие OnRead. мне нужно что то типа того что Class.OnRead:=Class.MyEvent;
Вобщем то пока я это дело сделал путем изменения исходника компонента
← →
RagE © (2004-07-08 09:41) [7]Ну вобщем то о главном. Таймер то не работает.
← →
RagE © (2004-07-08 11:25) [8]Все вопрос закрыт. Для тех кому интересен ответ: в цикле нужно вставлять ProcessMessages
← →
MBo © (2004-07-08 12:18) [9]>RagE © (08.07.04 11:25) [8]
>ответ: в цикле нужно вставлять ProcessMessages
>MBo © (07.07.04 15:50) [3]
>Кроме того, настораживает, мягко говоря, метод ожидания.
Я не просто так ведь это написал - у тебя получается, что главный поток приложения, в котором крутится этот цикл, бесполезно кушает ресурсы процессора. ProcessMessages "оживляет" систему, но всех проблем не решает.
А вот в рекомендованном компоненте, например, запускается дополнительный поток с использованием Wait-функций - он спит себе, пока не случится событие, и никому не мешает.
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.045 c