Ir para conteúdo
Fórum Script Brasil
  • 0

Evento Ontimer


kmkg

Pergunta

Posts Recomendados

  • 0

Estranho. Na documentação do windows que vem junto com o arquivo de ajuda do Delphi 2006 existe exatamente essa mesma página com todos os dados iguais, a única diferença é que diz que está presente desde o windows 95. Estranho.

Remarks

Each call to timeSetEvent for periodic timer events requires a corresponding call to the timeKillEvent function.

Creating an event with the TIME_KILL_SYNCHRONOUS and the TIME_CALLBACK_FUNCTION flag prevents the event from occurring after the timeKillEvent function is called.

Requirements

Windows NT/2000/XP: Included in Windows NT 3.1 and later.

Windows 95/98/Me: Included in Windows 95 and later.

Header: Declared in Mmsystem.h; include Windows.h.

Library: Use Winmm.lib.

Link para o comentário
Compartilhar em outros sites

  • 0
No Windows 2000 eu posso testar - caso algum de vocês não possam - e segunda-feira eu posto o resultado.
Confirmado - funciona.

A título de ilustração, vou colocar o código do teste aqui:

unit Unit1;
interface
uses
  Mmsystem,  // *** Inclusão necessária
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Counter :LongInt;
    timerHnd :THandle;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}
// *** aqui a callback que será chamada a cada 2 segundos (2000 milisegundos)
procedure TimerProc(uTimerID, uMsg :UINT; dwUser, dw1, dw2 :PDWORD); stdcall;
begin
  Form1.Memo1.Lines.Add('Timer '+IntToStr(Integer(dwUser^)));
  Inc(dwUser^);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled := False;
  Counter := 1;
  timerHnd := timeSetEvent(2000, 0, @TimerProc, LongInt(@Counter), TIME_PERIODIC);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if timerHnd > 0 then
    timeKillEvent(timerHnd);
end;

end.

Observar que o Help define que o parâmetro do usuário (dwUser) deve ser do tipo DWORD(e o compilador exige), entretanto, a procedure (callback) dever declarar este parâmetro do usuário como sendo um PDWORD (ver link). :blink:

Assim, para o exemplo que fiz, alterar o conteúdo do parâmetro recebido pela callback, fez-se necessário a inclusão do type-cast do endereço de Counter (convertendo para um LongInt/DWORD). Apenas deste modo a alteração de Counter na callback será mantido fora dela.

É verdade, o ProcessMessages quando é chamado dentro do procedimento de um evento, e já tiver uma mensagem pra rodar aquele mesmo procedimento na fila, pode causar uma recursão e muita dor de cabeça, falo por experiencia própria porque já me deparei com esse problema e a solução foi executar a operação em outra thread.
(do post) Thales, agora lendo os posts que não havia lido, apenas a título de ampliarmos nossos horizontes, acho que na citação acima o termo recursão não é bem adequado, já que o que poderá ocorrer é o processo(se muito demorado) ser interrompido no meio de sua execução para que um novo evento do timer seja processado e chame novamente o procedimento - que não havia sido concluído ainda. Isto porque a definição de recursão implica que um procedimento chame a si mesmo(wikipédia) - que não é o caso. Preempção é mais ou menos o que ocorre (wikipédia), quando o sistema operacional interrompe um processo para executar outro de maior prioridade (p.e evento do timer). Se alguém tiver algum comentário, manda brasa... ;)

[]s

Link para o comentário
Compartilhar em outros sites

  • 0
Thales, agora lendo os posts que não havia lido, apenas a título de ampliarmos nossos horizontes, acho que na citação acima o termo recursão não é bem adequado, já que o que poderá ocorrer é o processo(se muito demorado) ser interrompido no meio de sua execução para que um novo evento do timer seja processado e chame novamente o procedimento - que não havia sido concluído ainda. Isto porque a definição de recursão implica que um procedimento chame a si mesmo(wikipédia) - que não é o caso. Preempção é mais ou menos o que ocorre (wikipédia), quando o sistema operacional interrompe um processo para executar outro de maior prioridade (p.e evento do timer). Se alguém tiver algum comentário, manda brasa...

Quando escreví aquele comentário não me referia ao evento OnTimer, mas sim ao evento de um botão. E nesse procedimento não é chamado ele próprio mais é chamado um outro(ProccesMessages) que por sua vez o chama. Ou seja, o efeito é exatamente o mesmo que o de uma recursão. Exatamente. Falo isso porque eu estava lá, eu ví o que acontece.

Link para o comentário
Compartilhar em outros sites

  • 0

Ainda assim tenho lá minhas dúvidas. Se o msdn disse que só estava no XP, talvez no 2000 foi implementado em algum SP; parece-me que o 2000 está no SP4, talvez o do Micheus esteja também e pode ser que os 2000 desatualizados não tenham essa função na dll.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...