<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Timers &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/timers/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 02 Feb 2026 21:25:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Optimizing Xojo Code, Part 4: Timer.CallLater</title>
		<link>https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Mon, 02 Feb 2026 21:25:28 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CallLater]]></category>
		<category><![CDATA[CancelCallLater]]></category>
		<category><![CDATA[Developer Challenge]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI Responsiveness]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15786</guid>

					<description><![CDATA[In&#160;Part 1&#160;of this series, we looked at a common but discouraged approach using a tight loop with&#160;DoEvents&#160;to keep the UI from freezing. In&#160;Part 2, we&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In&nbsp;<a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/">Part 1</a>&nbsp;of this series, we looked at a common but discouraged approach using a tight loop with&nbsp;<code>DoEvents</code>&nbsp;to keep the UI from freezing. In&nbsp;<a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/">Part 2</a>, we explored a better alternative by replacing that loop with a Timer control dragged onto a Window. In&nbsp;<a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/">Part 3</a>, we advanced to creating Timers programmatically with&nbsp;<code>AddHandler</code>&nbsp;for use in classes and modules.</p>



<p>Now, for even simpler one-off or chained delayed tasks, Xojo offers&nbsp;<code>Timer.CallLater</code>: no Timer instance required.</p>



<h2 class="wp-block-heading" id="the-strategy-timercalllater">The Strategy: Timer.CallLater</h2>



<p><code>Timer.CallLater(milliseconds, AddressOf MethodName, arg As Variant)</code>&nbsp;schedules your method to run after the specified delay on the main UI thread. Pass data via the Variant parameter. To chain calls (like our countdown), re-call it from within the method. Use&nbsp;<code>Timer.CancelCallLater(AddressOf MethodName)</code>&nbsp;to abort pending calls.</p>



<p>For full details, see the&nbsp;<a href="https://documentation.xojo.com/api/language/timer.html" target="_blank" rel="noreferrer noopener">Timer documentation</a>.</p>



<h2 class="wp-block-heading" id="looking-at-the-code">Looking at the Code</h2>



<p>Prerequisites: Add a <code>StatusLabel</code> (DesktopLabel control) and a constant <code>kCountTo As Integer = 20000</code>.</p>



<p>Let&#8217;s look at how we implement this.</p>



<h3 class="wp-block-heading" id="the-setup-button-pressed">The Setup (Button Pressed)</h3>



<p>Place the following code in the&nbsp;<code>Pressed</code>&nbsp;event handler of a button control:</p>



<pre class="wp-block-code"><code>Sub Pressed()
  Timer.CancelCallLater(AddressOf UpdateProgress)
  
  StatusLabel.Text = "0"
  
  Timer.CallLater(100, AddressOf UpdateProgress, 100)
End Sub</code></pre>



<h3 class="wp-block-heading" id="the-handler-recursive-chain">The Handler (Recursive Chain)</h3>



<p>Create the following method that handles the recursive chain of delayed updates:</p>



<pre class="wp-block-code"><code>Sub UpdateProgress(elapsedMs As Variant)
  Var elapsed As Integer = elapsedMs.IntegerValue
  
  If elapsed &gt;= kCountTo Then

    StatusLabel.Text = "done"

  Else

    StatusLabel.Text = elapsed.ToString
    Timer.CallLater(100, AddressOf UpdateProgress, elapsed + 100)

  End If
End Sub</code></pre>



<p><strong>Crucial Note:</strong>&nbsp;The handler method must accept a&nbsp;<code>Variant</code>&nbsp;parameter to receive the argument passed to&nbsp;<code>CallLater</code>. Always use type-safe extraction like&nbsp;<code>.IntegerValue</code>.</p>



<h2 class="wp-block-heading" id="how-it-works">How It Works</h2>



<ol class="wp-block-list">
<li>Initial Schedule: The button cancels any pending calls and schedules the first <code>UpdateProgress</code> after 100ms, passing <code>100</code> as the elapsed time (just in case we like pressing a button multiple times quickly).</li>



<li>Recursion: Each call updates the UI and, if not finished, schedules the next one 100ms in the future with incremented elapsed time.</li>



<li>Automatic Management: No Timer properties or handlers to manage; Xojo handles scheduling and cleanup.</li>



<li>Cancellation: Ensures only one chain runs at a time.</li>
</ol>



<h2 class="wp-block-heading" id="wrapping-up">Wrapping Up</h2>



<p><code>Timer.CallLater</code>&nbsp;shines for delayed UI updates or chained tasks without the overhead of Timer objects. It&#8217;s concise, safe, and powerful for responsive apps.</p>



<p>In Part 5, we&#8217;ll tackle true background processing with&nbsp;<code>Threads</code>&nbsp;and&nbsp;<code>UserInterfaceUpdate</code>.</p>



<p>Until then, happy coding!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Optimizing Code Series:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 1: Getting Started</a></li>



<li><a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</a></li>



<li><a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</a></li>



<li><a href="https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 4: Timer.CallLater</a></li>



<li><a href="https://blog.xojo.com/2026/03/02/optimizing-xojo-code-part-5-threads-and-userinterfaceupdate/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 5: Threads and UserInterfaceUpdate</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</title>
		<link>https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Wed, 14 Jan 2026 16:27:11 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[AddHandler]]></category>
		<category><![CDATA[Code Optimization]]></category>
		<category><![CDATA[Developer Challenge]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI Responsiveness]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15768</guid>

					<description><![CDATA[In&#160;Part 1&#160;of this Optimizing Xojo Code series, we looked at a working but discouraged approach using a tight loop with&#160;DoEvents&#160;to keep the UI from freezing.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In&nbsp;<a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/">Part 1</a>&nbsp;of this Optimizing Xojo Code series, we looked at a working but discouraged approach using a tight loop with&nbsp;<code>DoEvents</code>&nbsp;to keep the UI from freezing. In&nbsp;<a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/">Part 2</a>, we explored a better alternative by replacing that loop with a Timer control dragged onto a DesktopWindow. This is a simple and effective solution that takes advantage of Xojo’s object-oriented nature.</p>



<p>But what if you need a timer inside a Class or a Module where you can&#8217;t drop a visual control?</p>



<h2 class="wp-block-heading" id="the-strategy-addhandler">The Strategy: AddHandler</h2>



<p>When you use a Timer control from the library, you double-click it to add an&nbsp;<code>Action</code>&nbsp;event. When we create a Timer in code, we don&#8217;t have a &#8220;code editor&#8221; for it in the same way. Instead, we use the&nbsp;<code>AddHandler</code>&nbsp;command to tell Xojo: &#8220;When this timer fires its Action event, run this specific method instead.&#8221;</p>



<h2 class="wp-block-heading" id="looking-at-the-code">Looking at the Code</h2>



<p>Let&#8217;s look at how we implement this. In our example project, we have a button that initializes our timer and a separate method to handle the &#8220;ticks.&#8221;</p>



<h3 class="wp-block-heading" id="the-setup-opening-the-gate">The Setup</h3>



<p>First, we define a property on our window (or class) to hold our timer:&nbsp;<code>mWaitTimer As Timer</code></p>



<p>Then, in the&nbsp;<strong>Pressed</strong>&nbsp;event of our button, we instantiate it:</p>



<pre class="wp-block-code"><code>Sub Pressed() Handles Pressed
  ' 1. Cleanup
  If mWaitTimer &lt;&gt; Nil Then
    mWaitTimer.RunMode = Timer.RunModes.Off
    mWaitTimer = Nil
  End If
  
  ' 2. Initialization
  mElapsedMs = 0
  StatusLabel.Text = "0"
  
  ' 3. Create the dynamic timer
  mWaitTimer = New Timer
  mWaitTimer.Period = 100 ' 100 ms tick
  mWaitTimer.RunMode = Timer.RunModes.Multiple
  
  ' 4. The Magic: Link the Action event to our WaitTick method
  AddHandler mWaitTimer.Action, AddressOf WaitTick
End Sub</code></pre>



<h3 class="wp-block-heading" id="the-handler-doing-the-work">The Handler (Doing the Work)</h3>



<p>Now, let&#8217;s create the method named&nbsp;<code>WaitTick</code>.&nbsp;<strong>Crucial Note:</strong>&nbsp;When using&nbsp;<code>AddHandler</code>&nbsp;for a Timer, the first parameter of your receiving method must be of the type&nbsp;<code>Timer</code>&nbsp;so it knows which object triggered it.</p>



<pre class="wp-block-code"><code>Sub WaitTick(t As Timer)
  mElapsedMs = mElapsedMs + t.Period
  
  If mElapsedMs &gt;= kCountTo Then
    ' Achievement unlocked! Stop the timer and clean up
    t.RunMode = Timer.RunModes.Off
    StatusLabel.Text = "done"
    
    ' It's good practice to remove the handler when done
    RemoveHandler t.Action, AddressOf WaitTick
  Else
    StatusLabel.Text = mElapsedMs.ToString
  End If
End Sub</code></pre>



<h2 class="wp-block-heading" id="how-it-works">How It Works</h2>



<ol class="wp-block-list">
<li><strong>New Timer:</strong>&nbsp;We create a new instance of the Timer class in memory.</li>



<li><strong>AddHandler:</strong>&nbsp;This command connects the&nbsp;<code>Action</code>&nbsp;event of our new timer to the&nbsp;<code>WaitTick</code>&nbsp;method. The&nbsp;<code>AddressOf</code>&nbsp;operator tells Xojo the memory location of the code we want to run.</li>



<li><strong>Passing the Object:</strong>&nbsp;Because&nbsp;<code>WaitTick</code>&nbsp;receives&nbsp;<code>t As Timer</code>&nbsp;as a parameter, you can actually use the same handler for multiple different timers and knows exactly which one is calling for attention.</li>
</ol>



<h2 class="wp-block-heading" id="wrapping-up">Wrapping Up</h2>



<p>By moving your Timers into code, you take a significant step toward writing more modular Xojo applications. You’ve moved the logic from &#8220;Global UI state&#8221; into &#8220;Managed Code execution.&#8221;</p>



<p>In the upcoming Part 4, we’ll look at a shortcut that makes one-off background tasks a breeze:&nbsp;<code>Timer.CallLater</code>.</p>



<p>Until then, happy coding and don&#8217;t forget to add your own solution in the <a href="https://forum.xojo.com/" data-type="link" data-id="https://forum.xojo.com/" target="_blank" rel="noreferrer noopener">Xojo Forum</a>!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Optimizing Code Series:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 1: Getting Started</a></li>



<li><a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</a></li>



<li><a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</a></li>



<li><a href="https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 4: Timer.CallLater</a></li>



<li><a href="https://blog.xojo.com/2026/03/02/optimizing-xojo-code-part-5-threads-and-userinterfaceupdate/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 5: Threads and UserInterfaceUpdate</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</title>
		<link>https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 16:00:00 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Code Optimization]]></category>
		<category><![CDATA[Developer Challenge]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI Responsiveness]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15526</guid>

					<description><![CDATA[Welcome back! If you missed the first part in this series, check out Optimizing Xojo Code, Part 1: Getting Started, where we dissected the blocking&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Welcome back! If you missed the first part in this series, check out <strong><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/">Optimizing Xojo Code, Part 1: Getting Started</a></strong>, where we dissected the blocking <code>While</code> loop that counted up to <code>kCountTo</code>, updated a label, and kept the UI responsive only by calling <code>App.DoEvents</code>. That code works, but it spends most of its life running on the UI thread. In this tutorial we’ll rebuild that workflow step by step and end up with the first optimized solution: a timer-driven solution that keeps the interface responsive.</p>



<h3 class="wp-block-heading">Step 1: Let&#8217;s sketch the goal</h3>



<p>We will need a button that, when pressed, starts a simulated wait that updates a label every 100 ms until a fixed duration (<code>kCountTo</code>, which remains <code>20000</code> ms in our example) is reached. So, the timer will fire periodically and handle the counting there. The button simply resets state and starts the timer.</p>



<h3 class="wp-block-heading">Step 2: Prepare the UI components</h3>



<p>Create a <code>DesktopLabel</code> named <code>StatusLabel</code> to display progress.<br>Add a <code>DesktopButton</code> (caption it “Method 1”) whose <code>Pressed</code> event will kick off the timer.<br>Finally, place a <code>Timer</code> control onto the window, name it <code>mTimer</code>, set its <code>Period</code> to <code>100</code>, and set <code>RunMode</code> to <code>Multiple</code> (but leave it off until the button starts it).<br>Add an <code>Integer</code> property to the window such as <code>mMsWaited</code> to accumulate elapsed milliseconds, and keep <code>kCountTo</code> defined as <code>20000</code>.</p>



<h3 class="wp-block-heading">Step 3: Wire up the button</h3>



<p>The button handler becomes very simple. Reset the tracked milliseconds, show <code>"0"</code> in the label, ensure the timer runs at 100 ms ticks, and let it fire repeatedly:</p>



<pre class="wp-block-code"><code>Sub Pressed()
  // Reset the tracked elapsed ms and start the timer at 100 ms ticks.
  mMsWaited = 0
  StatusLabel.Text = "0"
  mTimer.Period = 100
  mTimer.RunMode = Timer.RunModes.Multiple
End Sub</code></pre>



<p>This code primes the state but does not block. The timer will perform the actual counting.</p>



<h3 class="wp-block-heading">Step 4: Let the timer take over</h3>



<p>Implement <code>mTimer.Action</code> to run on the UI thread. Each tick adds the timer’s period to <code>mMsWaited</code>, updates the label, and turns itself off once <code>kCountTo</code> has been reached:</p>



<pre class="wp-block-code"><code>Sub Action()
  mMsWaited = mMsWaited + Me.Period

  If mMsWaited &gt;= kCountTo Then
    Me.RunMode = Timer.RunModes.Off
    StatusLabel.Text = "done"
  Else
    StatusLabel.Text = mMsWaited.ToString
  End If
End Sub</code></pre>



<p>This keeps your UI responsive because the timer fires briefly and returns control back to the event loop instead of spinning inside a <code>While</code> loop.</p>



<h3 class="wp-block-heading">Step 5: Test the flow</h3>



<p>Run the app, click the button previously created and watch the label count up and stop at the target value. The timer approach lets other interface interactions remain responsive while still providing clear progress feedback.</p>



<h2 class="wp-block-heading">What makes this timer driven solution a solid first step?</h2>



<p>It shows how you can preserve the original behavior while giving the UI breathing room. It avoids <code>App.DoEvents</code>, reduces tight loops, and still delivers frequent updates. In the next article we’ll build on this idea and explore alternative approaches that continue to improve responsiveness and structure.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Optimizing Code Series:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 1: Getting Started</a></li>



<li><a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</a></li>



<li><a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</a></li>



<li><a href="https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 4: Timer.CallLater</a></li>



<li><a href="https://blog.xojo.com/2026/03/02/optimizing-xojo-code-part-5-threads-and-userinterfaceupdate/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 5: Threads and UserInterfaceUpdate</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Cross-Platform Mobile Bounce Animation</title>
		<link>https://blog.xojo.com/2021/03/17/cross-platform-mobile-bounce-animation/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 17 Mar 2021 18:04:06 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[iOSCanvas]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8175</guid>

					<description><![CDATA[Here's a fun little project you can try to get a feel for some simple animation in your iOS and future Android apps.]]></description>
										<content:encoded><![CDATA[
<p>Here&#8217;s a fun little project you can try to get a feel for simple animation in your iOS apps. As you can see, this project moves a small &#8220;ball&#8221; around the screen and it bounces off the edges.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="448" height="799" src="https://blog.xojo.com/wp-content/uploads/2021/03/CleanShot-2021-03-11-at-17.25.02.gif" alt="" class="wp-image-8177"/></figure>



<p>Create a new iOS project and on Screen1 add a couple Buttons and a Canvas, the buttons at the top and the Canvas using up the rest of the space. Also add a Timer.</p>



<p>Add some properties to track the ball&#8217;s position and direction:</p>



<ul class="wp-block-list"><li>Public Property XDirection as Integer = 10</li><li>Public Property XPosition as Integer = 10</li><li>Public Property YDirection as Integer = 10</li><li>Public Property YPosition as Integer = 10</li></ul>



<p>In the Opening event for Screen1, initialize the Timer (which I&#8217;ve named MoveTimer):</p>



<pre class="wp-block-preformatted">MoveTimer.Period = 50
MoveTimer.RunMode = Timer.RunModes.Multiple
MoveTimer.Enabled = False</pre>



<p>Speaking of the Timer, in its Run event put this code to move the ball:</p>



<pre class="wp-block-preformatted">XPosition = XPosition + XDirection
YPosition = YPosition + YDirection
BounceCanvas.Refresh</pre>



<p>Add the Paint and PointerDown events to the Canvas. In the Paint event draw the ball with this code:</p>



<pre class="wp-block-preformatted">Var size As Integer = 25
g.DrawingColor = Color.RGB(255, 0, 0)
g.DrawRectangle(0, 0, g.Width, g.Height)
g.FillOval(XPosition, YPosition, size, size)
If (XPosition + size) &gt; g.Width Then
  XDirection = -XDirection
End If
If ( YPosition + size) &gt; g.Height Then
  YDirection = -YDirection
End If
If XPosition &lt; 0 Then
  XDirection = -XDirection
End If
If YPosition &lt; 0 Then
  YDirection = -YDirection
End If</pre>



<p>And in the PointerDown event, reset the ball&#8217;s position to the touch:</p>



<pre class="wp-block-preformatted">XPosition = position.X
YPosition = position.Y
XDirection = -XDirection
YDirection = -YDirection</pre>



<p>Lastly you can add the Pressed event to the Start button and tell it to start the Timer:</p>



<pre class="wp-block-preformatted">MoveTimer.Enabled = True</pre>



<p>Similarly add the Pressed event to the Stop button and tell it to stop the Timer:</p>



<pre class="wp-block-preformatted">MoveTimer.Enabled = False</pre>



<p>That&#8217;s it. Run the project, click start to watch the ball bounce. Tap on the screen to change its position and direction. You could probably use this as the start of a Pong game!</p>



<p>Oh, and I forgot to mention that the code above was actually copied from the Android project where I first created this. The exact code copied over to iOS and worked as is with no changes. For a little teaser, here&#8217;s Bounce running on Android:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="377" height="799" src="https://blog.xojo.com/wp-content/uploads/2021/03/CleanShot-2021-03-11-at-17.19.43.gif" alt="" class="wp-image-8176"/></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Detecting Modifier Keys</title>
		<link>https://blog.xojo.com/2020/02/19/detecting-modifier-keys/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 19 Feb 2020 10:00:00 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6589</guid>

					<description><![CDATA[Sometimes it is necessary, or at least user-friendly, to adjust your interface when the user holds down modifier keys. ]]></description>
										<content:encoded><![CDATA[
<p>Sometimes it is necessary, or at least user-friendly, to adjust your interface when the user holds down modifier keys. For example, iTunes changes its &#8220;Previous Track&#8221; button from a rewind icon to a Genius Shuffle icon when the option key is held down. The goal is to inform the user that option-clicking the button will perform a different task.</p>



<p>At first glance you might think that simply looking for the option key in a KeyDown event will do the trick. The problem is KeyDown/KeyUp does not get called for modifier keys. The solution is to use a Timer to detect the Option/Alt key, though it could be adapted to read any of the modifier keys.</p>



<p>First of all, we need to decide whether to create a Timer embedded on a Window, or to create a subclass. Either technique will work, but the subclass creates reusable code, something I always recommend. Also, the subclass will allow you to call events which can come in handy.</p>



<p>Start by creating a new class called &#8220;OptionTimer&#8221; whose super is &#8220;Timer&#8221;. Next, add a property &#8220;Pressed As Boolean&#8221;, an event definition &#8220;KeyDown&#8221;, and a second event definition &#8220;KeyUp&#8221; to OptionTimer. Lastly add the Action event handler with the following code:</p>



<pre class="wp-block-preformatted">If Keyboard.AsyncAltKey = True And Pressed = False Then
  Pressed = True
  RaiseEvent KeyDown
ElseIf KeyBoard.AsyncAltKey = False And Pressed = True Then
  Pressed = False
  RaiseEvent KeyUp
End If</pre>



<p>That&#8217;s it for code. Now go to your Window, place a Timer on it and set the super to &#8220;OptionTimer&#8221; and you can insert code into the events for that timer. You&#8217;ll also want to adjust the period of the timer to something small such as 200 to make sure the events are responsive.</p>



<p>To test this, add a Label to the Window which will be used to display different text when the Option key is held down. In the Timer subclass, put this code in the KeyDown event:</p>



<pre class="wp-block-preformatted">Label1.Value = "You are pressing Option."</pre>



<p>And in the KeyUp event put this code:</p>



<pre class="wp-block-preformatted">Label1.Value = "Normal Text"</pre>



<p>Run the project and watch the text change when you hold and release the Option/Alt key.</p>



<p class="has-small-font-size"><em>*Updated from an original post written by Thom McGrath.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How To Speed Timers in Windows</title>
		<link>https://blog.xojo.com/2019/03/18/how-to-speed-timers-in-windows/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 18 Mar 2019 10:00:58 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5471</guid>

					<description><![CDATA[Windows imposes a minimum resolution of 16 ms, insufficient when we demand the maximum precision for a critical task. Of course Xojo has a solution for this, you can resort to a third-party plug-in that works extremely well or you might find the following technique useful for all kinds of projects.]]></description>
										<content:encoded><![CDATA[<p>The <b>Timer</b> and <b>Xojo.Core.Timer</b> classes gives us a resolution that is more than enough for most of the cases where we need to use them. In fact, under macOS we don&#8217;t find any kind of limitation when using the classes provided by the Xojo Framework: we can achieve a maximum resolution of 1 ms on any of the most recent computers.</p>
<p>But when working with Windows OS this is not so straightforward . It doesn&#8217;t matter if we try to set the Timer <b>Period</b> property to a minimum value of 1 ms; Windows imposes a minimum resolution of 16 ms, insufficient when we demand the maximum precision for a critical task (period interval between Timer firings).</p>
<p>Of course Xojo has a solution for this, you can resort to a third-party plug-in that works extremely well … or you might find the following technique useful for all kinds of projects.</p>
<p><span id="more-5471"></span></p>
<p>Let&#8217;s start with the foundation. The Timer period is determined by the hardware internal clock and, specifically, by the OS <b>driver</b>. Under Windows, all modern computers are capable of providing a resolution above the 16 ms set by Windows by default.</p>
<p>In fact, when we use the <code>NtQueryTimerResolution</code> function (from the <b>NTDLL.DLL</b> library) we can get minimum, maximum and current timer values for the hardware it is running on, similar to these (based on my own computer running Windows 10 under a VMWare Fusion virtual machine):</p>
<ul>
<li><b>Minimum Resolution</b>: 15.62 ms</li>
<li><b>Maximum Resolution</b>: 0.5 ms</li>
<li><b>Current Resolution</b>: 0.99 ms</li>
</ul>
<p>As you can see, the first value matches the current Timer behavior under Windows, but the hardware tell us that we can reach even a higher resolution … even of 0.5 ms between timer firings.</p>
<p>In order to make this change, Windows offers several options (all of them available under Xojo via the use of <b>Declares</b> or, preferably, using <b>External Methods</b>).</p>
<p>The first of these options, the one that would be the optimal approach, uses the group of MultimediaTimer functions (or high resolution Timers); specially these:</p>
<ul>
<li><code>CreateTimerQueueTimer</code>: Allows creating a timer with a delegate (or <b>Callback</b>) that will fire just one time, or regularly at the set period interval. This would be a behavior similar to the current Xojo Timer class.</li>
<li><code>ChangeTimerQueueTimer</code>: Using this function, we can modify the firing period for an already created timer; like the one we got when using the previous function.</li>
</ul>
<p>The main problem we will face when using these functions is that Windows creates these Timers on a different thread than the one used by the Xojo app. During my tests, this is a showstopper due to the fact that, currently, Xojo doesn&#8217;t support the use of pre-emptive threading. Thus, it can&#8217;t coordinate the execution of our Timer Callback with the tasks in place by the Xojo framework. As result, at some random point our app will be pointing to Nil objects and will silently stall.</p>
<p>In addition, these kind of Timers are reentrant. That means that the timer will execute the Callback again even if the previous call has not finished the job yet.</p>
<p>During my tests, I found a way to solve this kind of reentrant problem using one-time firing Timers. This way, the callback method would be the responsible for deleting the previously created Timer (this is needed to not overflow the maximum limit of 500 timers), and create a new one-time firing timer.</p>
<p>But this approach doesn&#8217;t solve the main problem: at a random point, the app unexpectly quits due to the fact of the non preemptive multithreading coordination between the one created by Windows for the Timer and the main, single thread, used by the Xojo apps.</p>
<p><img decoding="async" class="aligncenter wp-image-5472" src="https://blog.xojo.com/wp-content/uploads/2019/02/resInfo.jpg" alt="" width="400" height="488" /></p>
<h3>Same Thread Timers</h3>
<p>Once you have discarded the previous (optimal) approach, the technique you can use is based on the use of another kind of Timer provided by Windows: <code>WaitableTimer</code>. This kind of timer is created and, most important, run under the same thread they were created on. Thus, there is no <em>collision</em> with the Xojo framework during the application execution. In adition, as it goes with the commented High Definition Timers, we can achieve the same maximum resolution of 1 ms.</p>
<p>To start creating and using this kind of Timers in your Xojo app, first add an <b>External Method</b> so we can set the function definition from the C or C++ Windows Library.</p>
<p>In a new Xojo project, add a <b>Module</b> and our first External Method in it using the following values:</p>
<ul>
<li><b>Method Name</b>: <a href="https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-createwaitabletimerw">CreateWaitableTimerW</a></li>
<li><b>Parameters</b>: att as ptr, resetMode as Boolean, timerName as CString</li>
<li><b>Return Type</b>: Uint32</li>
<li><b>Lib</b>: Kernel32.dll</li>
<li><b>Soft</b>: Enabled</li>
</ul>
<p>As you can see, this function returns a <b>UInt32</b> value that will be non zero if it has succeeded creating the Timer. In fact, the returned value is a <b>Handler</b> pointing to the Timer structure of data. Thus, it is recommended to store this value in a property you can access later when you need it for calling other functions to delete (i.e: cancel), and for deleting the handler in order to free the used memory.</p>
<p>From the Xojo code point of view, later we can use this external function in this way:</p>
<pre>Dim name As CString = "name"
handler = CreateWaitableTimerW(Nil, False,  name)</pre>
<p>In this example, the <code>handler</code> variable is a property set in a class that works as a <em>wrapper</em> (see the example project).</p>
<p>Once we get the Handler, we will be able to set the parameters of the Timer functionality, using the <code>SetWaitableTimer</code> function. As in the previous case, we need to add a new External Method using the following values:</p>
<ul>
<li><b>Method Name</b>: <a href="https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-setwaitabletimer">SetWaitableTimer</a></li>
<li><b>Parameters</b>: hTimer as uint32, byref lpDueTime as LARGE_INTEGER, period as uint32, CompletionRoutine as ptr, parameter as uint32, resume as Boolean</li>
<li><b>Return Type</b>: Boolean</li>
<li><b>Lib</b>: Kernel32.dll</li>
<li><b>Soft</b>: Enabled</li>
</ul>
<p>As you can see in the method signature, we are using a data type that is not available in the Xojo Framework: <code>LARGE_INTEGER</code>. This is a very simple data structure needed when calling the function (in fact, it needs a <b>pointer</b> to this structure, so this is why we employ the <code>ByRef</code> keyword here. This is the way to get a pointer to the structure).</p>
<p>So, we need to add a new Structure definition into our Xojo project, using these values:</p>
<ul>
<li><b>Structure Name</b>: LARGE_INTEGER</li>
</ul>
<p>And setting the following value in the <b>Declaration</b> editor for the Structure declaration:</p>
<ul>
<li><code>quadPart As Int64</code>.</li>
</ul>
<h2>Setting the Timer Values</h2>
<p>Now we can write the Xojo code to call the added External Method:</p>
<pre>pLarge.quadPart = -5
b = SetWaitableTimer(handler, pLarge, TimerPeriod, AddressOf callback, 0, False)</pre>
<p>The important arguments passed to the function are these:</p>
<ul>
<li><b>Handler</b>: This is the (non zero) value we got calling the previous function.</li>
<li><b>pLarge</b>: This is a property added to the project, and whose data type matches the defined structure. As you can see, we have previously assigned to it the negative value -5. It is <b>very important</b> to assign here a value, or starting point <b>from the past time, in this case, five milliseconds.</b></li>
<li><b>TimerPeriod</b>: Here we set the firing period for the Timer (for example, 1 ms.).</li>
<li><b>AddressOf callback</b>: Here we set the memory address of the Xojo method we want to execute when the Timer fires. It is <b>very important</b> to add this method into the project as a Shared Method. In this example, the Xojo Method name is <code>callback</code>.</li>
</ul>
<p>The function call will return a Boolean value: <code>True</code> if it had success, or <code>False</code> otherwise.</p>
<h3>Signaling the Timer Firing</h3>
<p>However, this kind of timer need to be <em>signaled</em> for them to execute. That means that we need to add other External Method to our Module from the Windows <code>Kernel32.DLL</code> library: <code>SleepEx</code>:</p>
<ul>
<li><b>Method Name</b>: <a href="https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-sleepex">SleepEx</a></li>
<li><b>Parameters</b>: miliseconds as uint32, bAlertable as Boolean</li>
<li><b>Return Type</b>: Uint32</li>
<li><b>Lib</b>: Kernel32.DLL</li>
<li><b>Soft</b>: Enabled</li>
</ul>
<p>Once it has been set, we can create an endlees loop in our Xojo Code, so the Timer keeps signaling:</p>
<pre>Do 
  result  = SleepEx(INFINITE, True)
  app.DoEvents
Loop Until CancelTimer = True</pre>
<p>I&#8217;m using here the Boolean <code>CancelTimer</code> property in order to have a way to exit the loop (and interrupting the Timer execution) when required from the app.</p>
<p>Another important parameter is the one used by the call to the <code>SleepEx</code> function: <b>INFINITE</b>. This is a <b>Constant</b> added to the project, whose value in hexadecimal is <code>&amp;hFFFFFFFF</code>.</p>
<h3>Timer Cleaning</h3>
<p>Unlike the Windows High Definition or Multimedia Timers, we can&#8217;t modify the firing period for the WaitableTimers once they have been set. The only way to do it is to delete the one previously created, and create a new one; something you need to do when quitting the app or when you just need the Timer to fire once.</p>
<p>For this, we need to use the <code>CancelWaitableTimer</code> function. Add a new Exterrnal Method with this values for the method signature:</p>
<ul>
<li><b>Method Name</b>: <a href="https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-cancelwaitabletimer">CancelWaitableTimer</a></li>
<li><b>Parameters</b>: thandler as uint32</li>
<li><b>Return Type</b>: Boolean</li>
<li><b>Lib</b>: Kernel32.DLL</li>
<li><b>Soft</b>: Enabled</li>
</ul>
<p>In addition, and as part of the cleaning process, we need also to call the function in charge of freeing the used Handler. Add the last External Method with this signature:</p>
<ul>
<li><b>Method Name</b>: <a href="https://docs.microsoft.com/en-us/windows/desktop/api/handleapi/nf-handleapi-closehandle">CloseHandle</a></li>
<li><b>Parameters</b>: tHandler as Uint32</li>
<li><b>Return Type</b>: Boolean</li>
<li><b>Lib</b>: Kernel32.dll</li>
<li><b>Soft</b>: Enabled</li>
</ul>
<p>Now, you can use the following Xojo code to cancel the timer and delete the handler:</p>
<pre>If handler &lt;&gt; 0 Then
  Dim b As Boolean
  b = CancelWaitableTimer( handler )
  b = CloseHandle( handler )
End If</pre>
<h2>To Summarize</h2>
<p>As you can see, the main disadvantage of this technique is that you&#8217;ll be interrupting the usual workflow of the app: it will not return to the calling method or event once it enters into the method in charge of creating and firing the Timer (until the exit the Loop, of course). The way to make the app responsive and execute the code associated with the UI controls is through the <code>App.DoEvents</code> line of code.</p>
<h2>Additional Reading:</h2>
<ul>
<li>About Multimedia or High Resolution Timers: <a href="https://msdn.microsoft.com/library/windows/desktop/ms682485">CreateTimerQueueTimer function</a></li>
<li>About setting the inner clock in Windows: <a href="https://docs.microsoft.com/es-es/windows/desktop/api/timeapi/nf-timeapi-timebeginperiod">timeBeginPeriod Function</a></li>
<li>About setting Timers on the same Thread (WaitableTimers): <a href="https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-setwaitabletimer">SetWaitableTimer function</a></li>
<li>About Windows Data Types: <a href="https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types#lpcstr">Data Types</a></li>
</ul>
<h3>Example Project</h3>
<p>You can download the example project, available from <a href="https://www.dropbox.com/s/a5dlge95vjaecm6/WindowsTimer.zip?dl=1">this link</a>, to see and test the following:</p>
<ul>
<li>Exposed technique in action (Timers with a maximum resolution of 1 ms.)</li>
<li>How to modify the period value with the cancelation of a previously created timer</li>
<li>How to modify on the fly the Callback code executed by the Timer</li>
<li>How to get the Current, Minimum and Maximum clock resolutions from the Windows computer you&#8217;re using to run the app</li>
</ul>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others.</em></p>
<p>*<a href="https://www.aprendexojo.com/2019/02/3082/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
