Queued Timer: Without Wrapper [Direct Way] lazarus / 34-Windows ---------------------------------------------------------------------- RAW · 2016-10-17 01:54 Is this the correct way of using a Queued Timer? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // EDIT:// not working stable... [SIGFPE, EXTERNAL ERROR, SIGSEGV]  At first it worked only with $Mode Delphi, but then I changed the OnTimer-Procedure to (Timer1: Pointer....) and now it's working with $Mode OBJFPC. At first I tried to close the THandle, but then I got an External Exception Error. So I deleted that line of code. Obviously a Queued Timer isn't a "SCROLLER"... it looks like a car- accident and my CPU-Usage was 13%... Maybe he's good for something else...  EDIT 2: This works well in D7 and the CPU-Usage is between 4 and 6 % (TaskManager)... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Unit Unit1; Interface USES  Windows, Classes, SysUtils, Forms, Controls, Graphics, StdCtrls;  TYPE  TForm1 = Class(TForm)    Procedure FormCreate (Sender: TObject);   Procedure FormClose  (Sender: TObject;  Var CloseAction: TCloseAction);     PRIVATE     hTimer: THandle;     labTXT: TLabel;  End;  TYPE  TimerCallback = Procedure(Param: Pointer; TimerOrWait: BOOL); StdCall;    Function CreateTimerQueueTimer(            Var Timer: THandle;            Queue    : THandle;            Callback : TimerCallback;            Param    : Pointer;            msStart  : LongWord;            msRestart: LongWord;            Flags    : LongWord): BOOL; StdCall;           External Kernel32 Name 'CreateTimerQueueTimer';   Function DeleteTimerQueueTimer(            Queue: THandle;            Timer: THandle;            Event: THandle): BOOL; StdCall;           External Kernel32 Name 'DeleteTimerQueueTimer';  VAR  Form1: TForm1; Implementation {$R *.dfm}  Procedure OnTimer(Param: Pointer; TimerOrWait: BOOL); StdCall; Begin  If Form1.labTXT.Left  <= -Form1.labTXT.Width  Then Form1.labTXT.Left:= Form1.Width;   Form1.labTXT.Left:= Form1.labTXT.Left -1; End;  Procedure TForm1.FormCreate(Sender: TObject); Begin  Color         := clBlack;  BorderStyle   := bsNone;  DoubleBuffered:= True;   labTXT             := TLabel.Create(Self);  labTXT.Color       := clBlack;  labTXT.Font.Color  := clLime;  labTXT.Font.Size   := Screen.Width Div 10;  labTXT.AutoSize    := True;  labTXT.Parent      := Self;  labTXT.Caption     := 'SCROLLING SOME TEXT...';  labTXT.SetBounds      (((Self.Width-labTXT.Width) Div 2),                         ((Self.Height-labTXT.Height) Div 2),                           labTXT.Width, labTXT.Height);   SetBounds(0, 0, Screen.Width, (Screen.Height Div 2));   If Not CreateTimerQueueTimer(hTimer, 0, @OnTimer, Nil, 0, 8, 0)  Then hTimer:= 0; End;  Procedure TForm1.FormClose(Sender: TObject; Var CloseAction: TCloseAction); Begin  DeleteTimerQueueTimer(0, hTimer, 0);    If   hTimer<> 0   Then hTimer:= 0; End; End. ---------------------------------------------------------------------- Thaddy · 2016-10-17 03:55 In this very simple c++ example I see that an explicit event is used: https://msdn.microsoft.com/en- us/library/windows/desktop/ms687003(v=vs.85).aspx ---------------------------------------------------------------------- shobits1 · 2016-10-17 15:24 Why not just use TTimer?? (just asking!) ---------------------------------------------------------------------- Thaddy · 2016-10-17 15:38 TWIMC, After I replaced the curly brackets with proper begin end, replaced the " into proper ' ,defined a macro for printf to mean writeln (and one that ignores \n), replaced :=:= with = because i Replaced = with := first, and put the variables in the right place and order...in the msdn example, (Why do C programmers write such sloppy Pascal?) I can confirm that the event is essential.... ---------------------------------------------------------------------- RAW · 2016-10-17 17:51 void CTimersDlg::OnButtonBegin() {    .    .    .     // create the timer    BOOL success = ::CreateTimerQueueTimer(       &m_timerHandle,       NULL,       TimerProc,       this,       0,       elTime,       WT_EXECUTEINTIMERTHREAD); } void CTimersDlg::OnButtonStop() {     // destroy the timer    DeleteTimerQueueTimer(NULL, m_timerHandle, NULL);    CloseHandle (m_timerHandle); } void CTimersDlg::QueueTimerHandler() // called every elTime milliseconds { // do what you want to do, but quickly    .    .    . } void CALLBACK TimerProc(void* lpParametar,                                     BOOLEAN TimerOrWaitFired)     {     // This is used only to call QueueTimerHandler     // Typically, this function is static member of CTimersDlg     CTimersDlg* obj = (CTimersDlg*) lpParametar;     obj->QueueTimerHandler();     } I wanted to do this, but I don't get it running.... need to try it again tomorrow.. At first it's running and after some seconds everything is going bye bye... @Thaddy: Thanks ... The example creates his own TimerQueue, that's interesting and probably a nice idea when using a lot more than one Timer. @shobits1: Because the QueuedTimer is running in his own thread and can be set to 1 ms or 2 ms. The QueuedTimer uses not much resources and is much more precise than a TTimer, especially when the CPU-LOAD increases. ---------------------------------------------------------------------- ASerge · 2016-10-17 18:53 Quote from: SoE on October 17, 2016, 07:51:18 pmBecause the QueuedTimer is running in his own thread and can be set to 1 ms or 2 ms. The QueuedTimer uses not much resources and is much more precise than a TTimer, especially when the CPU-LOAD increases. That's why it's a bad idea to use QueueTimer in the UI: 1. Perform synchronization is necessary because the GUI is not intended for drawing from another thread. For example, use PostMessage to handle in a window procedure. 2. To the user one or two milliseconds is too fast to notice. 3. Resources used are clearly more than the usual TTimer. At least one thread. ---------------------------------------------------------------------- RAW · 2016-10-17 22:30 QuoteThat's why it's a bad idea to use QueueTimer in the UI:... It's working very well in D7 so why should it be a problem with LAZARUS? I don't believe that this timer was developed for NON-GUI only. QuoteTo the user one or two milliseconds is too fast to notice. Sure..., but what about MIDI-Software and Music-Software in general ??? Don't tell me they use a normal TTimer for those tasks. There must be a reason for the multimedia timer.... right?!! And I can see it very well when scrolling one or two simple TLabels. When I set the multimedia timer to DELAY: 17 and RESOLUTION: 1, then it really looks good for a Non-OpenGL-Solution! [1 Pixel Scrolling]. My MMTimer-Wrapper runs right now only in $MODE DELPHI, but it's running very nice without problems. In the moment I can't see why the QueuedTimer is doing such a @§%&@€... but I will find out... QuoteResources used are clearly more than the usual TTimer. At least one thread. That's not much for a good timer... The TTimer is a dead timer when it comes to high cpu-loads. What good is a timer that isn't alive when the program needs him. ---------------------------------------------------------------------- RAW · 2016-10-17 23:23 QuoteI can confirm that the event is essential.... I know nothing about C++ code but for me it looks like the only reason for the event is the main program loop... similar to a LPR-program or a console-app. Maybe I can do it the same way... I'll try... ---------------------------------------------------------------------- ASerge · 2016-10-18 23:37 Quote from: SoE on October 18, 2016, 12:30:48 amIt's working very well in D7 so why should it be a problem with LAZARUS? No matter D7 or Lazarus. Works until the error was evident . See http://forum.lazarus.freepascal.org/index.php/topic,33597.0.html for example. QuoteSure..., but what about MIDI-Software and Music-Software in general ??? Don't tell me they use a normal TTimer for those tasks. Common tasks for UI is the visualization of data to the user. If you want something more sophisticated and sensitive, such as games, multimedia, not sorry for the thread pool resources, accurate timers, etc. and of course, in this case you must use tools such as QueueTimer.