Recent

Author Topic: TTimer in class does not trigger OnTimer event, why?  (Read 1100 times)

alpine

  • Hero Member
  • *****
  • Posts: 1263
Re: TTimer in class does not trigger OnTimer event, why?
« Reply #15 on: September 06, 2024, 02:45:42 pm »
Here is the call sequence when enabling a TTimer:

TCustomTimer.SetEnabled: https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/lcl/customtimer.pas?ref_type=heads#L196
TCustomTimer.UpdateTimer: https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/lcl/customtimer.pas?ref_type=heads#L131
TWin32WidgetSet.CreateTimer: https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/lcl/interfaces/win32/win32object.inc?ref_type=heads#L627
Code: Pascal  [Select][+][-]
  1. TimerInfo^.TimerID := Win32Extra.SetTimer(0, 0, Interval, @TimerCallBackProc);
Win32Extra.SetTimer: https://gitlab.com/freepascal.org/lazarus/lazarus/-/blob/main/lcl/interfaces/win32/win32extra.pas?ref_type=heads#L238
Code: Pascal  [Select][+][-]
  1. function SetTimer(hWnd:HWND; nIDEvent:UINT_PTR; uElapse:UINT; lpTimerFunc: TIMERPROC): UINT_PTR; stdcall; external 'user32' name 'SetTimer';

Obviously the winuser.h SetTimer function is called with hWnd=0. What happens in that case is written in the Remarks of https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer

The fact that it is the one of the two possible ways to handle a WM_TIMER is another question. In that particular case (LCL+Win) the parent window (handle) is completely irrelevant.

BTW the Owner parameter of the constructor is just a TComponent mechanism for auto destruction of the "owned" components, i.e. a MM feature and has nothing to do with the message handling. You are probably confusing it with the Parent property.

And it is noted earlier by Martin in his reply #9 above.

EDIT:
Because customtimer.pas is from the common part of the LCL, and it calls the abstract WidgetSet.CreateTimer(), which in turn have just two parameters: Interval and TimerFunc, it is clear that no other parameters (Owner, Parent, Handle, whatever) are used in any other widgetset.
« Last Edit: September 06, 2024, 03:16:30 pm by alpine »
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1408
    • Lebeau Software
Re: TTimer in class does not trigger OnTimer event, why?
« Reply #16 on: September 06, 2024, 06:21:37 pm »
In Window$ timers were created with a specified callback and thus they don't need a hWnd at all.

While it is true that a timer can use a callback instead of a window, however both approaches still require the owning thread to have a message queue and dispatch messages.  A WM_TIMER message is always generated when the timer elapses, but if there is no window associated with the timer then dispatching the message with DispatchMessage() will invoke the callback.

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-settimer

Quote
An application can process WM_TIMER messages by including a WM_TIMER case statement in the window procedure or by specifying a TimerProc callback function when creating the timer. When you specify a TimerProc callback function, the DispatchMessage calls the callback function instead of calling the window procedure when it processes WM_TIMER with a non-NULL lParam. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

alpine

  • Hero Member
  • *****
  • Posts: 1263
Re: TTimer in class does not trigger OnTimer event, why?
« Reply #17 on: September 06, 2024, 09:58:54 pm »
In Window$ timers were created with a specified callback and thus they don't need a hWnd at all.

While it is true that a timer can use a callback instead of a window, however both approaches still require the owning thread to have a message queue and dispatch messages.  A WM_TIMER message is always generated when the timer elapses, but if there is no window associated with the timer then dispatching the message with DispatchMessage() will invoke the callback.
Did I claim anything different?
  • In a Win GUI App DispatchMessage() will be invoked by TApplication.ProcessMessages --> WidgetSet.AppProcessMessages
  • A TTimer doesn't need an Owner in order to work
  • There is no hidden window for receiving timer messages

I have already listed the call path for user32 SetTimer, it is always called with hWnd=0. The params that reach that call are only the interval and the callback. Of course there is a list of TWin32Timerinfo's but they hold only a timer ID and a procedure of object.

I don't know what the subject of the dispute is, it's all written in the code.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

PascalDragon

  • Hero Member
  • *****
  • Posts: 5672
  • Compiler Developer
Re: TTimer in class does not trigger OnTimer event, why?
« Reply #18 on: September 15, 2024, 09:33:05 pm »
start with unit classe.blinklabel; that is delphi code, not fpc.(yet)

Dotted unit names are supported since 3.0.0 already.

 

TinyPortal © 2005-2018