Как в консольном приложении получать события от Timer?
В консольном приложении, создаю объект, в котором есть Timer. Но его событие OnTimer не срабатывает и я ни как не пойму, почему?
Project2:
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, Unit1 in 'Unit1.pas';
var
MyObject: TMyObject;
begin
MyObject := TMyObject.Create;
Readln;
FreeAndNil(MyObject);
end.
Unit1:
unit Unit1;
interface
uses
System.SysUtils, System.Classes, FMX.Types;
type
TMyObject = class
protected
FTimer: TTimer; // class(TFmxObject)
procedure OnTimer(Sender: TObject);
public
constructor Create();
destructor Destroy; override;
end;
implementation
constructor TMyObject.Create();
begin
inherited Create;
Self.FTimer := TTimer.Create(nil);
Self.FTimer.Interval := 1000;
Self.FTimer.OnTimer := OnTimer;
Self.FTimer.Enabled := True;
end;
procedure TMyObject.OnTimer(Sender: TObject);
begin
writeln(DateTimeToStr(Now));
end;
destructor TMyObject.Destroy;
begin
Self.FTimer.Enabled := False;
FreeAndNil(Self.FTimer);
inherited;
end;
Ответы (2 шт):
Автор решения: MBo
→ Ссылка
TTimer работает с использованием сообщения WM_TIMER, которое отправляется в очередь сообщений. А этой очереди у консольного приложения нет. Выход - создать очередь сообщений, запустив цикл выборки и диспетчеризации сообщений. Вариант - использовать свою реализацию таймера, работающую в дополнительном потоке (например, на основе WaitableTimer или просто WaitForMultipleObjects)
Примерно так: (не проверял, мог что-то упустить)
procedure MakeMsgQueue; //вызвать после запуска таймера
var
Msg: TMsg;
begin
while GetMessage(Msg, 0, 0, 0) do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
Автор решения: Lem0nti
→ Ссылка
Ещё вариант - мультимедиа таймер:
uses
...MMSystem...
...
mmResult: MMRESULT;
...
//обработчик таймера
procedure TimeCallBack(TimerID, Msg: Uint; dwUser, dw1, dw2: DWORD); pascal;
begin
//параметр dw2 будет содержать тот хендл, который выдался при выполнении timeSetEvent
end;
...
mmResult:=timeSetEvent(8000,0,@TimeCallBack,0,TIME_PERIODIC); //создание таймера
...
timeKillEvent(mmResult); //удаление таймера