2010-04-14 11 views
7

Necesito un temporizador en un 'no forma' unidad de Delphi (que todavía hay una unidad principal con un formulario), así que hacer esto:Delphi: caso AlCronómetro de mi propio temporizador nunca sucede

unit ... 

interface 

type 
    TMyTimer = Class(TTimer) 
    public 
    procedure OnMyTimer(Sender: TObject); 
    end; 

var 
    MyTimer: TMyTimer; 

implementation 

procedure TMyTimer.OnMyTimer(Sender: TObject); 
begin 
    ... 
end; 

initialization 

MyTimer := TMyTimer.Create(nil); 
with MyTimer do 
begin 
    Interval := 1000; 
    Enabled := True; 
    OnTimer := OnMyTimer; 
end; 

finalization 

FreeAndNil(MyTimer); 

El problema es que el procedimiento OnMyTimer nunca se ejecuta. Voy a apreciar realmente alguna idea de por qué :-)

Respuesta

6

Aparte del hecho de que ha creado un MyTimer y liberaron a un MouseTimer, no veo nada malo en su código (yo supongo que utilice su código en una aplicación GUI o al menos están teniendo un bucle de mensajes)

este ejemplo de código funciona con Delphi 5. laHello World de escriba en el registro de eventos por segundo.

unit Unit2; 

interface 

uses 
    extctrls; 

type 
    TMyTimer = Class(TTimer) 
    public 
    procedure OnMyTimer(Sender: TObject); 
    end; 

var 
    MyTimer: TMyTimer; 

implementation 

uses 
    windows, sysutils, classes; 

procedure TMyTimer.OnMyTimer(Sender: TObject); 
begin 
    OutputDebugString(PChar('Hello World')); 
end; 

initialization 

MyTimer := TMyTimer.Create(nil); 
with MyTimer do 
begin 
    Interval := 1000; 
    Enabled := True; 
    OnTimer := OnMyTimer; 
end; 

finalization 
    FreeAndNil(MyTimer); 

end. 
+0

No sé por qué, pero lo hice funcionar reorganizando unidades en las secciones * uses * (ExtCtrls en la interfaz, SysUtils y Windows en implementación). Vaya a la figura :-) – Mikhail

+4

Mikhail, le aseguro que el orden de uso de las unidades no tuvo ningún efecto en el éxito de su programa. El problema estaba en otra parte. –

+0

Tengo que secundar eso. –

9

Para que un contador de tiempo para trabajar, su programa debe procesar los mensajes. En un programa GUI, esa parte es automática; la clase TApplication lo proporciona para usted. Pero usted dice que tiene un programa "sin forma", así que supongo que probablemente no esté llamando al Application.Run en su archivo DPR.

Para usar un temporizador, debe procesar los mensajes. El punto de partida típico para un suministro de mensajes es el código de la siguiente manera:

while Integer(GetMessage(Msg, 0, 0, 0)) > 0 do begin 
    TranslateMessage(Msg); 
    DispatchMessage(Msg); 
end; 

Cuando ha transcurrido el plazo de un temporizador, el sistema operativo coloca de manera efectiva un mensaje wm_Timer en la cola de mensajes de su programa. La llamada GetMessage obtiene mensajes de la cola y DispatchMessage llama al procedimiento de ventana de la ventana de destino. TTimer crea una ventana oculta para que sirva como destino para esos mensajes, y DispatchMessage se asegura de que lleguen allí.

+1

A menudo la creación de un bucle de mensajes solo para usar un temporizador me parece excesivo. Puede usar otro mecanismo que funcione mejor en hilos y objetos similares. Objeto WaitForSingle por ejemplo, etc ... – Runner

+0

Absolutamente. Pude haber profundizado sobre alternativas a TTimer, pero decidí limitar mi respuesta a la pregunta en cuestión. –

+0

Quise decir sin falta de respeto. Solo quería, si alguien lo lee, que lo saben. – Runner

1

¿Su unidad es utilizada por otras unidades o no? Si esta unidad no es utilizada por otros, ni siquiera entrará en la sección de inicialización. O tal vez la unidad se finalice antes de lo que piensas.

Poner un punto de interrupción en MyTimer: = TMyTimer.Create (nil); línea y en la línea FreeAndNil (MyTimer) y ejecute su aplicación. Asegúrese de que el temporizador se crea cuando lo desea y no se destruye demasiado pronto.

Cuestiones relacionadas