<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Calvin Hsia's WebLog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/calvin_hsia/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/feed.xml</link>
    <description>thoughts from a professional developer</description>
    <lastBuildDate>Fri, 30 Nov 2018 02:19:26 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Create a simple File Watcher to monitor folder changes: Windows Prefetcher</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/create-a-simple-file-watcher-to-monitor-folder-changes-windows-prefetcher</link>
      <pubDate>Fri, 30 Nov 2018 02:19:26 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7905</guid>
      <description><![CDATA[There’s a folder like c:\Windows\Prefetch on your machine, probably with a few hundred files and a...]]></description>
      <content:encoded><![CDATA[<p><br>There’s a folder like c:\Windows\Prefetch on your machine, probably with a few hundred files and a few megabytes. If you search the web, you’ll find a few comments about Prefetch (enhanced by SuperFetch and ReadyBoost:&nbsp; <a href="https://en.wikipedia.org/wiki/Prefetcher">https://en.wikipedia.org/wiki/Prefetcher</a> ).<br>Below is sample code you can run to monitor the activity of this folder. The program shows a window that displays any changes to the folder as they occur. Start a few programs on your computer and you’ll see some action.<br>The sample code uses the FileSystemWatcher&nbsp; which makes it easy to write such a program.</p> <p>When your computer starts to run a program, the program and its dependencies need to be loaded into primary memory for execution. The data being read is stored in some sort of slower memory like disk or SSD (see <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2012/08/10/performance-of-memory-vs-disk/">https://blogs.msdn.microsoft.com/calvin_hsia/2012/08/10/performance-of-memory-vs-disk/</a> )<br>For example, you start Outlook. The computer then may have to access hundreds or thousands of various pieces of data scattered on the slower memory.<br>Suppose you start Outlook every day. The prefetcher could have already fetched all that data into faster memory before its needed, so Outlook starts much faster. Similarly, rebooting a system causes lots of programs to load. A prefetcher can fetch the data before its actually required.<br>Additionally, the prefetched data can be retrieved in an optimum sequence: accounting for data locality can improve fetch times.</p> <p>If you were working on the Windows team and were given a task to write a Prefetch feature that makes the computer seem faster to most users, how would you approach it? Hmm… a computer is very good at recording information. A folder is a very convenient place to put recorded information. You’d probably need some way to cap the size of the collected data so it doesn’t eat too much user space. You could record all slow memory accesses and how often the program was accessed. When the OS starts a program it could consult the Prefetch data to see if it’s already been “fetched” and thus seem faster to the user.</p> <p>&nbsp;</p> <p>For example, I start and old and a new app Visual Foxpro and Paint 3D on my Windows 10 machine, and I see <br>[03:16:42:331],31,Changed VFP9.EXE-F6167E92.pf<br>[03:16:42:331],32,Changed VFP9.EXE-F6167E92.pf<br>[03:17:03:769],33,Created PAINTSTUDIO.VIEW.EXE-8DC0D32B.pf<br>[03:17:03:770],33,Changed PAINTSTUDIO.VIEW.EXE-8DC0D32B.pf</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>&lt;code&gt;</p> <div class="codeBlock"><pre><code>
<span style="color: #0000ff">using</span> System;
<span style="color: #0000ff">using</span> System.Collections.Generic;
<span style="color: #0000ff">using</span> System.Diagnostics;
<span style="color: #0000ff">using</span> System.IO;
<span style="color: #0000ff">using</span> System.Linq;
<span style="color: #0000ff">using</span> System.Text;
<span style="color: #0000ff">using</span> System.Threading;
<span style="color: #0000ff">using</span> System.Threading.Tasks;
<span style="color: #0000ff">using</span> System.Windows;
<span style="color: #0000ff">using</span> System.Windows.Controls;
<span style="color: #0000ff">using</span> System.Windows.Data;
<span style="color: #0000ff">using</span> System.Windows.Documents;
<span style="color: #0000ff">using</span> System.Windows.Media;
<span style="color: #0000ff">using</span> System.Windows.Media.Imaging;
<span style="color: #0000ff">using</span> System.Windows.Navigation;
<span style="color: #0000ff">using</span> System.Windows.Shapes;
<span style="color: #0000ff">using</span> System.Windows.Threading;

<span style="color: #008000">/*
File-&gt;new-&gt;Project-&gt;C#-&gt;WPF App "PreFetchWatcher"
*/</span>

<span style="color: #0000ff">namespace</span> PrefetchWatcher
{
    <span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;summary&gt;</span>
    <span style="color: #808080">///</span><span style="color: #008000"> Interaction logic for MainWindow.xaml</span>
    <span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;/summary&gt;</span>
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">partial</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">MainWindow</span> : Window
    {
        TextBox _txtStatus;
        <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> FileFilter { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
        <span style="color: #0000ff">public</span> <span style="color: #0000ff">bool</span> ShowFileChanges { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; } = <span style="color: #0000ff">true</span>;

        <span style="color: #0000ff">public</span> MainWindow()
        {
            InitializeComponent();
            <span style="color: #0000ff">this</span>.Loaded += MainWindow_Loaded;
        }

        <span style="color: #0000ff">private</span> <span style="color: #0000ff">async</span> <span style="color: #0000ff">void</span> MainWindow_Loaded(<span style="color: #0000ff">object</span> sender, RoutedEventArgs ee)
        {
            <span style="color: #0000ff">try</span>
            {
                <span style="color: #0000ff">this</span>.DataContext = <span style="color: #0000ff">this</span>;
                <span style="color: #0000ff">this</span>.Height = 600;
                <span style="color: #0000ff">this</span>.Width = 1000;
                <span style="color: #0000ff">var</span> sp = <span style="color: #0000ff">new</span> StackPanel() { Orientation = Orientation.Vertical };
                <span style="color: #0000ff">var</span> spControls = <span style="color: #0000ff">new</span> StackPanel() { Orientation = Orientation.Horizontal };
                sp.Children.Add(spControls);

                spControls.Children.Add(<span style="color: #0000ff">new</span> Label() { Content = <span style="color: #a31515">"FileFilter"</span>, ToolTip = <span style="color: #a31515">"if not empty, will filter file change events  (case insensitive)"</span> });
                <span style="color: #0000ff">var</span> txtfileFilter = <span style="color: #0000ff">new</span> TextBox() { Width = 100, Height = 20, VerticalAlignment = VerticalAlignment.Top };
                txtfileFilter.SetBinding(TextBox.TextProperty, nameof(FileFilter));
                spControls.Children.Add(txtfileFilter);


                <span style="color: #0000ff">var</span> chkShowFileChanges = <span style="color: #0000ff">new</span> CheckBox()
                {
                    Content = <span style="color: #a31515">"ShowFileChanges"</span>,
                    Height = 20,
                    VerticalAlignment = VerticalAlignment.Top,
                    Margin = <span style="color: #0000ff">new</span> Thickness(10, 0, 10, 0)
                };
                chkShowFileChanges.SetBinding(CheckBox.IsCheckedProperty, nameof(ShowFileChanges));
                spControls.Children.Add(chkShowFileChanges);


                _txtStatus = <span style="color: #0000ff">new</span> TextBox()
                {
                    IsReadOnly = <span style="color: #0000ff">true</span>,
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                    IsUndoEnabled = <span style="color: #0000ff">false</span>,
                    FontFamily = <span style="color: #0000ff">new</span> FontFamily(<span style="color: #a31515">"Courier New"</span>),
                    FontSize = 10,
                    Height = 200,
                    MaxHeight = 200,
                    HorizontalContentAlignment = HorizontalAlignment.Left
                };
                sp.Children.Add(_txtStatus);
                <span style="color: #0000ff">this</span>.Content = sp;
                <span style="color: #0000ff">var</span> folderPreFetch = System.IO.Path.Combine(Environment.GetEnvironmentVariable(<span style="color: #a31515">"SystemRoot"</span>), <span style="color: #a31515">"Prefetch"</span>);
                AddStatusMsg(<span style="color: #a31515">$"Started watching </span>{folderPreFetch}<span style="color: #a31515">"</span>);
                <span style="color: #0000ff">await</span> Task.Run(() =&gt;
                {
                    <span style="color: #0000ff">var</span> watcher = <span style="color: #0000ff">new</span> FileSystemWatcher(folderPreFetch);
                    <span style="color: #0000ff">var</span> hndler = <span style="color: #0000ff">new</span> FileSystemEventHandler((o, e) =&gt;
                    {
                        <span style="color: #0000ff">bool</span> showit = <span style="color: #0000ff">true</span>;
                        <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(FileFilter))
                        {
                            <span style="color: #0000ff">if</span> (e.Name.ToLower().IndexOf(FileFilter.Trim().ToLower()) &lt; 0)
                            {
                                showit = <span style="color: #0000ff">false</span>;
                            }
                        }
                        <span style="color: #0000ff">if</span> (e.ChangeType == WatcherChangeTypes.Changed &amp;&amp; !<span style="color: #0000ff">this</span>.ShowFileChanges)
                        {
                            showit = <span style="color: #0000ff">false</span>;
                        }
                        <span style="color: #0000ff">if</span> (showit)
                        {
                            AddStatusMsg(<span style="color: #a31515">$"</span>{e.ChangeType}<span style="color: #a31515"> </span>{e.Name}<span style="color: #a31515">"</span>);
                            <span style="color: #008000">//switch (e.ChangeType)</span>
                            <span style="color: #008000">//{</span>
                            <span style="color: #008000">//    case WatcherChangeTypes.Created:</span>
                            <span style="color: #008000">//        break;</span>
                            <span style="color: #008000">//    case WatcherChangeTypes.Changed:</span>
                            <span style="color: #008000">//        break;</span>
                            <span style="color: #008000">//    case WatcherChangeTypes.Deleted:</span>
                            <span style="color: #008000">//        break;</span>
                            <span style="color: #008000">//    case WatcherChangeTypes.Renamed:</span>
                            <span style="color: #008000">//        break;</span>
                            <span style="color: #008000">//}</span>
                        }
                    });
                    watcher.Created += hndler;
                    watcher.Deleted += hndler;
                    watcher.Changed += hndler;
                    <span style="color: #008000">//watcher.Renamed += hndler;</span>
                    watcher.EnableRaisingEvents = <span style="color: #0000ff">true</span>;
                });

            }
            <span style="color: #0000ff">catch</span> (Exception ex)
            {
                <span style="color: #0000ff">this</span>.Content = ex.ToString();
            }
        }


        <span style="color: #0000ff">void</span> AddStatusMsg(<span style="color: #0000ff">string</span> msg, <span style="color: #0000ff">params</span> <span style="color: #0000ff">object</span>[] args)
        {
            <span style="color: #0000ff">if</span> (_txtStatus != <span style="color: #0000ff">null</span>)
            {
                <span style="color: #008000">// we want to read the threadid </span>
                <span style="color: #008000">//and time immediately on current thread</span>
                <span style="color: #0000ff">var</span> dt = <span style="color: #0000ff">string</span>.Format(<span style="color: #a31515">"[{0}],{1,2},"</span>,
                    DateTime.Now.ToString(<span style="color: #a31515">"hh:mm:ss:fff"</span>),
                    Thread.CurrentThread.ManagedThreadId);
                _txtStatus.Dispatcher.BeginInvoke(
                    <span style="color: #0000ff">new</span> Action(() =&gt;
                    {
                        <span style="color: #008000">// this action executes on main thread</span>
                        <span style="color: #0000ff">var</span> str = <span style="color: #0000ff">string</span>.Format(dt + msg + <span style="color: #a31515">"\r\n"</span>, args);
                        <span style="color: #008000">// note: this is a memory leak: can clear periodically</span>
                        _txtStatus.AppendText(str);
                        _txtStatus.ScrollToEnd();
                    }));
            }
        }
    }
}</code></pre></div>
<p>&lt;/code&gt;</p>]]></content:encoded>
    </item>
    <item>
      <title>How to stress and measure the Garbage Collector</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/how-to-stress-and-measure-the-garbage-collector</link>
      <pubDate>Tue, 30 Oct 2018 23:50:46 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7895</guid>
      <description><![CDATA[Many years ago, I was writing real time applications for monitoring sound signals bouncing off...]]></description>
      <content:encoded><![CDATA[<p>Many years ago, I was writing real time applications for monitoring sound signals bouncing off submarines. That code (written in Fortran and PDP-11 assembly code) had to process the incoming sound at the rate of thousands of data points per second, doing real-time Fast Fourier Transforms and analyzing the results, printing graphs. Using a managed language, with unpredictable garbage collection can make this much more problematic. The CLR needs to suspend managed threads for garbage collection, which can cause slowdowns in user code, causing interruptions in the timing, perhaps causing missed data points.<br>How can one write very little simple code with a huge impact on the .Net garbage collector?<br>You’d think one way to do this is to consume large amounts of memory. That’s one way, but here’s another:</p> <p>Thinking about GC, here’s a simple model of how it could work. Imagine every object is a person in a room:<br></p> <p>1.&nbsp;&nbsp;&nbsp; Suspend all threads, so that object references are constant<br>2.&nbsp;&nbsp;&nbsp; Tell every person to raise a hand<br>3.&nbsp;&nbsp;&nbsp; Define a “GC Root” person: one who cannot be freed. Examples are<br>&nbsp;&nbsp;&nbsp; a.&nbsp;&nbsp;&nbsp; static vars, globals<br>&nbsp;&nbsp;&nbsp; b.&nbsp;&nbsp;&nbsp; Variables on a stack<br>&nbsp;&nbsp;&nbsp; c.&nbsp;&nbsp;&nbsp; Interop wrappers<br>4.&nbsp;&nbsp;&nbsp; For each&nbsp; “GC Root”:<br>&nbsp;&nbsp;&nbsp; a.&nbsp;&nbsp;&nbsp; Recursive step:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i.&nbsp;&nbsp;&nbsp; Put your hand down (I still need you as non-garbage)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ii.&nbsp;&nbsp;&nbsp; Tell each object that you reference (point to) to <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.&nbsp;&nbsp;&nbsp; Do the recursive step<br>5.&nbsp;&nbsp;&nbsp; Those with their hands still up are “garbage” and can be collected<br>6.&nbsp;&nbsp;&nbsp; Optionally compress/consolidate free space in the room by moving objects <br>&nbsp;&nbsp;&nbsp; a.&nbsp;&nbsp;&nbsp; Moving an object changes its objectId, so all references need to be patched too.<br></p> <p>&nbsp;</p> <p><br>So creating an example that takes a while might be to create a long chain of references: A=&gt;B=&gt;C=&gt;D</p> <p>Here’s some code to generate a long object reference chain.</p> <p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class MyLinklist<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MyLinklist _next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyLinklist _root = null; // static root</p> <p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; nIter; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var x = new MyLinklist<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _next = _root<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _root = x;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _root = null;</p> <p><br>How do I measure the effectiveness of this code on GC? I need some way of determining the performance impact of the code.</p> <p>I wrote a post <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2014/05/29/how-to-monitor-and-respond-to-memory-use/">https://blogs.msdn.microsoft.com/calvin_hsia/2014/05/29/how-to-monitor-and-respond-to-memory-use/</a> a few years ago, which showed how to get performance counter numbers.</p> <p>I combined that with the graphing code in <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2017/08/31/graph-poker-hand-distributions/">https://blogs.msdn.microsoft.com/calvin_hsia/2017/08/31/graph-poker-hand-distributions/</a>, resulting in the sample code below.</p> <p><font color="#c0504d">File-&gt;new-&gt;Project-&gt;C#-&gt;WPF App "GCStress"<br>Project-&gt;Add Reference to System.Drawing, WindowsFormsIntegration, System.Windows.Forms, System.Windows.Forms.DataVisualizetion<br>Paste in the code below to replace the code in MainWindow.xaml.cs</font></p> <p>The perf counter monitoring code runs and samples the perf counters periodically and updates a moving graph. The GC Stress code can be turned on/off with the button.</p> <p>When you run the code, it starts monitoring the selected performance counters. Of course, you can use the PerfMon application built into Windows already <a href="https://msdn.microsoft.com/en-us/library/aa266946%28v=vs.60%29.aspx?f=255&amp;MSPPError=-2147217396">https://msdn.microsoft.com/en-us/library/aa266946%28v=vs.60%29.aspx?f=255&amp;MSPPError=-2147217396</a> , but that is quite general purpose and not easily customizable.</p> <p>Click the Go button to start stressing the GC. From the graphs, the % of time spent in GC is &gt; 60%</p> <p>You can choose various performance counters to monitor, and you can specify various parameters for the performance graph </p> <p>Try running the code, and just move the window around, or resize, monitoring how ProcessorPctTime changes.<br>Try increasing the NumIterations, watching the ProcessorVirtualBytes. Eventually the program will slow down and crash Out of Memory.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/10/image90.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/10/image_thumb75.png" width="734" height="339"></a></p> <p>See also<br><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2005/09/16/the-fast-fourier-transform/">https://blogs.msdn.microsoft.com/calvin_hsia/2005/09/16/the-fast-fourier-transform/</a><br><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2011/10/31/more-fun-with-the-fast-fourier-transform/">https://blogs.msdn.microsoft.com/calvin_hsia/2011/10/31/more-fun-with-the-fast-fourier-transform/</a></p> <p><br>&nbsp;</p> <p>&lt;Code&gt;</p> <div class='codeBlock'><pre><code><span style='color:#0000ff'>using</span> System;
<span style='color:#0000ff'>using</span> System.Collections.Generic;
<span style='color:#0000ff'>using</span> System.Diagnostics;
<span style='color:#0000ff'>using</span> System.Linq;
<span style='color:#0000ff'>using</span> System.Text;
<span style='color:#0000ff'>using</span> System.Threading;
<span style='color:#0000ff'>using</span> System.Threading.Tasks;
<span style='color:#0000ff'>using</span> System.Windows;
<span style='color:#0000ff'>using</span> System.Windows.Controls;
<span style='color:#0000ff'>using</span> System.Windows.Data;
<span style='color:#0000ff'>using</span> System.Windows.Documents;
<span style='color:#0000ff'>using</span> System.Windows.Forms.DataVisualization.Charting;
<span style='color:#0000ff'>using</span> System.Windows.Forms.Integration;
<span style='color:#0000ff'>using</span> System.Windows.Input;
<span style='color:#0000ff'>using</span> System.Windows.Media;
<span style='color:#0000ff'>using</span> System.Windows.Media.Imaging;
<span style='color:#0000ff'>using</span> System.Windows.Navigation;
<span style='color:#0000ff'>using</span> System.Windows.Shapes;
<span style='color:#0000ff'>using</span> System.Windows.Threading;

<span style='color:#008000'>/*
 File-&gt;new-&gt;Project-&gt;C#-&gt;WPF App "GCStress"
 Project-&gt;Add Reference to System.Drawing, WindowsFormsIntegration, System.Windows.Forms, System.Windows.Forms.DataVisualizetion
*/</span>

<span style='color:#0000ff'>namespace</span> GCStress
{
    <span style='color:#808080'>///</span><span style='color:#008000'> </span><span style='color:#808080'>&lt;summary&gt;</span>
    <span style='color:#808080'>///</span><span style='color:#008000'> Interaction logic for MainWindow.xaml</span>
    <span style='color:#808080'>///</span><span style='color:#008000'> </span><span style='color:#808080'>&lt;/summary&gt;</span>
    <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>partial</span> <span style='color:#0000ff'>class</span> <span style='color:#2b91af'>MainWindow</span> : Window
    {
        TextBox _txtStatus;
        Chart _chart;

        <span style='color:#808080'>///</span><span style='color:#008000'> </span><span style='color:#808080'>&lt;summary&gt;</span>
        <span style='color:#808080'>///</span><span style='color:#008000'> PerfCounters updated periodically. Safe to change without stopping the monitoring</span>
        <span style='color:#808080'>///</span><span style='color:#008000'> </span><span style='color:#808080'>&lt;/summary&gt;</span>
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>int</span> UpdateInterval { <span style='color:#0000ff'>get</span>; <span style='color:#0000ff'>set</span>; } = 200;
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>int</span> NumIterations { <span style='color:#0000ff'>get</span>; <span style='color:#0000ff'>set</span>; } = 3000;
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>int</span> NumDataPoints { <span style='color:#0000ff'>get</span>; <span style='color:#0000ff'>set</span>; } = 100;

        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>bool</span> ScaleByteCounters { <span style='color:#0000ff'>get</span>; <span style='color:#0000ff'>set</span>; } = <span style='color:#0000ff'>true</span>;
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>bool</span> SetMaxGraphTo100 { <span style='color:#0000ff'>get</span>; <span style='color:#0000ff'>set</span>; } = <span style='color:#0000ff'>true</span>;

        <span style='color:#0000ff'>public</span> PerfCounterType PerfCounterTypesToShow { <span style='color:#0000ff'>get</span>; <span style='color:#0000ff'>set</span>; } = PerfCounterType.ProcessorPctTime;

        [Flags] <span style='color:#008000'>// user can select multiple items. (beware scaling: pct =&gt; 0-100, Bytes =&gt; 0-4G)</span>
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>enum</span> <span style='color:#2b91af'>PerfCounterType</span>
        {
            None,
            ProcessorPctTime = 0x1,
            ProcessorPrivateBytes = 0x2,
            ProcessorVirtualBytes = 0x4,
            GCPctTime = 0x8,
            GCBytesInAllHeaps = 0x10,
            GCAllocatedBytesPerSec = 0x20,
        }

        Dictionary&lt;PerfCounterType, <span style='color:#0000ff'>string</span>&gt; _dictPerfCounterDefinitions = <span style='color:#0000ff'>new</span> Dictionary&lt;PerfCounterType, <span style='color:#0000ff'>string</span>&gt;
        {
            {PerfCounterType.ProcessorPctTime,<span style='color:#a31515'>"Process|% Processor Time|ID Process"</span> },
            {PerfCounterType.ProcessorPrivateBytes,<span style='color:#a31515'>"Process|Private Bytes|ID Process"</span> },
            {PerfCounterType.ProcessorVirtualBytes,<span style='color:#a31515'>"Process|Virtual Bytes|ID Process"</span> },
            {PerfCounterType.GCPctTime,<span style='color:#a31515'>".NET CLR Memory|% Time in GC|Process ID"</span> },
            {PerfCounterType.GCBytesInAllHeaps,<span style='color:#a31515'>".NET CLR Memory|# Bytes in all Heaps|Process ID"</span> },
            {PerfCounterType.GCAllocatedBytesPerSec,<span style='color:#a31515'>".NET CLR Memory|Allocated Bytes/sec|Process ID"</span> },
        };

        CancellationTokenSource _ctsGCStress;
        CancellationTokenSource _ctsPcounter;
        Task _tskDoPerfMonitoring;
        <span style='color:#0000ff'>public</span> MainWindow()
        {
            InitializeComponent();
            <span style='color:#0000ff'>this</span>.Loaded += MainWindow_Loaded;
        }

        <span style='color:#0000ff'>private</span> <span style='color:#0000ff'>async</span> <span style='color:#0000ff'>void</span> MainWindow_Loaded(<span style='color:#0000ff'>object</span> sender, RoutedEventArgs e)
        {
            <span style='color:#0000ff'>try</span>
            {
                <span style='color:#0000ff'>this</span>.DataContext = <span style='color:#0000ff'>this</span>;
                <span style='color:#0000ff'>this</span>.Title = <span style='color:#a31515'>"GCStress"</span>;
                <span style='color:#0000ff'>this</span>.Height = 600;
                <span style='color:#0000ff'>this</span>.Width = 1000;
                <span style='color:#0000ff'>var</span> sp = <span style='color:#0000ff'>new</span> StackPanel() { Orientation = Orientation.Vertical };
                <span style='color:#0000ff'>var</span> spControls = <span style='color:#0000ff'>new</span> StackPanel() { Orientation = Orientation.Horizontal };
                sp.Children.Add(spControls);

                spControls.Children.Add(<span style='color:#0000ff'>new</span> Label() { Content = <span style='color:#a31515'>"Update Interval"</span>, ToolTip = <span style='color:#a31515'>"MilliSeconds"</span> });
                <span style='color:#0000ff'>var</span> txtUpdateInterval = <span style='color:#0000ff'>new</span> TextBox() { Width = 50, Height = 20, VerticalAlignment = VerticalAlignment.Top };
                txtUpdateInterval.SetBinding(TextBox.TextProperty, nameof(UpdateInterval));
                spControls.Children.Add(txtUpdateInterval);

                <span style='color:#0000ff'>var</span> lbPCounters = <span style='color:#0000ff'>new</span> ListBox()
                {
                    Width = 150,
                    SelectionMode = SelectionMode.Multiple,
                    Margin = <span style='color:#0000ff'>new</span> Thickness(10, 0, 0, 0)
                };
                lbPCounters.ItemsSource = ((PerfCounterType[])Enum.GetValues(<span style='color:#0000ff'>typeof</span>(PerfCounterType))).Skip(1); <span style='color:#008000'>// skip the "None"</span>
                lbPCounters.SelectedIndex = 0;
                lbPCounters.SelectionChanged += <span style='color:#0000ff'>async</span> (ol, el) =&gt;
                {
                    lbPCounters.IsEnabled = <span style='color:#0000ff'>false</span>;
                    AddStatusMsg(<span style='color:#a31515'>$"Setting counters to </span>{<span style='color:#0000ff'>this</span>.PerfCounterTypesToShow.ToString()}<span style='color:#a31515'>"</span>);
                    <span style='color:#008000'>// cancel the perf monitoring</span>
                    _ctsPcounter?.Cancel();
                    <span style='color:#008000'>// before we wait for cancel to finish we can do some work</span>
                    PerfCounterType pcEnum = PerfCounterType.None;
                    <span style='color:#0000ff'>foreach</span> (var itm <span style='color:#0000ff'>in</span> lbPCounters.SelectedItems)
                    {
                        pcEnum |= (PerfCounterType)Enum.Parse(<span style='color:#0000ff'>typeof</span>(PerfCounterType), itm.ToString());
                    }
                    <span style='color:#008000'>// wait for it to be done cancelling</span>
                    <span style='color:#0000ff'>if</span> (_tskDoPerfMonitoring != <span style='color:#0000ff'>null</span>)
                    {
                        <span style='color:#0000ff'>await</span> _tskDoPerfMonitoring;
                    }
                    <span style='color:#0000ff'>await</span> Task.Run(() =&gt;
                    {
                        <span style='color:#008000'>// run on threadpool thread</span>
                        <span style='color:#0000ff'>lock</span> (_lstPerfCounterData)
                        {
                            <span style='color:#0000ff'>this</span>.PerfCounterTypesToShow = pcEnum;
                            ResetPerfCounterMonitor();
                        }
                    });
                    AddStatusMsg(<span style='color:#a31515'>$"SelectionChanged done"</span>);
                    lbPCounters.IsEnabled = <span style='color:#0000ff'>true</span>;
                };
                spControls.Children.Add(lbPCounters);

                <span style='color:#0000ff'>var</span> chkSetMaxGraphTo100 = <span style='color:#0000ff'>new</span> CheckBox()
                {
                    Content = <span style='color:#a31515'>"SetMaxGraphTo100"</span>,
                    ToolTip = <span style='color:#a31515'>"Set Max Y axis to 100. Else will dynamically rescale Y axis"</span>,
                    Height = 20,
                    VerticalAlignment = VerticalAlignment.Top,
                    Margin = <span style='color:#0000ff'>new</span> Thickness(10, 0, 10, 0)
                };
                chkSetMaxGraphTo100.SetBinding(CheckBox.IsCheckedProperty, nameof(SetMaxGraphTo100));
                spControls.Children.Add(chkSetMaxGraphTo100);

                <span style='color:#0000ff'>var</span> chkScaleByteCtrs = <span style='color:#0000ff'>new</span> CheckBox()
                {
                    Content = <span style='color:#a31515'>"Scale 'Byte' counters"</span>,
                    ToolTip = <span style='color:#a31515'>"for Byte counters, scale to be a percent of 4Gigs"</span>,
                    Height = 20,
                    VerticalAlignment = VerticalAlignment.Top
                };
                chkScaleByteCtrs.SetBinding(CheckBox.IsCheckedProperty, nameof(ScaleByteCounters));
                spControls.Children.Add(chkScaleByteCtrs);

                spControls.Children.Add(<span style='color:#0000ff'>new</span> Label()
                {
                    Content = <span style='color:#a31515'>"NumDataPoints"</span>,
                    ToolTip = <span style='color:#a31515'>"Number of Data points (x axis). Will change on next Reset"</span>
                });
                <span style='color:#0000ff'>var</span> txtNumDataPoints = <span style='color:#0000ff'>new</span> TextBox() { Width = 50, Height = 20, VerticalAlignment = VerticalAlignment.Top };
                txtNumDataPoints.SetBinding(TextBox.TextProperty, nameof(NumDataPoints));
                spControls.Children.Add(txtNumDataPoints);

                spControls.Children.Add(<span style='color:#0000ff'>new</span> Label()
                {
                    Content = <span style='color:#a31515'>"NumIterations"</span>,
                    ToolTip = <span style='color:#a31515'>"Number of linklist items (will be multiplied by 1000)"</span>
                });
                <span style='color:#0000ff'>var</span> txtNumIter = <span style='color:#0000ff'>new</span> TextBox() { Width = 50, Height = 20, VerticalAlignment = VerticalAlignment.Top };
                txtNumIter.SetBinding(TextBox.TextProperty, nameof(NumIterations));
                spControls.Children.Add(txtNumIter);

                <span style='color:#0000ff'>var</span> btnGo = <span style='color:#0000ff'>new</span> Button()
                {
                    Content = <span style='color:#a31515'>"_Go"</span>,
                    ToolTip = <span style='color:#a31515'>"Stress GC"</span>,
                    Width = 30,
                    Height = 20,
                    VerticalAlignment = VerticalAlignment.Top
                };
                spControls.Children.Add(btnGo);

                _chart = <span style='color:#0000ff'>new</span> Chart()
                {
                    Width = 200,
                    Height = 100,
                    Dock = System.Windows.Forms.DockStyle.Fill
                };
                <span style='color:#0000ff'>var</span> wfh = <span style='color:#0000ff'>new</span> WindowsFormsHost()
                {
                    Child = _chart
                };
                sp.Children.Add(wfh);
                _txtStatus = <span style='color:#0000ff'>new</span> TextBox()
                {
                    IsReadOnly = <span style='color:#0000ff'>true</span>,
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                    IsUndoEnabled = <span style='color:#0000ff'>false</span>,
                    FontFamily = <span style='color:#0000ff'>new</span> FontFamily(<span style='color:#a31515'>"Courier New"</span>),
                    FontSize = 10,
                    Height = 200,
                    MaxHeight = 200,
                    HorizontalContentAlignment = HorizontalAlignment.Left
                };
                sp.Children.Add(_txtStatus);
                <span style='color:#0000ff'>this</span>.Content = sp;

                <span style='color:#0000ff'>var</span> isGoing = <span style='color:#0000ff'>false</span>;
                btnGo.Click += <span style='color:#0000ff'>async</span> (ob, eb) =&gt;
                {
                    isGoing = !isGoing;
                    <span style='color:#0000ff'>if</span> (isGoing)
                    {
                        btnGo.Content = <span style='color:#a31515'>"_Stop"</span>;
                        AddStatusMsg(<span style='color:#a31515'>"Starting"</span>);
                        _ctsGCStress = <span style='color:#0000ff'>new</span> CancellationTokenSource();
                        <span style='color:#0000ff'>await</span> DoGCStressAsync();
                        <span style='color:#008000'>// when the task finishes, then we're stopping</span>
                        isGoing = <span style='color:#0000ff'>false</span>;
                    }
                    AddStatusMsg(<span style='color:#a31515'>"Stopping"</span>);
                    _ctsGCStress.Cancel();
                    btnGo.Content = <span style='color:#a31515'>"_Go"</span>;
                };
                <span style='color:#0000ff'>await</span> Task.Run(() =&gt;
                {
                    ResetPerfCounterMonitor();
                });

                <span style='color:#008000'>//        btnGo.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));</span>
            }
            <span style='color:#0000ff'>catch</span> (Exception ex)
            {
                <span style='color:#0000ff'>this</span>.Content = ex.ToString();
            }
        }

        <span style='color:#0000ff'>class</span> <span style='color:#2b91af'>MyLinklist</span>
        {
            <span style='color:#0000ff'>public</span> MyLinklist _next;
            <span style='color:#008000'>//public int[] _array;</span>
            <span style='color:#008000'>//public MyLinklist()</span>
            <span style='color:#008000'>//{</span>
            <span style='color:#008000'>//    _array = new int[100];</span>
            <span style='color:#008000'>//}</span>
        }
        MyLinklist _root = <span style='color:#0000ff'>null</span>; <span style='color:#008000'>// static root</span>

        <span style='color:#0000ff'>private</span> <span style='color:#0000ff'>async</span> Task DoGCStressAsync()
        {
            <span style='color:#0000ff'>await</span> Task.Run(() =&gt;
            {
                AddStatusMsg(<span style='color:#a31515'>$"starting </span>{nameof(DoGCStressAsync)}<span style='color:#a31515'>"</span>);
                <span style='color:#0000ff'>try</span>
                {
                    <span style='color:#0000ff'>while</span> (!_ctsGCStress.Token.IsCancellationRequested)
                    {
                        <span style='color:#0000ff'>int</span> nIter = 1000 * NumIterations;
                        <span style='color:#0000ff'>for</span> (<span style='color:#0000ff'>int</span> i = 0; i &lt; nIter; i++)
                        {
                            <span style='color:#0000ff'>var</span> x = <span style='color:#0000ff'>new</span> MyLinklist
                            {
                                _next = _root
                            };
                            _root = x;
                        }
                        _root = <span style='color:#0000ff'>null</span>;
                    }
                }
                <span style='color:#0000ff'>catch</span> (OutOfMemoryException ex)
                {
                    _root = <span style='color:#0000ff'>null</span>;
                    AddStatusMsg(<span style='color:#a31515'>$"</span>{nameof(DoGCStressAsync)}<span style='color:#a31515'> </span>{ex.ToString()}<span style='color:#a31515'>"</span>);
                }
                AddStatusMsg(<span style='color:#a31515'>$"cancelling </span>{nameof(DoGCStressAsync)}<span style='color:#a31515'>"</span>);
            });
        }


        <span style='color:#008000'>// list of current set of perfcounters we're monitoring</span>
        List&lt;PerfCounterData&gt; _lstPerfCounterData = <span style='color:#0000ff'>new</span> List&lt;PerfCounterData&gt;();

        <span style='color:#008000'>// use a circular buffer to store samples. </span>
        <span style='color:#008000'>// dictionary of sample # (int from 0 to NumDataPoints) =&gt;( List (PerfCtrValues in order)</span>
        <span style='color:#0000ff'>public</span> Dictionary&lt;<span style='color:#0000ff'>int</span>, List&lt;<span style='color:#0000ff'>uint</span>&gt;&gt; _dataPoints = <span style='color:#0000ff'>new</span> Dictionary&lt;<span style='color:#0000ff'>int</span>, List&lt;<span style='color:#0000ff'>uint</span>&gt;&gt;();
        <span style='color:#0000ff'>int</span> _bufferIndex = 0;
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>class</span> <span style='color:#2b91af'>PerfCounterData</span>
        {
            <span style='color:#0000ff'>public</span> PerfCounterType pcntrType;
            <span style='color:#0000ff'>public</span> PerformanceCounter performanceCounter;
            <span style='color:#0000ff'>public</span> PerfCounterData(PerfCounterType pcntrType, PerformanceCounter performanceCounter)
            {
                <span style='color:#0000ff'>this</span>.pcntrType = pcntrType;
                <span style='color:#0000ff'>this</span>.performanceCounter = performanceCounter;
            }
        }
        <span style='color:#0000ff'>void</span> ResetPerfCounterMonitor()
        {
            <span style='color:#0000ff'>var</span> pid = Process.GetCurrentProcess().Id;
            <span style='color:#0000ff'>lock</span> (_lstPerfCounterData)
            {
                AddStatusMsg(<span style='color:#a31515'>$"</span>{nameof(ResetPerfCounterMonitor)}<span style='color:#a31515'> </span>{PerfCounterTypesToShow.ToString()}<span style='color:#a31515'> "</span>);
                _lstPerfCounterData.Clear();
                _dataPoints.Clear();
                _bufferIndex = 0;
                <span style='color:#0000ff'>foreach</span> (PerfCounterType pcntrType <span style='color:#0000ff'>in</span> Enum.GetValues(<span style='color:#0000ff'>typeof</span>(PerfCounterType)))
                {
                    <span style='color:#0000ff'>if</span> (pcntrType != PerfCounterType.None)
                    {
                        <span style='color:#0000ff'>if</span> (PerfCounterTypesToShow.HasFlag(pcntrType))
                        {
                            <span style='color:#0000ff'>var</span> pcounter = GetPerfCounter(pcntrType, pid);
                            <span style='color:#0000ff'>var</span> pcntrData = <span style='color:#0000ff'>new</span> PerfCounterData(pcntrType, pcounter);
                            _lstPerfCounterData.Add(pcntrData);
                        }
                    }
                }

                <span style='color:#0000ff'>for</span> (<span style='color:#0000ff'>int</span> i = 0; i &lt; NumDataPoints; i++)
                {
                    <span style='color:#0000ff'>var</span> emptyList = <span style='color:#0000ff'>new</span> List&lt;<span style='color:#0000ff'>uint</span>&gt;();
                    _lstPerfCounterData.ForEach((s) =&gt; emptyList.Add(0));
                    _dataPoints[i] = emptyList;
                }
            }
            DoPerfCounterMonitoring();
        }
        <span style='color:#0000ff'>void</span> AddDataPoints(List&lt;<span style='color:#0000ff'>uint</span>&gt; lstNewestSample)
        {
            _dataPoints[_bufferIndex++] = lstNewestSample;
            <span style='color:#0000ff'>if</span> (_bufferIndex == _dataPoints.Count)
            {
                _bufferIndex = 0;
            }
            <span style='color:#0000ff'>var</span> task = <span style='color:#0000ff'>this</span>.Dispatcher.BeginInvoke(
                <span style='color:#0000ff'>new</span> Action(() =&gt;
                {
                    <span style='color:#008000'>// this needs to be done on UI thread</span>
                    _chart.Series.Clear();
                    _chart.ChartAreas.Clear();
                    <span style='color:#0000ff'>var</span> chartArea = <span style='color:#0000ff'>new</span> ChartArea(<span style='color:#a31515'>"ChartArea"</span>);
                    _chart.ChartAreas.Add(chartArea);
                    <span style='color:#0000ff'>int</span> ndxSeries = 0;
                    <span style='color:#0000ff'>foreach</span> (var entry <span style='color:#0000ff'>in</span> lstNewestSample)
                    {
                        <span style='color:#0000ff'>var</span> series = <span style='color:#0000ff'>new</span> Series
                        {
                            ChartType = SeriesChartType.Line
                        };
                        _chart.Series.Add(series);
                        <span style='color:#0000ff'>for</span> (<span style='color:#0000ff'>int</span> i = 0; i &lt; _dataPoints.Count; i++)
                        {
                            <span style='color:#0000ff'>var</span> ndx = _bufferIndex + i;
                            <span style='color:#0000ff'>if</span> (ndx &gt;= _dataPoints.Count)
                            {
                                ndx -= _dataPoints.Count;
                            }
                            <span style='color:#0000ff'>var</span> dp = <span style='color:#0000ff'>new</span> DataPoint(i + 1, _dataPoints[ndx][ndxSeries]);
                            series.Points.Add(dp);
                        }
                        ndxSeries++;
                        <span style='color:#0000ff'>if</span> (SetMaxGraphTo100)
                        {
                            _chart.ChartAreas[0].AxisY.Maximum = 100;
                        }
                    }
                    _chart.DataBind();
                }));
        }


        <span style='color:#0000ff'>void</span> DoPerfCounterMonitoring()
        {
            _ctsPcounter = <span style='color:#0000ff'>new</span> CancellationTokenSource();
            _tskDoPerfMonitoring = Task.Run(<span style='color:#0000ff'>async</span> () =&gt;
            {
                <span style='color:#0000ff'>try</span>
                {
                    <span style='color:#0000ff'>while</span> (!_ctsPcounter.Token.IsCancellationRequested)
                    {
                        <span style='color:#0000ff'>var</span> sBuilder = <span style='color:#0000ff'>new</span> StringBuilder();
                        <span style='color:#0000ff'>var</span> lstPCData = <span style='color:#0000ff'>new</span> List&lt;<span style='color:#0000ff'>uint</span>&gt;();
                        <span style='color:#0000ff'>lock</span> (_lstPerfCounterData)
                        {
                            <span style='color:#0000ff'>foreach</span> (var ctr <span style='color:#0000ff'>in</span> _lstPerfCounterData)
                            {
                                <span style='color:#0000ff'>var</span> pcntr = ctr.performanceCounter;
                                <span style='color:#0000ff'>var</span> pcValueAsFloat = pcntr.NextValue();
                                <span style='color:#0000ff'>uint</span> pcValue = 0;
                                <span style='color:#0000ff'>if</span> (ctr.pcntrType.ToString().Contains(<span style='color:#a31515'>"Bytes"</span>) &amp;&amp; !ctr.pcntrType.ToString().Contains(<span style='color:#a31515'>"PerSec"</span>) &amp;&amp; <span style='color:#0000ff'>this</span>.ScaleByteCounters)
                                {
                                    pcValue = (<span style='color:#0000ff'>uint</span>)(pcValueAsFloat * 100 / <span style='color:#0000ff'>uint</span>.MaxValue); <span style='color:#008000'>// '% of 4G</span>
                                }
                                <span style='color:#0000ff'>else</span>
                                {
                                    pcValue = (<span style='color:#0000ff'>uint</span>)pcValueAsFloat;
                                }
                                sBuilder.Append(<span style='color:#a31515'>$"</span>{pcntr.CounterName}<span style='color:#a31515'>=</span>{pcValue:<span style='color:#a31515'>n0</span>}<span style='color:#a31515'>  "</span>);
                                lstPCData.Add(pcValue);
                            }
                            AddDataPoints(lstPCData);
                        }
                        AddStatusMsg(<span style='color:#a31515'>$"Sampling </span>{sBuilder.ToString()}<span style='color:#a31515'>"</span>);
                        <span style='color:#0000ff'>await</span> Task.Delay(UpdateInterval, _ctsPcounter.Token);
                    }
                }
                <span style='color:#0000ff'>catch</span> (TaskCanceledException)
                {
                }
                AddStatusMsg(<span style='color:#a31515'>$"cancelling </span>{nameof(DoPerfCounterMonitoring)}<span style='color:#a31515'>"</span>);
            });
        }

        <span style='color:#0000ff'>public</span> PerformanceCounter GetPerfCounter(PerfCounterType pcntr, <span style='color:#0000ff'>int</span> vspid)
        {
            <span style='color:#0000ff'>var</span> strvalues = _dictPerfCounterDefinitions[pcntr].Split(<span style='color:#a31515'>"|"</span>.ToCharArray());
            <span style='color:#0000ff'>var</span> perfcountCat = strvalues[0];
            <span style='color:#0000ff'>var</span> perfcountName = strvalues[1];
            <span style='color:#0000ff'>var</span> pidstr = strvalues[2];
            PerformanceCounter pc = <span style='color:#0000ff'>null</span>;
            <span style='color:#0000ff'>var</span> category = <span style='color:#0000ff'>new</span> PerformanceCounterCategory(perfcountCat);

            <span style='color:#0000ff'>foreach</span> (var instanceName <span style='color:#0000ff'>in</span> category.GetInstanceNames()) <span style='color:#008000'>// exception if you're not admin or "Performance Monitor Users" group (must re-login)</span>
            {
                <span style='color:#0000ff'>using</span> (<span style='color:#0000ff'>var</span> cntr = <span style='color:#0000ff'>new</span> PerformanceCounter(category.CategoryName, pidstr, instanceName, readOnly: <span style='color:#0000ff'>true</span>))
                {
                    <span style='color:#0000ff'>try</span>
                    {
                        <span style='color:#0000ff'>var</span> val = (<span style='color:#0000ff'>int</span>)cntr.NextValue();
                        <span style='color:#0000ff'>if</span> (val == vspid)
                        {
                            pc = <span style='color:#0000ff'>new</span> PerformanceCounter(perfcountCat, perfcountName, instanceName);
                            <span style='color:#0000ff'>break</span>;
                        }
                    }
                    <span style='color:#0000ff'>catch</span> (Exception)
                    {
                        <span style='color:#008000'>// System.InvalidOperationException: Instance 'IntelliTrace' does not exist in the specified Category.</span>
                    }
                }
            }
            <span style='color:#0000ff'>return</span> pc;
        }

        <span style='color:#0000ff'>void</span> AddStatusMsg(<span style='color:#0000ff'>string</span> msg, <span style='color:#0000ff'>params</span> <span style='color:#0000ff'>object</span>[] args)
        {
            <span style='color:#0000ff'>if</span> (_txtStatus != <span style='color:#0000ff'>null</span>)
            {
                <span style='color:#008000'>// we want to read the threadid </span>
                <span style='color:#008000'>//and time immediately on current thread</span>
                <span style='color:#0000ff'>var</span> dt = <span style='color:#0000ff'>string</span>.Format(<span style='color:#a31515'>"[{0}],{1,2},"</span>,
                    DateTime.Now.ToString(<span style='color:#a31515'>"hh:mm:ss:fff"</span>),
                    Thread.CurrentThread.ManagedThreadId);
                _txtStatus.Dispatcher.BeginInvoke(
                    <span style='color:#0000ff'>new</span> Action(() =&gt;
                    {
                        <span style='color:#008000'>// this action executes on main thread</span>
                        <span style='color:#0000ff'>var</span> str = <span style='color:#0000ff'>string</span>.Format(dt + msg + <span style='color:#a31515'>"\r\n"</span>, args);
                        <span style='color:#008000'>// note: this is a memory leak: can clear periodically</span>
                        _txtStatus.AppendText(str);
                        _txtStatus.ScrollToEnd();
                    }));
            }
        }
    }
}</code></pre></div>
<p>&lt;/Code&gt;</p>]]></content:encoded>
    </item>
    <item>
      <title>Using Async with ManualResetEventSlim</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/using-async-with-manualreseteventslim</link>
      <pubDate>Sat, 29 Sep 2018 01:06:35 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7865</guid>
      <description><![CDATA[When I first started writing programs many years ago, my computer had only one processor and no...]]></description>
      <content:encoded><![CDATA[<p>When I first started writing programs many years ago, my computer had only one processor and no notion of thread, because there was only one. Understanding code for it just meant following one “thread” of execution.</p> <p>I was trying to create a way to queue items to work on in a different thread than the UI thread. I wanted the client thread to be very fast, allowing the expensive processing to be done in the background.<br>It’s easy to create your own dedicated thread, and ThreadPool threads are quite handy.<br>I have some old code that would do this by adding items to a queue and then set a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.manualreseteventslim?view=netframework-4.7.2">ManualResetEventSlim</a> to Signaled. A background thread waits for this event, and upon signaling, would go to work on the items in the queue.<br>However, this pattern consumes a dedicated or ThreadPool Thread to process the incoming events. That particular application was an automatically run test app, so nobody complained about its performance.</p> <p>This can easily be shown by looking at the call stack in the debugger:<br>Using WatiHandle.WaitOne, or similar waits on a thread pool thread causes that thread to be busy waiting and thus consuming one ThreadPool Thread as seen in the debugger.<br>Here, even when using await, the background task says WaitOne, causing the entire thread to block:</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var x = new ManualResetEventSlim();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await Task.Run(() =&gt; x.WaitHandle.WaitOne());</p> <p>mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.WaitHandle.WaitOne()&nbsp;&nbsp;&nbsp; Unknown<br>QueueTest.exe!QueueTest.MainWindow.MainWindow_Loaded.AnonymousMethod__5() Line 89&nbsp;&nbsp;&nbsp; C#<br>mscorlib.dll!System.Threading.Tasks.Task&lt;bool&gt;.InnerInvoke()&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.Tasks.Task.Execute()&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution)&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()&nbsp;&nbsp;&nbsp; Unknown<br>mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()&nbsp;&nbsp;&nbsp; Unknown</p> <p>Consuming a thread includes the entire thread stack (1 Meg by default). Each time a thread is created, every DLL in the process (that doesn’t call&nbsp; <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms682579(v=vs.85).aspx">DisableThreadLibraryCalls</a>) will have its DLLMain called, which means a lot of processing just to initialize a thread.<br>A glance at Task Manager or Process Explorer shows many applications with dozens of threads, include Microsoft Edge and Visual Studio.</p> <p>The number of simultaneous threads that can run at a time is limited to the number of logical processors. All the other threads are dormant. There are perhaps thousands of thread switches at any time on a machine, swapping one thread for another.</p> <p>Using async and await without the WaitOne() and the ilk, a thread can be freed to do other work.</p> <p>Threads should be thought of as a shared resource. Using one dedicated to a particular task can be inefficient.</p> <p>Below is a sample using AyncManualResetEvent, which does not consume any dedicated threads for background processing.</p> <p>&nbsp;</p> <p>See also:<br><a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool.registerwaitforsingleobject?view=netframework-4.7.2">ThreadPool.RegisterWaitForSingleObject&nbsp; Method</a> </p> <p>&lt;code&gt;<br> <pre style="font-family:Consolas;font-size:13px;color:black;background:white">
<span style="color:blue">using</span>&nbsp;System;
<span style="color:blue">using</span>&nbsp;System.Collections.Concurrent;
<span style="color:blue">using</span>&nbsp;System.Collections.Generic;
<span style="color:blue">using</span>&nbsp;System.IO;
<span style="color:blue">using</span>&nbsp;System.Linq;
<span style="color:blue">using</span>&nbsp;System.Text;
<span style="color:blue">using</span>&nbsp;System.Threading;
<span style="color:blue">using</span>&nbsp;System.Threading.Tasks;
<span style="color:blue">using</span>&nbsp;System.Windows;
<span style="color:blue">using</span>&nbsp;System.Windows.Controls;
<span style="color:blue">using</span>&nbsp;System.Windows.Data;
<span style="color:blue">using</span>&nbsp;System.Windows.Documents;
<span style="color:blue">using</span>&nbsp;System.Windows.Input;
<span style="color:blue">using</span>&nbsp;System.Windows.Media;
<span style="color:blue">using</span>&nbsp;System.Windows.Media.Imaging;
<span style="color:blue">using</span>&nbsp;System.Windows.Navigation;
<span style="color:blue">using</span>&nbsp;System.Windows.Shapes;
 
<span style="color:blue">namespace</span>&nbsp;QueueTest
{
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray">///</span><span style="color:green">&nbsp;</span><span style="color:gray">&lt;</span><span style="color:gray">summary</span><span style="color:gray">&gt;</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray">///</span><span style="color:green">&nbsp;Interaction&nbsp;logic&nbsp;for&nbsp;MainWindow.xaml</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:gray">///</span><span style="color:green">&nbsp;</span><span style="color:gray">&lt;/</span><span style="color:gray">summary</span><span style="color:gray">&gt;</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;<span style="color:blue">partial</span>&nbsp;<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">MainWindow</span>&nbsp;:&nbsp;<span style="color:#2b91af">Window</span>
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;MainWindow()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitializeComponent();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">this</span>.Loaded&nbsp;+=&nbsp;MainWindow_Loaded;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">private</span>&nbsp;<span style="color:blue">void</span>&nbsp;MainWindow_Loaded(<span style="color:blue">object</span>&nbsp;sender,&nbsp;<span style="color:#2b91af">RoutedEventArgs</span>&nbsp;e)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">try</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;dp&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">DockPanel</span>();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">this</span>.Content&nbsp;=&nbsp;dp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;spControls&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">StackPanel</span>()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Orientation&nbsp;=&nbsp;<span style="color:#2b91af">Orientation</span>.Vertical
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp.Children.Add(spControls);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;btnGo&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">Button</span>()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Content&nbsp;=&nbsp;<span style="color:#a31515">&quot;_Go&quot;</span>,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HorizontalAlignment&nbsp;=&nbsp;<span style="color:#2b91af">HorizontalAlignment</span>.Left,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;=&nbsp;100
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spControls.Children.Add(btnGo);
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;txtStatus&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">TextBox</span>()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Margin&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">Thickness</span>(10,&nbsp;0,&nbsp;0,&nbsp;0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsReadOnly&nbsp;=&nbsp;<span style="color:blue">true</span>,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Width&nbsp;=&nbsp;900,</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//Height&nbsp;=&nbsp;100,</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MaxHeight&nbsp;=&nbsp;800,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VerticalScrollBarVisibility&nbsp;=&nbsp;<span style="color:#2b91af">ScrollBarVisibility</span>.Auto
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Action</span>&lt;<span style="color:blue">string</span>&gt;&nbsp;addStatusMsg&nbsp;=&nbsp;(str)&nbsp;=&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;=&nbsp;<span style="color:#2b91af">DateTime</span>.Now.ToString(<span style="color:#a31515">&quot;hh:mm:ss.fff&quot;</span>)&nbsp;+&nbsp;<span style="color:#a31515">$&quot;&nbsp;tid=&nbsp;</span>{<span style="color:#2b91af">Thread</span>.CurrentThread.ManagedThreadId}<span style="color:#a31515">&nbsp;</span>{str}<span style="color:#a31515">&quot;</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dispatcher.BeginInvoke(<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">Action</span>(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;()&nbsp;=&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txtStatus.AppendText(<span style="color:#a31515">$&quot;</span>{str}<span style="color:#a31515">\r\n&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txtStatus.ScrollToEnd();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp.LastChildFill&nbsp;=&nbsp;<span style="color:blue">true</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp.Children.Add(txtStatus);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addStatusMsg(<span style="color:#a31515">&quot;We&nbsp;have&nbsp;2&nbsp;queues:&nbsp;one&nbsp;for&nbsp;normal&nbsp;telemetry&nbsp;and&nbsp;one&nbsp;for&nbsp;notification&nbsp;service&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;queueNotifications&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">ConcurrentQueue</span>&lt;<span style="color:blue">string</span>&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">CancellationTokenSource</span>&nbsp;tks&nbsp;=&nbsp;<span style="color:blue">null</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">bool</span>&nbsp;fIsRunning&nbsp;=&nbsp;<span style="color:blue">false</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">int</span>&nbsp;itemToQueue&nbsp;=&nbsp;0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;evntNewItemAvailable&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">AsyncManualResetEvent</span>();
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;btnGo.Click&nbsp;+=&nbsp;(ob,&nbsp;eb)&nbsp;=&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>&nbsp;(!fIsRunning)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tks&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">CancellationTokenSource</span>();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Task</span>.Run(<span style="color:blue">async</span>&nbsp;()&nbsp;=&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">while</span>&nbsp;(!tks.Token.IsCancellationRequested)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addStatusMsg(<span style="color:#a31515">$&quot;awaiting&nbsp;notification&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">await</span>&nbsp;evntNewItemAvailable.WaitAsync();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">while</span>&nbsp;(queueNotifications.Count()&nbsp;&gt;&nbsp;0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>&nbsp;(queueNotifications.TryDequeue(<span style="color:blue">out</span>&nbsp;<span style="color:blue">var</span>&nbsp;result))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addStatusMsg(<span style="color:#a31515">$&quot;notification&nbsp;processed&nbsp;</span>{result}<span style="color:#a31515">&nbsp;&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evntNewItemAvailable.Reset();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addStatusMsg(<span style="color:#a31515">&quot;end&nbsp;task&nbsp;notification&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Task</span>.Run(<span style="color:blue">async</span>&nbsp;()&nbsp;=&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;simulate&nbsp;incoming&nbsp;notifications&nbsp;by&nbsp;putting&nbsp;them&nbsp;into&nbsp;the&nbsp;queue&nbsp;periodically</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">while</span>&nbsp;(!tks.Token.IsCancellationRequested)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">await</span>&nbsp;<span style="color:#2b91af">Task</span>.Delay(<span style="color:#2b91af">TimeSpan</span>.FromMilliseconds(1),&nbsp;tks.Token);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>&nbsp;(!tks.IsCancellationRequested)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;newitem&nbsp;=&nbsp;++itemToQueue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addStatusMsg(<span style="color:#a31515">$&quot;Queuing&nbsp;new&nbsp;notification&nbsp;</span>{newitem}<span style="color:#a31515">&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;we&nbsp;add&nbsp;the&nbsp;item&nbsp;to&nbsp;2&nbsp;queues</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queueNotifications.Enqueue(newitem.ToString());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evntNewItemAvailable.Set();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">else</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evntNewItemAvailable.Set();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tks.Cancel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addStatusMsg(<span style="color:#a31515">&quot;Canceling&quot;</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fIsRunning&nbsp;=&nbsp;!fIsRunning;
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">catch</span>&nbsp;(<span style="color:#2b91af">Exception</span>&nbsp;ex)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">this</span>.Content&nbsp;=&nbsp;ex.ToString();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;https://blogs.msdn.microsoft.com/pfxteam/2012/02/11/building-async-coordination-primitives-part-1-asyncmanualresetevent/</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">internal</span>&nbsp;<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">AsyncManualResetEvent</span>
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">private</span>&nbsp;<span style="color:blue">volatile</span>&nbsp;<span style="color:#2b91af">TaskCompletionSource</span>&lt;<span style="color:blue">bool</span>&gt;&nbsp;tcs&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">TaskCompletionSource</span>&lt;<span style="color:blue">bool</span>&gt;();
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;<span style="color:#2b91af">Task</span>&nbsp;WaitAsync()&nbsp;=&gt;&nbsp;<span style="color:blue">this</span>.tcs.Task;
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;<span style="color:blue">void</span>&nbsp;Set()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;https://stackoverflow.com/questions/12693046/configuring-the-continuation-behaviour-of-a-taskcompletionsources-task</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Task</span>.Run(()&nbsp;=&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">this</span>.tcs.TrySetResult(<span style="color:blue">true</span>));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">public</span>&nbsp;<span style="color:blue">void</span>&nbsp;Reset()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">while</span>&nbsp;(<span style="color:blue">true</span>)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">var</span>&nbsp;tcs&nbsp;=&nbsp;<span style="color:blue">this</span>.tcs;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">if</span>&nbsp;(!tcs.Task.IsCompleted&nbsp;||
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#2b91af">Interlocked</span>.CompareExchange(<span style="color:blue">ref</span>&nbsp;<span style="color:blue">this</span>.tcs,&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">TaskCompletionSource</span>&lt;<span style="color:blue">bool</span>&gt;(),&nbsp;tcs)&nbsp;==&nbsp;tcs)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:blue">return</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
}
 
</pre>&lt;/code&gt;</p>]]></content:encoded>
    </item>
    <item>
      <title>Use reflection to get assembly type and method sizes for comparison</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/use-reflection-to-get-assembly-type-and-method-sizes-for-comparison</link>
      <pubDate>Fri, 31 Aug 2018 00:06:04 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7845</guid>
      <description><![CDATA[I wanted to know what changed between two versions of a managed assembly. Software changes over...]]></description>
      <content:encoded><![CDATA[<p>I wanted to know what changed between two versions of a managed assembly. Software changes over time, and seeing what changed can be important in understanding behavior.<br>So I wrote a little program to show the assembly contents, sorted by size, showing the size of various components such as classes and methods.</p> <p>Because it doesn’t look at things like static members, manifests, etc.&nbsp; It’s not complete, and left as an exercise to the reader.</p> <p>Note how it calculates each node’s cost by summing it’s children, then uses the size as a sort description.</p> <p><br>&lt;code&gt; </p> <pre style="font-family:Consolas;font-size:13px;color:black;background:white"><span style="color:blue">using</span>&nbsp;System;
<span style="color:blue">using</span>&nbsp;System.Reflection;
<span style="color:blue">using</span>&nbsp;System.Collections.Generic;
<span style="color:blue">using</span>&nbsp;System.Linq;
<span style="color:blue">using</span>&nbsp;System.Text;
<span style="color:blue">using</span>&nbsp;System.Threading.Tasks;
<span style="color:blue">using</span>&nbsp;System.Windows;
<span style="color:blue">using</span>&nbsp;System.Windows.Controls;
<span style="color:blue">using</span>&nbsp;System.Windows.Data;
<span style="color:blue">using</span>&nbsp;System.Windows.Documents;
<span style="color:blue">using</span>&nbsp;System.Windows.Input;
<span style="color:blue">using</span>&nbsp;System.Windows.Media;
<span style="color:blue">using</span>&nbsp;System.Windows.Media.Imaging;
<span style="color:blue">using</span>&nbsp;System.Windows.Navigation;
<span style="color:blue">using</span>&nbsp;System.Windows.Shapes;
<span style="color:blue">using</span>&nbsp;System.Runtime.InteropServices;
<span style="color:blue">using</span>&nbsp;System.Diagnostics;
 
<span style="color:green">//&nbsp;Start&nbsp;Visual&nbsp;Studio,&nbsp;File-&gt;New-&gt;Project-&gt;C#,&nbsp;WPF&nbsp;Application.&nbsp;call&nbsp;it&nbsp;&quot;MgdCodeSize&quot;</span>
<span style="color:green">//&nbsp;Replace&nbsp;MainWindow.xaml.cs&nbsp;wtih&nbsp;this&nbsp;content</span>
 
<span style="color:blue">namespace</span>&nbsp;MgdCodeSize
{
	<span style="color:gray">///</span><span style="color:green">&nbsp;</span><span style="color:gray">&lt;</span><span style="color:gray">summary</span><span style="color:gray">&gt;</span>
	<span style="color:gray">///</span><span style="color:green">&nbsp;Interaction&nbsp;logic&nbsp;for&nbsp;MainWindow.xaml</span>
	<span style="color:gray">///</span><span style="color:green">&nbsp;</span><span style="color:gray">&lt;/</span><span style="color:gray">summary</span><span style="color:gray">&gt;</span>
	<span style="color:blue">public</span>&nbsp;<span style="color:blue">partial</span>&nbsp;<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">MainWindow</span>&nbsp;:&nbsp;Window
	{
		<span style="color:blue">public</span>&nbsp;MainWindow()
		{
			InitializeComponent();
			<span style="color:blue">this</span>.Loaded&nbsp;+=&nbsp;MainWindow_Loaded;
			<span style="color:blue">this</span>.WindowState&nbsp;=&nbsp;WindowState.Maximized;
		}
 
		<span style="color:blue">public</span>&nbsp;<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">MyTreeViewItem</span>&nbsp;:&nbsp;TreeViewItem
		{
			<span style="color:blue">public</span>&nbsp;<span style="color:blue">int</span>&nbsp;size&nbsp;{&nbsp;<span style="color:blue">get</span>;&nbsp;<span style="color:blue">set</span>;&nbsp;}
			<span style="color:blue">string</span>&nbsp;_name;
			<span style="color:blue">public</span>&nbsp;MyTreeViewItem(<span style="color:blue">string</span>&nbsp;name)
			{
				<span style="color:blue">this</span>._name&nbsp;=&nbsp;name;
			}
			<span style="color:blue">public</span>&nbsp;<span style="color:blue">void</span>&nbsp;CalcHeader(<span style="color:blue">bool</span>&nbsp;expand&nbsp;=&nbsp;<span style="color:blue">true</span>)
			{
				<span style="color:blue">foreach</span>&nbsp;(<span style="color:#2b91af">MyTreeViewItem</span>&nbsp;child&nbsp;<span style="color:blue">in</span>&nbsp;<span style="color:blue">this</span>.Items)
				{
					<span style="color:blue">this</span>.size&nbsp;+=&nbsp;child.size;
				}
				<span style="color:blue">var</span>&nbsp;sp&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;StackPanel()
				{
					Orientation&nbsp;=&nbsp;Orientation.Horizontal
				};
				sp.Children.Add(<span style="color:blue">new</span>&nbsp;TextBox()
				{
					Text&nbsp;=&nbsp;size.ToString()
				});
				sp.Children.Add(<span style="color:blue">new</span>&nbsp;TextBox()
				{
					Text&nbsp;=&nbsp;_name
				});
				<span style="color:blue">this</span>.Header&nbsp;=&nbsp;sp;
				<span style="color:blue">this</span>.Items.SortDescriptions.Add(<span style="color:blue">new</span>&nbsp;System.ComponentModel.SortDescription(<span style="color:#a31515">&quot;size&quot;</span>,&nbsp;System.ComponentModel.<span style="color:#2b91af">ListSortDirection</span>.Descending));
				<span style="color:blue">if</span>&nbsp;(expand)
				{
					<span style="color:blue">this</span>.IsExpanded&nbsp;=&nbsp;<span style="color:blue">true</span>;
				}
			}
			<span style="color:blue">public</span>&nbsp;<span style="color:blue">override</span>&nbsp;<span style="color:blue">string</span>&nbsp;ToString()
			{
				<span style="color:blue">return</span>&nbsp;<span style="color:#a31515">$&quot;</span>{<span style="color:blue">this</span>.size}<span style="color:#a31515">&nbsp;</span>{<span style="color:blue">this</span>._name}<span style="color:#a31515">&quot;</span>;
			}
		}
		<span style="color:blue">private</span>&nbsp;<span style="color:blue">void</span>&nbsp;MainWindow_Loaded(<span style="color:blue">object</span>&nbsp;sender,&nbsp;RoutedEventArgs&nbsp;e)
		{
			<span style="color:blue">try</span>
			{
				<span style="color:blue">var</span>&nbsp;filename&nbsp;=&nbsp;<span style="color:maroon">@&quot;C:\Program&nbsp;Files&nbsp;(x86)\Microsoft&nbsp;Visual&nbsp;Studio\Preview\Enterprise\Common7\IDE\EntityFramework.dll&quot;</span>;
				<span style="color:blue">var</span>&nbsp;asm&nbsp;=&nbsp;<span style="color:#2b91af">Assembly</span>.LoadFrom(filename);
				<span style="color:blue">var</span>&nbsp;tv&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;TreeView();
				<span style="color:blue">this</span>.Content&nbsp;=&nbsp;tv;
				<span style="color:blue">var</span>&nbsp;tvFileNode&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">MyTreeViewItem</span>(filename);
				tv.Items.Add(tvFileNode);
				<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">var</span>&nbsp;module&nbsp;<span style="color:blue">in</span>&nbsp;asm.Modules)
				{
					<span style="color:blue">var</span>&nbsp;tvModuleNode&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">MyTreeViewItem</span>(module.Name);
					tvFileNode.Items.Add(tvModuleNode);
 
					<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">var</span>&nbsp;type&nbsp;<span style="color:blue">in</span>&nbsp;module.GetTypes())
					{
						<span style="color:blue">var</span>&nbsp;tvTypeNode&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">MyTreeViewItem</span>(type.Name);
						tvModuleNode.Items.Add(tvTypeNode);
						<span style="color:blue">var</span>&nbsp;methods&nbsp;=&nbsp;type.GetMethods(<span style="color:#2b91af">BindingFlags</span>.NonPublic&nbsp;|&nbsp;<span style="color:#2b91af">BindingFlags</span>.Public&nbsp;|&nbsp;<span style="color:#2b91af">BindingFlags</span>.Instance);
						<span style="color:blue">foreach</span>&nbsp;(<span style="color:blue">var</span>&nbsp;method&nbsp;<span style="color:blue">in</span>&nbsp;methods)
						{
							<span style="color:blue">var</span>&nbsp;methodBody&nbsp;=&nbsp;method.GetMethodBody();
							<span style="color:blue">var</span>&nbsp;bytes&nbsp;=&nbsp;methodBody?.GetILAsByteArray();
							<span style="color:blue">var</span>&nbsp;tvMethodNode&nbsp;=&nbsp;<span style="color:blue">new</span>&nbsp;<span style="color:#2b91af">MyTreeViewItem</span>(method.Name);
							<span style="color:blue">if</span>&nbsp;(bytes&nbsp;!=&nbsp;<span style="color:blue">null</span>)
							{
								<span style="color:blue">var</span>&nbsp;numbytes&nbsp;=&nbsp;bytes.Length;
								tvMethodNode.size&nbsp;=&nbsp;numbytes;
								tvTypeNode.Items.Add(tvMethodNode);
							}
							tvMethodNode.CalcHeader(expand:&nbsp;<span style="color:blue">false</span>);
						}
						tvTypeNode.CalcHeader(expand:&nbsp;<span style="color:blue">false</span>);
					}
					tvModuleNode.CalcHeader();
				}
				tvFileNode.CalcHeader();
 
			}
			<span style="color:blue">catch</span>&nbsp;(<span style="color:#2b91af">Exception</span>&nbsp;ex)
			{
				<span style="color:blue">this</span>.Content&nbsp;=&nbsp;ex.ToString();
			}
		}
	}
}
</pre>
&lt;/code&gt;]]></content:encoded>
    </item>
    <item>
      <title>Detouring code</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/detouring-code</link>
      <pubDate>Thu, 26 Jul 2018 22:49:13 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7835</guid>
      <description><![CDATA[&nbsp; Microsoft Detours from Microsoft Research is a powerful technology to intercept operating...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;</p> <p>Microsoft Detours from Microsoft Research is a powerful technology to intercept operating system function calls and detour the call to your own code. This enables:&nbsp; <br>1.&nbsp;&nbsp;&nbsp; Diagnostics: you can log callers, parameters<br>2.&nbsp;&nbsp;&nbsp; Replace functionality completely: the caller calls the WinAPI “MessageBox”, but it calls your version instead.<br>3.&nbsp;&nbsp;&nbsp; Modify functionality: perhaps change some parameters to the call to change behavior.</p> <p>The source code for Detours is <a href="https://github.com/Microsoft/Detours">https://github.com/Microsoft/Detours</a><br><font color="#c0504d">Sample code below shows a window with a Button to invoke MessageBox, and a checkbox to toggle Detouring to a private implementation of MessageBox:<br>Start Visual Studio<br>File-&gt;New-&gt;Project-&gt;C++ Desktop Application. Call it "DetourSample"<br>Replace the entire DetourSample.cpp with this code.</font></p> <p><br>Set a breakpoint on the call to MessageBoxA. Hit F5 to build and run, and don’t click the Detour Checkbox yet.<br>Click on the MessageBox button to reach the breakpoint.<br>Then hit Ctrl-F11 (Show Disassembly) to see the disassembly of the code in a few columns: First the address, then the machine code bytes (you may need to right-click-&gt;Show Code Bytes), then the Assembly code instructions and lastly the operands.</p> <p>Notice that there are 4 push instructions, corresponding to the 4 parameters of MessageBoxA, in right to left order. Then comes the call to __imp__MessageBoxA@16<br>You can single step the assembly code and watch how the registers change values (Debug-&gt;Windows-&gt;Registers) (You may have to disable Tools-&gt;Options-&gt;Debugging-&gt;General-&gt;Just My Code)</p> <p><font size="2" face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBoxA(_hWnd, "Some Text", g_szArch, MB_OK);<br>013B9710 8B F4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esi,esp&nbsp; <br>013B9712 6A 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; <br>013B9714 68 44 D0 3C 01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset g_szArch (013CD044h)&nbsp; <br>013B9719 68 60 A1 3C 01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; offset string "Some Text" (013CA160h)&nbsp; <br>013B971E 8B 45 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [this]&nbsp; <br>013B9721 8B 88 94 01 00 00&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx,dword ptr [eax+194h]&nbsp; <br>013B9727 51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx&nbsp; <br>013B9728 FF 15 68 E1 3C 01&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [__imp__MessageBoxA@16 (013CE168h)]</font>&nbsp; </p> <p><br>Notice how the address of __imp_MessageBoxA@16 is 013CE168, and that the code bytes for that instruction are&nbsp; “FF 15” + “68 E1 3C 01”&nbsp; and the 2nd part is the address in Little Endian order (68 E1 3C 01 == 013CE168).<br>Debug-&gt;Windows-&gt;view-&gt;Memory 1 to show the memory window, then drag the “0x013CE168” to the Address of the window (you’ll need to right-click on the Memory Window and show as 4-byte integer)<br>This shows a portion of the import address table and the content of 013CE168 is 75b58830</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/07/image.gif"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/07/image_thumb.gif" width="602" height="133"></a><br></p> <p>Debug-&gt;Windows-&gt;Modules, and look for User32.dll. It shows the Address as 75AD0000-75C2F000, which includes our 75b58830,which is the entry point to User32!MessageBoxA</p> <p>Another way to see this: from a Command prompt, run this to create a VS Developer prompt (adjust the path to your install path):<br>“C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\vc\Auxiliary\Build\vcvars32.bat”<br>Then type: link /dump /exports c:\windows\SysWow64\user32.dll | find “MessageBoxA”<br>This shows the user32.dll export of MessageBoxA , and the relative address. The last few hex digits of the result are “8830”<br>(Note: due to Windows Updates and different versions of windows, your numbers will probably be different from mine.)</p> <p>When you step into the MessageBoxA function, you see the entire MessageBoxA function from User32.dll (it’s small because it just re-pushes the parameters and forwards to another function (notice the addition of a new parameter, 0)<br>Extra points if you can name that function</p> <p><font face="Courier New">75B58830 8B FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi,edi&nbsp; <br>75B58832 55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp&nbsp; <br>75B58833 8B EC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp,esp&nbsp; <br>75B58835 6A 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; <br>75B58837 FF 75 14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+14h]&nbsp; <br>75B5883A FF 75 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+10h]&nbsp; <br>75B5883D FF 75 0C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+0Ch]&nbsp; <br>75B58840 FF 75 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+8]&nbsp; <br>75B58843 E8 18 00 00 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 75B58860&nbsp; <br>75B58848 5D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp&nbsp; <br>75B58849 C2 10 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10h</font>&nbsp; </p> <p>&nbsp;</p> <p>For detours to work, the beginning of the MessageBoxA function must be replaced with a jmp instruction to the detoured function.<br>We can’t just replace instructions and expect the function to continue working: we need to still execute the replaced instructions. Where do we put them? User32.dll is laid out in memory exactly, and we can’t just squeeze in a few bytes. So we need to allocate some memory.</p> <p>Click the Detour checkbox, then do the MessageBox again. The import address table hasn’t changed, so we still go to 75b58830:</p> <p><font face="Courier New">75B58830 E9 43 88 85 8B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MyMessageBoxA (013B1078h)&nbsp; <br>75B58835 6A 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; <br>75B58837 FF 75 14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+14h]&nbsp; <br>75B5883A FF 75 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+10h]&nbsp; <br>75B5883D FF 75 0C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+0Ch]&nbsp; <br>75B58840 FF 75 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp+8]&nbsp; <br>75B58843 E8 18 00 00 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 75B58860&nbsp; <br>75B58848 5D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp&nbsp; <br>75B58849 C2 10 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10h</font>&nbsp; </p> <p>Notice that there are 5 new bytes: a Long jmp instruction to the detoured version of MessageBoxA called MyMessageBoxA. The rest of the function is unchanged.<br>Those 5 new bytes replaced the first 3 original instructions: <br><font face="Courier New">75B58830 8B FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi,edi&nbsp; <br>75B58832 55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp&nbsp; <br>75B58833 8B EC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp,esp&nbsp; </font></p> <p>&nbsp;</p> <p>The detoured version does its thing, then calls the real version via g_real_MessageBoxA, which now points to the memory allocated for the detour, which contains this:</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/07/image1.gif"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/07/image_thumb1.gif" width="812" height="88"></a><br></p> <p>&nbsp;</p> <p>And at the 6DB400D8 address we find the instructions that were replaced, plus a long jmp back to where we left off at 75B58835: (which is the instruction right after the detour jump)</p> <p><font face="Courier New">6DB400D8 8B FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edi,edi&nbsp; <br>6DB400DA 55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp&nbsp; <br>6DB400DB 8B EC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp,esp&nbsp; <br>6DB400DD E9 53 87 01 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 75B58835</font>&nbsp; </p> <p>So now we see why it’s called a detour: we took a side trip and came back to where we’re supposed to be.<br>Of course the detoured function can do all sorts of things, like:<br>1.&nbsp;&nbsp;&nbsp; Change the parameters or return value before or after the call<br>2.&nbsp;&nbsp;&nbsp; Not call the original function at all (could cause a crash)<br>3.&nbsp;&nbsp;&nbsp; Record information about the function call.</p> <p>Possible Problems:<br>1.&nbsp;&nbsp;&nbsp; Suppose you’re in the middle of replacing the 5 bytes of a function, when another thread tries to execute that function when only 4 bytes have been replaced? It goes off into random memory somewhere and crashes. You could suspend threads and then patch the thread stacks for each detour. (VS used to do this)<br>2.&nbsp;&nbsp;&nbsp; If the API you want to detour isn’t loaded in memory&nbsp; yet, it can still be detoured. You can detour any function for which you know the function signature and address. You can get the address via calling LoadLibrary, GetProcAddress. Even if you don’t know the signature, if you know the parameter sizes, and calling convention, you can detour the function successfully.<br>3.&nbsp;&nbsp;&nbsp; Suppose you want to detour from various component DLLs in a single app. Each detour will allocate its own memory to store the detours. Because each memory region needs to have certain rights, each region is allocated via VirtualAlloc, which uses a minimum 64k for a 32 bit process. That means if 3 DLLs are detouring, that’s using 3 * 64K = 192K Virtual Address space. Visual Studio used to do this.</p> <p>Possible Expansions:<br>1.&nbsp;&nbsp;&nbsp; Put your detour code into a DLL, then inject that DLL into another process. <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2012/06/27/increase-the-memory-available-to-your-tests/">MemSpect</a> does this.<br>2.&nbsp;&nbsp;&nbsp; Have your detoured functions collect information and communicate that data to another process so you can “spy” on the target process. <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2012/06/27/increase-the-memory-available-to-your-tests/">MemSpect</a> does this.<br>3.&nbsp;&nbsp;&nbsp; Combine detours with <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2014/01/30/create-your-own-clr-profiler/">CLR Profiler</a> APIs. Guess what?&nbsp; <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2012/06/27/increase-the-memory-available-to-your-tests/">MemSpect</a> does this too.<br></p>  <p>&nbsp;</p> <p>&lt;Code Sample&gt;</p> <pre style="font-family:Consolas;font-size:13px;color:black;background:white"><span style="color:green">//&nbsp;DetourSample.cpp&nbsp;:&nbsp;Defines&nbsp;the&nbsp;entry&nbsp;point&nbsp;for&nbsp;the&nbsp;application.</span>
<span style="color:green">//</span>
 
<span style="color:gray">#include</span>&nbsp;<span style="color:#a31515">&quot;stdafx.h&quot;</span>
<span style="color:gray">#include</span>&nbsp;<span style="color:#a31515">&quot;DetourSample.h&quot;</span>
<span style="color:gray">#include</span>&nbsp;<span style="color:#a31515">&lt;string&gt;</span>
<span style="color:green">/*</span>
<span style="color:green">Start&nbsp;Visual&nbsp;Studio</span>
<span style="color:green">File-&gt;New-&gt;Project-&gt;C++&nbsp;Desktop&nbsp;Application.&nbsp;Call&nbsp;it&nbsp;&quot;DetourSample&quot;</span>
<span style="color:green">Replace&nbsp;the&nbsp;entire&nbsp;DetourSample.cpp&nbsp;with&nbsp;this&nbsp;code.</span>
 
<span style="color:green">From&nbsp;https://github.com/Microsoft/Detours&nbsp;copy&nbsp;4&nbsp;files:&nbsp;detours.h,&nbsp;detours.cpp,&nbsp;disasm.cpp,&nbsp;Modules.cpp&nbsp;next&nbsp;to&nbsp;this&nbsp;file</span>
<span style="color:green">Include&nbsp;the&nbsp;3&nbsp;.cpp&nbsp;files&nbsp;in&nbsp;the&nbsp;project&nbsp;(Solution&nbsp;Explorer-&gt;Show&nbsp;all&nbsp;files-&gt;Right&nbsp;click-&gt;Include&nbsp;in&nbsp;Project)</span>
<span style="color:green">Need&nbsp;to&nbsp;turn&nbsp;off&nbsp;precompiled&nbsp;headers&nbsp;for&nbsp;all&nbsp;configurations&nbsp;(both&nbsp;debug/release,&nbsp;32&nbsp;bit,&nbsp;64&nbsp;bit).&nbsp;Project-&gt;Properties-&gt;Configuration-&gt;C/C++-&gt;PrecompiledHeaders-&gt;Not&nbsp;using&nbsp;PrecompiledHeaders</span>
<span style="color:green">Many&nbsp;C++&nbsp;projects&nbsp;consist&nbsp;of&nbsp;lots&nbsp;of&nbsp;C++&nbsp;files,&nbsp;which&nbsp;have&nbsp;many&nbsp;#include&nbsp;at&nbsp;the&nbsp;top.&nbsp;Each&nbsp;#include&nbsp;file&nbsp;needs&nbsp;to&nbsp;be&nbsp;expanded&nbsp;and&nbsp;compiled&nbsp;for&nbsp;each&nbsp;C++&nbsp;file.</span>
<span style="color:green">The&nbsp;PrecompiledHeaders&nbsp;option&nbsp;specifies&nbsp;an&nbsp;included&nbsp;file&nbsp;name&nbsp;like&nbsp;&quot;windows.h&quot;.&nbsp;Every&nbsp;C++&nbsp;file&nbsp;is&nbsp;assumed&nbsp;to&nbsp;be&nbsp;identical&nbsp;up&nbsp;to&nbsp;the&nbsp;line&nbsp;that&nbsp;includes&nbsp;&quot;windows.h&quot;</span>
<span style="color:green">This&nbsp;allows&nbsp;that&nbsp;identical&nbsp;part&nbsp;to&nbsp;be&nbsp;precompiled&nbsp;into&nbsp;a&nbsp;.pch&nbsp;file&nbsp;on&nbsp;disk,&nbsp;which&nbsp;is&nbsp;only&nbsp;needed&nbsp;to&nbsp;be&nbsp;done&nbsp;once&nbsp;for&nbsp;all&nbsp;the&nbsp;C++&nbsp;files.</span>
<span style="color:green">Works&nbsp;in&nbsp;64&nbsp;bit&nbsp;and&nbsp;32&nbsp;bit:&nbsp;Build-&gt;Configuration-&gt;Active&nbsp;Solution&nbsp;Platform-&gt;x86&nbsp;or&nbsp;x64</span>
 
 
<span style="color:green">*/</span>
<span style="color:gray">#ifdef</span>&nbsp;_WIN64
<span style="color:blue">char</span>&nbsp;g_szArch[]&nbsp;=&nbsp;<span style="color:#a31515">&quot;x64&nbsp;64&nbsp;bit&quot;</span>;
<span style="color:gray">#define</span>&nbsp;_X86_
<span style="color:gray">#else</span>
<span style="color:blue">char</span>&nbsp;g_szArch[]&nbsp;=&nbsp;<span style="color:#a31515">&quot;x86&nbsp;32&nbsp;bit&quot;</span>;
<span style="color:gray">#endif</span>
<span style="color:gray">#include</span>&nbsp;<span style="color:#a31515">&quot;detours.h&quot;</span>
 
<span style="color:blue">using</span>&nbsp;<span style="color:blue">namespace</span>&nbsp;std;
 
<span style="color:gray">#define</span>&nbsp;<span style="color:#6f008a">MAX_LOADSTRING</span>&nbsp;100
 
<span style="color:blue">class</span>&nbsp;<span style="color:#2b91af">CMyApplication</span>;
<span style="color:#2b91af">CMyApplication</span>&nbsp;*&nbsp;g_CMyApplication;
 
<span style="color:green">//&nbsp;Forward&nbsp;declarations&nbsp;of&nbsp;functions&nbsp;included&nbsp;in&nbsp;this&nbsp;code&nbsp;module:</span>
LRESULT&nbsp;CALLBACK&nbsp;WindowProcedure(HWND,&nbsp;UINT,&nbsp;WPARAM,&nbsp;LPARAM);
 
<span style="color:green">/*</span>
<span style="color:green">Many&nbsp;windows&nbsp;API&nbsp;functions&nbsp;that&nbsp;require&nbsp;a&nbsp;string&nbsp;parameter&nbsp;have&nbsp;2&nbsp;versions:&nbsp;an&nbsp;A&nbsp;(for&nbsp;ANSI)&nbsp;and&nbsp;W&nbsp;(for&nbsp;Wide&nbsp;Unicode)&nbsp;strings.</span>
<span style="color:green">For&nbsp;example,&nbsp;MessageBoxA&nbsp;and&nbsp;MessageBoxW.</span>
<span style="color:green">If&nbsp;you&nbsp;just&nbsp;call&nbsp;MessageBox,&nbsp;the&nbsp;relevant&nbsp;header&nbsp;(WinUser.h)&nbsp;contains:</span>
<span style="color:green">#ifdef&nbsp;UNICODE</span>
<span style="color:green">#define&nbsp;MessageBox&nbsp;&nbsp;MessageBoxW</span>
<span style="color:green">#else</span>
<span style="color:green">#define&nbsp;MessageBox&nbsp;&nbsp;MessageBoxA</span>
<span style="color:green">#endif&nbsp;//&nbsp;!UNICODE</span>
 
<span style="color:green">Detouring&nbsp;the&nbsp;W&nbsp;version&nbsp;might&nbsp;detour&nbsp;both&nbsp;the&nbsp;W&nbsp;and&nbsp;the&nbsp;A&nbsp;version&nbsp;because&nbsp;the&nbsp;A&nbsp;version&nbsp;might&nbsp;just&nbsp;convert&nbsp;to&nbsp;W&nbsp;and&nbsp;call&nbsp;the&nbsp;W&nbsp;version.</span>
<span style="color:green">That&#039;s&nbsp;not&nbsp;true&nbsp;with&nbsp;MessageBoxA&nbsp;and&nbsp;MessageBoxW.&nbsp;MessageBoxA&nbsp;on&nbsp;Win10&nbsp;converts&nbsp;to&nbsp;unicode&nbsp;and&nbsp;then&nbsp;calls&nbsp;(undocumented)&nbsp;MessageBoxTimeOutW</span>
<span style="color:green">We&nbsp;can&nbsp;look&nbsp;at&nbsp;the&nbsp;exports&nbsp;of&nbsp;user32.dll&nbsp;from&nbsp;a&nbsp;VS&nbsp;command&nbsp;prompt:</span>
<span style="color:green">C:\&gt;link&nbsp;/dump&nbsp;/exports&nbsp;\Windows\System32\user32.dll&nbsp;|&nbsp;find&nbsp;/i&nbsp;&quot;messagebo&quot;</span>
<span style="color:green">2149&nbsp;&nbsp;282&nbsp;0006F000&nbsp;MessageBoxA</span>
<span style="color:green">2150&nbsp;&nbsp;283&nbsp;0006F060&nbsp;MessageBoxExA</span>
<span style="color:green">2151&nbsp;&nbsp;284&nbsp;0006F090&nbsp;MessageBoxExW</span>
<span style="color:green">2152&nbsp;&nbsp;285&nbsp;0006F0C0&nbsp;MessageBoxIndirectA</span>
<span style="color:green">2153&nbsp;&nbsp;286&nbsp;0006F260&nbsp;MessageBoxIndirectW</span>
<span style="color:green">2154&nbsp;&nbsp;287&nbsp;0006F320&nbsp;MessageBoxTimeoutA</span>
<span style="color:green">2155&nbsp;&nbsp;288&nbsp;0006F470&nbsp;MessageBoxTimeoutW</span>
<span style="color:green">2156&nbsp;&nbsp;289&nbsp;0006F640&nbsp;MessageBoxW</span>
<span style="color:green">2408&nbsp;&nbsp;387&nbsp;0006F6A0&nbsp;SoftModalMessageBox</span>
<span style="color:green">*/</span>
 
 
<span style="color:green">//&nbsp;decltype&nbsp;is&nbsp;like&nbsp;typeof()</span>
<span style="color:green">//&nbsp;initialize&nbsp;a&nbsp;pointer&nbsp;to&nbsp;the&nbsp;real&nbsp;version&nbsp;of&nbsp;the&nbsp;API</span>
<span style="color:blue">decltype</span>(&amp;MessageBoxA)&nbsp;g_real_MessageBoxA&nbsp;=&nbsp;&amp;MessageBoxA;
<span style="color:blue">decltype</span>(&amp;MessageBoxW)&nbsp;g_real_MessageBoxW&nbsp;=&nbsp;&amp;MessageBoxW;
 
<span style="color:green">//&nbsp;here&nbsp;is&nbsp;my&nbsp;implementation&nbsp;that&nbsp;will&nbsp;be&nbsp;called&nbsp;when&nbsp;detoured.</span>
<span style="color:blue">int</span>&nbsp;WINAPI&nbsp;MyMessageBoxA(
	<span style="color:#6f008a">_In_opt_</span>&nbsp;HWND&nbsp;hWnd,
	<span style="color:#6f008a">_In_opt_</span>&nbsp;LPCSTR&nbsp;lpText,
	<span style="color:#6f008a">_In_opt_</span>&nbsp;LPCSTR&nbsp;lpCaption,
	<span style="color:#6f008a">_In_</span>&nbsp;UINT&nbsp;uType)
{
	string&nbsp;caption(lpCaption);
	caption&nbsp;+=&nbsp;<span style="color:#a31515">&quot;&nbsp;The&nbsp;detoured&nbsp;version&nbsp;of&nbsp;MessageboxA&quot;</span>;
	string&nbsp;text(lpText);
	text&nbsp;+=&nbsp;<span style="color:#a31515">&quot;&nbsp;hi&nbsp;from&nbsp;detoured&nbsp;version&quot;</span>;
	<span style="color:green">//&nbsp;we&nbsp;now&nbsp;call&nbsp;the&nbsp;real&nbsp;implementation&nbsp;of&nbsp;MessageBox.</span>
	<span style="color:green">//&nbsp;(we&nbsp;could&nbsp;log&nbsp;various&nbsp;things&nbsp;about&nbsp;detoured&nbsp;API&nbsp;calls,&nbsp;such&nbsp;as</span>
	<span style="color:green">//&nbsp;&nbsp;&nbsp;the&nbsp;callstack&nbsp;and&nbsp;the&nbsp;return&nbsp;value)</span>
	<span style="color:blue">return</span>&nbsp;g_real_MessageBoxA(hWnd,&nbsp;text.c_str(),&nbsp;caption.c_str(),&nbsp;uType);
}
 
<span style="color:blue">int</span>&nbsp;WINAPI&nbsp;MyMessageBoxW(
	<span style="color:#6f008a">_In_opt_</span>&nbsp;HWND&nbsp;hWnd,
	<span style="color:#6f008a">_In_opt_</span>&nbsp;LPCWSTR&nbsp;lpText,
	<span style="color:#6f008a">_In_opt_</span>&nbsp;LPCWSTR&nbsp;lpCaption,
	<span style="color:#6f008a">_In_</span>&nbsp;UINT&nbsp;uType)
{
	wstring&nbsp;caption(lpCaption);
	caption&nbsp;+=&nbsp;<span style="color:#a31515">L&quot;&nbsp;The&nbsp;unicode&nbsp;detoured&nbsp;version&nbsp;of&nbsp;MessageboxA&quot;</span>;
	wstring&nbsp;text(lpText);
	text&nbsp;+=&nbsp;<span style="color:#a31515">L&quot;&nbsp;hi&nbsp;from&nbsp;unicode&nbsp;detoured&nbsp;version&quot;</span>;
	<span style="color:blue">return</span>&nbsp;g_real_MessageBoxW(hWnd,&nbsp;text.c_str(),&nbsp;caption.c_str(),&nbsp;uType);
}
 
 
<span style="color:blue">class</span>&nbsp;CMyApplication
{
	WCHAR&nbsp;_szTitle[<span style="color:#6f008a">MAX_LOADSTRING</span>];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;The&nbsp;title&nbsp;bar&nbsp;text</span>
	WCHAR&nbsp;_szWindowClass[<span style="color:#6f008a">MAX_LOADSTRING</span>];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;the&nbsp;main&nbsp;window&nbsp;class&nbsp;name</span>
	HINSTANCE&nbsp;_hInstance;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;current&nbsp;instance</span>
	HWND&nbsp;_hWnd;
	HWND&nbsp;_hwndBtnMsgBox;
	HWND&nbsp;_hwndChkDetour;
	POINTS&nbsp;_size;
<span style="color:blue">public</span>:
	CMyApplication(HINSTANCE&nbsp;hInstance)
	{
		_hInstance&nbsp;=&nbsp;hInstance;
		<span style="color:green">//&nbsp;Initialize&nbsp;global&nbsp;strings</span>
		LoadStringW(_hInstance,&nbsp;IDS_APP_TITLE,&nbsp;_szTitle,&nbsp;<span style="color:#6f008a">MAX_LOADSTRING</span>);
		LoadStringW(_hInstance,&nbsp;IDC_DETOURSAMPLE,&nbsp;_szWindowClass,&nbsp;<span style="color:#6f008a">MAX_LOADSTRING</span>);
 
		WNDCLASSEXW&nbsp;wcex;
		wcex.cbSize&nbsp;=&nbsp;<span style="color:blue">sizeof</span>(WNDCLASSEX);
 
		wcex.style&nbsp;=&nbsp;CS_HREDRAW&nbsp;|&nbsp;CS_VREDRAW;
		wcex.lpfnWndProc&nbsp;=&nbsp;WindowProcedure;
		wcex.cbClsExtra&nbsp;=&nbsp;0;
		wcex.cbWndExtra&nbsp;=&nbsp;0;
		wcex.hInstance&nbsp;=&nbsp;hInstance;
		wcex.hIcon&nbsp;=&nbsp;LoadIcon(hInstance,&nbsp;MAKEINTRESOURCE(IDI_DETOURSAMPLE));
		wcex.hCursor&nbsp;=&nbsp;LoadCursor(<span style="color:blue">nullptr</span>,&nbsp;IDC_ARROW);
		wcex.hbrBackground&nbsp;=&nbsp;(HBRUSH)(COLOR_WINDOW&nbsp;+&nbsp;1);
		wcex.lpszMenuName&nbsp;=&nbsp;MAKEINTRESOURCEW(IDC_DETOURSAMPLE);
		wcex.lpszClassName&nbsp;=&nbsp;_szWindowClass;
		wcex.hIconSm&nbsp;=&nbsp;LoadIcon(wcex.hInstance,&nbsp;MAKEINTRESOURCE(IDI_SMALL));
		RegisterClassExW(&amp;wcex);
	}
 
	<span style="color:blue">void</span>&nbsp;Initialize()
	{
		_hWnd&nbsp;=&nbsp;CreateWindowW(_szWindowClass,&nbsp;_szTitle,&nbsp;WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT,&nbsp;0,&nbsp;CW_USEDEFAULT,&nbsp;0,&nbsp;<span style="color:blue">nullptr</span>,&nbsp;<span style="color:blue">nullptr</span>,&nbsp;_hInstance,&nbsp;<span style="color:blue">nullptr</span>);
 
		MoveWindow(_hWnd,&nbsp;400,&nbsp;400,&nbsp;700,&nbsp;400,&nbsp;<span style="color:green">/*bRepaint*/</span>&nbsp;<span style="color:blue">false</span>);
		ShowWindow(_hWnd,&nbsp;SW_NORMAL);
		UpdateWindow(_hWnd);
		ShowStatusMsg(<span style="color:#a31515">L&quot;Click&nbsp;to&nbsp;show&nbsp;MessageBox,&nbsp;RightClick&nbsp;to&nbsp;toggle&nbsp;detours&nbsp;(%S)&quot;</span>,&nbsp;g_szArch);
		_hwndBtnMsgBox&nbsp;=&nbsp;CreateWindow(
			<span style="color:#a31515">L&quot;BUTTON&quot;</span>,&nbsp;&nbsp;<span style="color:green">//&nbsp;Predefined&nbsp;class;&nbsp;Unicode&nbsp;assumed&nbsp;</span>
			<span style="color:#a31515">L&quot;MsgBox&quot;</span>,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Button&nbsp;text&nbsp;</span>
			WS_TABSTOP&nbsp;|&nbsp;WS_VISIBLE&nbsp;|&nbsp;WS_CHILD&nbsp;|&nbsp;BS_DEFPUSHBUTTON,&nbsp;&nbsp;<span style="color:green">//&nbsp;Styles&nbsp;</span>
			0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;x&nbsp;position&nbsp;</span>
			0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;y&nbsp;position&nbsp;</span>
			100,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Button&nbsp;width</span>
			20,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Button&nbsp;height</span>
			_hWnd,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Parent&nbsp;window</span>
			<span style="color:#6f008a">NULL</span>,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;No&nbsp;menu.</span>
			_hInstance,
			<span style="color:#6f008a">NULL</span>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Pointer&nbsp;not&nbsp;needed.</span>
 
		_hwndChkDetour&nbsp;=&nbsp;CreateWindow(
			<span style="color:#a31515">L&quot;BUTTON&quot;</span>,&nbsp;&nbsp;<span style="color:green">//&nbsp;Predefined&nbsp;class;&nbsp;Unicode&nbsp;assumed&nbsp;</span>
			<span style="color:#a31515">L&quot;Detour&quot;</span>,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Button&nbsp;text&nbsp;</span>
			WS_TABSTOP&nbsp;|&nbsp;WS_VISIBLE&nbsp;|&nbsp;WS_CHILD&nbsp;|&nbsp;BS_AUTOCHECKBOX,&nbsp;&nbsp;<span style="color:green">//&nbsp;Styles&nbsp;</span>
			130,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;x&nbsp;position&nbsp;</span>
			0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;y&nbsp;position&nbsp;</span>
			100,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Button&nbsp;width</span>
			20,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Button&nbsp;height</span>
			_hWnd,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Parent&nbsp;window</span>
			<span style="color:#6f008a">NULL</span>,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;No&nbsp;menu.</span>
			_hInstance,
			<span style="color:#6f008a">NULL</span>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:green">//&nbsp;Pointer&nbsp;not&nbsp;needed.</span>
	}
 
	<span style="color:blue">int</span>&nbsp;_topStatline&nbsp;=&nbsp;25;
	<span style="color:blue">int</span>&nbsp;_statLine&nbsp;=&nbsp;_topStatline;
	<span style="color:blue">void</span>&nbsp;ShowStatusMsg(LPCWSTR&nbsp;<span style="color:gray">pText</span>,&nbsp;...)
	{
		<span style="color:blue">if</span>&nbsp;(_hWnd&nbsp;!=&nbsp;<span style="color:#6f008a">NULL</span>)
		{
			<span style="color:#2b91af">va_list</span>&nbsp;args;
			va_start(args,&nbsp;<span style="color:gray">pText</span>);
			<span style="color:#2b91af">wstring</span>&nbsp;strtemp(1000,&nbsp;<span style="color:#a31515">&#039;\0&#039;</span>);
			_vsnwprintf_s(&amp;strtemp<span style="color:teal">[</span>0<span style="color:teal">]</span>,&nbsp;1000,&nbsp;<span style="color:#6f008a">_TRUNCATE</span>,&nbsp;<span style="color:gray">pText</span>,&nbsp;args);
			va_end(args);
			<span style="color:blue">auto</span>&nbsp;len&nbsp;=&nbsp;wcslen(strtemp.c_str());
			strtemp.resize(len);
			HDC&nbsp;hDC&nbsp;=&nbsp;GetDC(_hWnd);
			HFONT&nbsp;hFont&nbsp;=&nbsp;(HFONT)GetStockObject(ANSI_FIXED_FONT);
			HFONT&nbsp;hOldFont&nbsp;=&nbsp;(HFONT)SelectObject(hDC,&nbsp;hFont);
			TEXTMETRIC&nbsp;textMetric;
			<span style="color:blue">if</span>&nbsp;(GetTextMetrics(hDC,&nbsp;&amp;textMetric)&nbsp;&amp;&amp;&nbsp;textMetric.tmAveCharWidth&nbsp;&gt;&nbsp;0)
			{
				<span style="color:green">//&nbsp;pad&nbsp;to&nbsp;full&nbsp;line&nbsp;to&nbsp;erase&nbsp;any&nbsp;prior&nbsp;content</span>
				<span style="color:blue">auto</span>&nbsp;nCharsOnLine&nbsp;=&nbsp;_size.x&nbsp;/&nbsp;textMetric.tmAveCharWidth;
				<span style="color:blue">if</span>&nbsp;(nCharsOnLine&nbsp;&gt;&nbsp;0&nbsp;&amp;&amp;&nbsp;nCharsOnLine&nbsp;&gt;=&nbsp;(<span style="color:blue">int</span>)strtemp.size())
				{
					<span style="color:blue">auto</span>&nbsp;nCharsToPad&nbsp;=&nbsp;nCharsOnLine&nbsp;-&nbsp;strtemp.size();
					<span style="color:blue">if</span>&nbsp;(nCharsToPad&nbsp;&gt;&nbsp;0)
					{
						strtemp.insert(strtemp.size(),&nbsp;nCharsToPad,&nbsp;<span style="color:#a31515">&#039;&nbsp;&#039;</span>);
					}
					TextOut(hDC,&nbsp;0,&nbsp;_statLine,&nbsp;strtemp.c_str(),&nbsp;(<span style="color:blue">int</span>)strtemp.size());
					_statLine&nbsp;+=&nbsp;textMetric.tmHeight;
					<span style="color:blue">if</span>&nbsp;(_statLine&nbsp;&gt;&nbsp;_size.y)
					{
						_statLine&nbsp;=&nbsp;_topStatline;
					}
				}
			}
			SelectObject(hDC,&nbsp;hOldFont);
			ReleaseDC(_hWnd,&nbsp;hDC);
		}
	}
 
	<span style="color:blue">bool</span>&nbsp;_fIsDetouring&nbsp;=&nbsp;<span style="color:blue">false</span>;
	<span style="color:green">//&nbsp;Macro&nbsp;to&nbsp;show&nbsp;error.&nbsp;The&nbsp;expression&nbsp;is&nbsp;Stringized&nbsp;using&nbsp;the&nbsp;&quot;#&quot;&nbsp;operator.</span>
	<span style="color:green">//&nbsp;the&nbsp;&quot;%S&quot;&nbsp;is&nbsp;used&nbsp;(upper&nbsp;case&nbsp;S)&nbsp;to&nbsp;convert&nbsp;to&nbsp;Unicode</span>
<span style="color:gray">#define</span>&nbsp;<span style="color:#6f008a">IFFAILSHOWERROR</span>(expr)&nbsp;\
	<span style="color:blue">if</span>&nbsp;((err&nbsp;=&nbsp;expr)&nbsp;!=&nbsp;NO_ERROR)&nbsp;\
	{\
		g_CMyApplication-&gt;ShowStatusMsg(<span style="color:#a31515">L&quot;Error&nbsp;%d&nbsp;%S&quot;</span>,&nbsp;err,&nbsp;#expr);&nbsp;\
	}\
 
	<span style="color:blue">void</span>&nbsp;DoDetours()
	{
		<span style="color:blue">int</span>&nbsp;err;
		<span style="color:#6f008a">IFFAILSHOWERROR</span>(DetourTransactionBegin());
		<span style="color:blue">if</span>&nbsp;(!_fIsDetouring)
		{
			ShowStatusMsg(<span style="color:#a31515">L&quot;Start&nbsp;Detouring&quot;</span>);
			<span style="color:#6f008a">IFFAILSHOWERROR</span>(DetourAttach((PVOID&nbsp;*)&amp;g_real_MessageBoxA,&nbsp;MyMessageBoxA));
			<span style="color:#6f008a">IFFAILSHOWERROR</span>(DetourAttach((PVOID&nbsp;*)&amp;g_real_MessageBoxW,&nbsp;MyMessageBoxW));
		}
		<span style="color:blue">else</span>
		{
			ShowStatusMsg(<span style="color:#a31515">L&quot;Stop&nbsp;&nbsp;Detouring&quot;</span>);
			<span style="color:#6f008a">IFFAILSHOWERROR</span>(DetourDetach((PVOID&nbsp;*)&amp;g_real_MessageBoxA,&nbsp;MyMessageBoxA));
			<span style="color:#6f008a">IFFAILSHOWERROR</span>(DetourDetach((PVOID&nbsp;*)&amp;g_real_MessageBoxW,&nbsp;MyMessageBoxW));
		}
		<span style="color:#6f008a">IFFAILSHOWERROR</span>(DetourTransactionCommit());
		_fIsDetouring&nbsp;=&nbsp;!_fIsDetouring;
	}
	LRESULT&nbsp;CALLBACK&nbsp;WndProc(HWND&nbsp;hWnd,&nbsp;UINT&nbsp;message,&nbsp;WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)
	{
		<span style="color:blue">switch</span>&nbsp;(message)
		{
		<span style="color:blue">case</span>&nbsp;WM_COMMAND:
		{
			<span style="color:blue">int</span>&nbsp;wmId&nbsp;=&nbsp;LOWORD(wParam);
			<span style="color:green">//&nbsp;Parse&nbsp;the&nbsp;menu&nbsp;selections:</span>
			<span style="color:blue">switch</span>&nbsp;(wmId)
			{
			<span style="color:blue">case</span>&nbsp;BN_CLICKED:
				<span style="color:blue">if</span>&nbsp;((HWND)lParam&nbsp;==&nbsp;_hwndBtnMsgBox)
				{
					MessageBoxA(_hWnd,&nbsp;<span style="color:#a31515">&quot;Some&nbsp;Text&quot;</span>,&nbsp;g_szArch,&nbsp;MB_OK);
					<span style="color:green">//			MessageBoxW(_hWnd,&nbsp;_T(&quot;Some&nbsp;Unicode&nbsp;Text&quot;),&nbsp;_T(&quot;Caption&quot;),&nbsp;MB_OK);</span>
				}
				<span style="color:blue">else</span>&nbsp;<span style="color:blue">if</span>&nbsp;((HWND)lParam&nbsp;==&nbsp;_hwndChkDetour)
				{
					DoDetours();
				}
				<span style="color:blue">break</span>;
			<span style="color:blue">case</span>&nbsp;IDM_EXIT:
				DestroyWindow(hWnd);
				<span style="color:blue">break</span>;
			default:
				<span style="color:blue">return</span>&nbsp;DefWindowProc(hWnd,&nbsp;message,&nbsp;wParam,&nbsp;lParam);
			}
		}
		<span style="color:blue">break</span>;
		<span style="color:blue">case</span>&nbsp;WM_SIZE:
		{
			<span style="color:blue">auto</span>&nbsp;pts&nbsp;=&nbsp;MAKEPOINTS(lParam);
			ShowStatusMsg(<span style="color:#a31515">L&quot;Size&nbsp;&nbsp;%5d&nbsp;%5d&quot;</span>,&nbsp;pts.x,&nbsp;pts.y);
			_size&nbsp;=&nbsp;pts;
		}
		<span style="color:blue">break</span>;
		<span style="color:blue">case</span>&nbsp;WM_PAINT:
		{
			PAINTSTRUCT&nbsp;ps;
			HDC&nbsp;hdc&nbsp;=&nbsp;BeginPaint(hWnd,&nbsp;&amp;ps);
			EndPaint(hWnd,&nbsp;&amp;ps);
		}
		<span style="color:blue">break</span>;
		<span style="color:blue">case</span>&nbsp;WM_DESTROY:
			PostQuitMessage(0);
			<span style="color:blue">break</span>;
		<span style="color:blue">default</span>:
			<span style="color:blue">return</span>&nbsp;DefWindowProc(hWnd,&nbsp;message,&nbsp;wParam,&nbsp;lParam);
		}
		<span style="color:blue">return</span>&nbsp;0;
	}
 
	<span style="color:blue">int</span>&nbsp;DoMessageLoop()
	{
		HACCEL&nbsp;hAccelTable&nbsp;=&nbsp;LoadAccelerators(_hInstance,&nbsp;MAKEINTRESOURCE(IDC_DETOURSAMPLE));
		MSG&nbsp;msg;
		<span style="color:green">//&nbsp;Main&nbsp;message&nbsp;loop:</span>
		<span style="color:blue">while</span>&nbsp;(GetMessage(&amp;msg,&nbsp;<span style="color:blue">nullptr</span>,&nbsp;0,&nbsp;0))
		{
			<span style="color:blue">if</span>&nbsp;(!TranslateAccelerator(msg.hwnd,&nbsp;hAccelTable,&nbsp;&amp;msg))
			{
				TranslateMessage(&amp;msg);
				DispatchMessage(&amp;msg);
			}
		}
		<span style="color:blue">return</span>&nbsp;(<span style="color:blue">int</span>)msg.wParam;
	}
};
 
LRESULT&nbsp;CALLBACK&nbsp;WindowProcedure(HWND&nbsp;hWnd,&nbsp;UINT&nbsp;message,&nbsp;WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)
{
	<span style="color:blue">return</span>&nbsp;g_CMyApplication-&gt;WndProc(hWnd,&nbsp;message,&nbsp;wParam,&nbsp;lParam);
}
 
<span style="color:blue">int</span>&nbsp;APIENTRY&nbsp;wWinMain(<span style="color:#6f008a">_In_</span>&nbsp;HINSTANCE&nbsp;hInstance,
	<span style="color:#6f008a">_In_opt_</span>&nbsp;HINSTANCE&nbsp;hPrevInstance,
	<span style="color:#6f008a">_In_</span>&nbsp;LPWSTR&nbsp;&nbsp;&nbsp;&nbsp;lpCmdLine,
	<span style="color:#6f008a">_In_</span>&nbsp;<span style="color:blue">int</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nCmdShow)
{
	<span style="color:green">//&nbsp;create&nbsp;an&nbsp;instance&nbsp;of&nbsp;CMyApplication&nbsp;&nbsp;on&nbsp;stack</span>
	CMyApplication&nbsp;aCMyApplication(hInstance);
	g_CMyApplication&nbsp;=&nbsp;&amp;aCMyApplication;
	g_CMyApplication-&gt;Initialize();
 
	<span style="color:blue">return</span>&nbsp;g_CMyApplication-&gt;DoMessageLoop();
}
</pre><p>&nbsp;</p>
<p>&lt;/Code Sample&gt;</p>]]></content:encoded>
    </item>
    <item>
      <title>Visual Studio slowdown because Virus &amp; Threat protection Windows Defender Antivirus is scanning this file</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/visual-studio-slowdown-because-virus-threat-protection-windows-defender-antivirus-is-scanning-this-file</link>
      <pubDate>Wed, 27 Jun 2018 22:32:09 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7785</guid>
      <description><![CDATA[I noticed that if I hit F5 to build and debug some code for a very small solution (1-5 small...]]></description>
      <content:encoded><![CDATA[<p>I noticed that if I hit F5 to build and debug some code for a very small solution (1-5 small projects), there was a long delay of about 10-15 seconds. This seemed very unusual: I was expecting near instantaneous response.<br>If I change a single file and do a Build (without running), the build completes quickly, taking advantage of incremental build in managed and native compilers.</p> <p>If I hit F5 to run the app (the first time after build, the delay occurs), stop debugging, and hit F5 again (without changing any code and thus no change in the running binary), the 2nd time is much faster (2-3 seconds).</p> <p>So… the long delay occurred only the first time a build changes the binary.</p> <p>I tried to see what was going on and learned that if I disabled Real time Virus protection for the folder into which my binaries are built, then the delay is gone.</p> <p>Once the file has been scanned and deemed without a virus, the 2nd time running “remembers” the result and is much faster.</p> <p>While writing code, many developers repeat a few steps:<br>1.&nbsp;&nbsp;&nbsp; Make a code change,<br>2.&nbsp;&nbsp;&nbsp; Build and run the code<br>3.&nbsp;&nbsp;&nbsp; Ensure the code runs as expected<br>4.&nbsp;&nbsp;&nbsp; Repeat </p> <p>For some smaller projects, sometimes that loop takes 1-2 seconds. If there’s a 12 second delay for virus scanning the newly built executable code, then that’s a significant productivity slowdown.</p> <p>I’ve observed these delays on other folk’s machines too.</p> <p>Slowdowns due to AntiVirus are probably in many AV products. Thankfully, there’s a workaround: you can <a href="https://support.microsoft.com/en-us/help/4028485/windows-10-add-an-exclusion-to-windows-defender-antivirus">add a folder to an “Exclusion List”</a></p> <p>Once I did that, the long delay was gone.</p> <p>BTW, Edit and Continue (even in C++) is a really good feature to avoid stopping/starting debugging). When you reach a break point you can modify your code, Set Next Statement (change the next statement that gets executed) if necessary, and continue running the newly modified code.</p> <p>I’m a big fan of Test Driven Development (TDD). One of my favorite shortcut keys is Ctrl-R L, which repeats the last run unit test.<br><a href="https://msdnshared.blob.core.windows.net/media/2018/06/image.gif"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/06/image_thumb.gif" width="285" height="151"></a></p> <p><br>Virus &amp; threat protection Windows defender antivirus is scanning this file</p> <p>visual studio virus &amp; threat protection windows defender antivirus is scanning this file your it administrator requires a security scan of this item. The scan could take up to 10 seconds</p>]]></content:encoded>
    </item>
    <item>
      <title>Getting more disk space, Symbolic Links and Azure Virtual Machines</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/getting-more-disk-space-symbolic-links-and-azure-virtual-machines</link>
      <pubDate>Wed, 30 May 2018 23:46:01 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7755</guid>
      <description><![CDATA[AzureAzure lets you get free virtual machines.What does this mean? You can use a free Azure account...]]></description>
      <content:encoded><![CDATA[<p><a href="https://azure.microsoft.com/en-us/free/search/?&amp;OCID=AID631184_SEM_F7h68B6n&amp;lnkd=Bing_Azure_Brand&amp;msclkid=99d3042b9c0e1a93063d5f256b85bf9c">Azure</a>Azure lets you get free virtual machines.<br>What does this mean? You can use a free Azure account to create a new machine that only you can access, and can manipulate it as you see fit, almost as if you had a brand new computer to use (you can’t spill coffee on it). It can be configured with various amounts of memory, computing power. </p> <p>You can use Remote Desktop Connection to connect to the new machine and use it as if you were right in front of it. Your monitor will show the Virtual Machine and the keyboard and mouse will be attached to the VM. It’s a “virtual” machine, so it doesn’t really exist as a physical computer, but it is hosted on a real computer. </p> <p>The host machine can host many virtual machines simultaneously, each independent of the other, yielding huge economies of scale: think how often you use your computer, or more precisely, how often you don’t use your computer.</p> <p>Unless you are a BlockChain miner (currently in the news a lot because of the huge computation power required), your machine will likely be unused much of the time, and thus the actual cost is just a few files on the disk of the host computer. As you use your virtual machine, parts of the file are swapped into the host, while others may be swapped out.</p> <p>Virtual Machines have been around for a while: I’ve been hosting them in various Windows versions for over a decade. HyperVisor manager in Windows Server is a control center for managing VMs<br>I like to say that the 2 best inventions in computing are Cut/Paste, then Virtual Machines.</p> <p>Here you can see one of my physical machines “CalvinH1” hosting 4 Virtual Machines:<br><a href="https://msdnshared.blob.core.windows.net/media/2018/05/image309.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb239.png" width="244" height="195"></a></p> <p>Not only are there Virtual Machines, but you can create Virtual Disks for the VMs in both HyperVisor and Azure. These are stored on the host machine as files, which are pretty inexpensive to store these days. I remember getting a 5 Megabyte hard disk for several hundred dollars. <br>Once you create and associate a new Virtual Disk to a Virtual Machine via HyperVisor or Azure, you need to attach the disk to the machine. You then connect to the VM via Remote Desktop, open File Explorer, right click on “This PC”, choose Computer Management-&gt;Storage-&gt;Disk Management to see your new uninitialized disk (just as if attaching a real physical disk to a real physical machine).</p> <p>You can format newly attached drives, create new volumes, and even mount a volume into a folder.<br>I have an enlistment for a very large GIT Repo on one of my Azure machines, which had a 127G initial drive size for volume C:. I ran out of space, so I created a couple volumes and mounted them to folders, like “c:\Nugetcache” and “c:\vs\VSOut”.</p> <p><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2011/01/26/are-you-running-out-of-disk-space-treemap-your-files-to-see-whats-eating-the-most/">TreeMap</a> is very handy at identifying large disk folders, which are candidates for moving or deleting.<br></p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/05/image312.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb240.png" width="583" height="330"></a></p> <p>&nbsp;</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/05/image313.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb241.png" width="277" height="217"></a></p> <p>&nbsp;</p> <p>Windows comes with a utility to create symbolic links: mklink<br><font face="Courier New">C:\&gt;mklink /?<br>Creates a symbolic link.</font></p> <p><font face="Courier New">MKLINK [[/D] | [/H] | [/J]] Link Target</font></p> <p><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Creates a directory symbolic link.&nbsp; Default is a file<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; symbolic link.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /H&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Creates a hard link instead of a symbolic link.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /J&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Creates a Directory Junction.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Link&nbsp;&nbsp;&nbsp; Specifies the new symbolic link name.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Target&nbsp; Specifies the path (relative or absolute) that the new link<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; refers to.</font></p> <p><br>Be very careful when deleting a symbolic link: ensure that you’re not deleting the target of the link, but just the link itself!</p> <p>If you are running out of space on a volume, you can move some large folders out to make more room.<br>Identify the large folder. E.G. the Windows SDK “C:\Program Files (x86)\Windows Kits” can be several Gigabytes.<br>Shutdown any program that might be using the folder, like Visual Studio (ensure MsBuild shut down too)<br>Copy/delete original windows kits directory: e.g. "C:\Program Files (x86)\Windows Kits" to “e:\Windows Kits"<br>Mklink /j "C:\Program Files (x86)\Windows Kits" "e:\Windows Kits"</p> <p>You can use the program below to understand more about Symbolic Links.</p> <p>File-&gt;new-&gt;project-&gt;C#-&gt;Console App</p> <p>Paste in the code below.<br>For testing, you can choose Project-&gt;properties-&gt;Debug tab, and in the Command Line Arguments, put is some sample arguments for testing. I used e.g.&nbsp; /d foo "C:\footemp", which would make a link in the current directory to a folder called “c:\footemp”</p> <p>The resulting Symbolic link “foo” appears:</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/05/image314.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb242.png" width="397" height="88"></a></p> <p>&nbsp;</p> <p>And double clicking on foo goes to the target.</p> <p>If you make a Symbolic link to a target that doesn’t exist, the link gets created, but navigating there via File Explorer yields:<br></p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/05/image315.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/05/image_thumb243.png" width="503" height="164"></a></p> <p>&nbsp;</p> <p>If you prepend the linkname with&nbsp; “\\?\” then you can make paths that are longer.&nbsp; Try experimenting with the commented code.<br>"C:\Users\calvinh\source\repos\SYMBOL~1\SYMBOL~1\bin\Debug\LONGAB~1"</p> <p>Put a breakpoint on the CreateSymbolicLinkW line and you can experiment with changing values, changing the code, Set Next Statement (to change the next statement to execute)<br>See <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx?f=255&amp;MSPPError=-2147217396">Naming Files, Paths, and Namespaces</a> for more on how to use very long ( up to 32,767 char) path names <br></p> <p><br>&nbsp;</p>    <p>&lt;code&gt;</p> <p>&nbsp;</p> <div class='codeBlock'><pre><code><span style='color:#0000ff'>using</span> System;
<span style='color:#0000ff'>using</span> System.Collections.Generic;
<span style='color:#0000ff'>using</span> System.Diagnostics;
<span style='color:#0000ff'>using</span> System.Linq;
<span style='color:#0000ff'>using</span> System.Runtime.InteropServices;
<span style='color:#0000ff'>using</span> System.Text;
<span style='color:#0000ff'>using</span> System.Threading.Tasks;

<span style='color:#0000ff'>namespace</span> SymbolicLInk
{
    <span style='color:#0000ff'>class</span> <span style='color:#2b91af'>Program</span>
    {
        <span style='color:#0000ff'>static</span> <span style='color:#0000ff'>int</span> Main(<span style='color:#0000ff'>string</span>[] args)
        {
            <span style='color:#0000ff'>var</span> instance = <span style='color:#0000ff'>new</span> Program();
            <span style='color:#0000ff'>return</span> instance.DoMain(args);
        }

        <span style='color:#0000ff'>private</span> <span style='color:#0000ff'>int</span> DoMain(<span style='color:#0000ff'>string</span>[] args)
        {
            <span style='color:#0000ff'>var</span> flag = SYMBOLIC_LINK_FLAG.File;
            <span style='color:#0000ff'>var</span> linkName = <span style='color:#0000ff'>string</span>.Empty;
            <span style='color:#0000ff'>var</span> linkTarget = <span style='color:#0000ff'>string</span>.Empty;
            <span style='color:#0000ff'>for</span> (<span style='color:#0000ff'>int</span> i = 0; i &lt; args.Length; i++)
            {
                <span style='color:#0000ff'>switch</span> (args[i][0])
                {
                    <span style='color:#0000ff'>case</span> <span style='color:#a31515'>'-'</span>:
                    <span style='color:#0000ff'>case</span> <span style='color:#a31515'>'/'</span>:
                        <span style='color:#0000ff'>if</span> (args[i].Length &gt; 1)
                        {
                            <span style='color:#0000ff'>switch</span> (args[i][1])
                            {
                                <span style='color:#0000ff'>case</span> <span style='color:#a31515'>'D'</span>:
                                <span style='color:#0000ff'>case</span> <span style='color:#a31515'>'d'</span>:
                                    flag = SYMBOLIC_LINK_FLAG.Directory;
                                    <span style='color:#0000ff'>break</span>;
                            }
                        }
                        <span style='color:#0000ff'>break</span>;
                    <span style='color:#0000ff'>default</span>:
                        <span style='color:#0000ff'>if</span> (<span style='color:#0000ff'>string</span>.IsNullOrEmpty(linkName))
                        {
                            linkName = args[i];
                        }
                        <span style='color:#0000ff'>else</span>
                        {
                            <span style='color:#0000ff'>if</span> (<span style='color:#0000ff'>string</span>.IsNullOrEmpty(linkTarget))
                            {
                                linkTarget = args[i];
                            }
                            <span style='color:#0000ff'>else</span>
                                <span style='color:#0000ff'>return</span> ShowHelp();
                        }
                        <span style='color:#0000ff'>break</span>;
                }
            }
            <span style='color:#0000ff'>if</span> (<span style='color:#0000ff'>string</span>.IsNullOrEmpty(linkName) || <span style='color:#0000ff'>string</span>.IsNullOrEmpty(linkTarget))
            {
                <span style='color:#0000ff'>return</span> ShowHelp();
            }
            <span style='color:#008000'>//var longstr = $"a{new string('b', 242)}c";</span>
            <span style='color:#008000'>//var longname = $@"Long{longstr}dirname";</span>
            <span style='color:#008000'>//var lenLink = longname.Length;</span>
            <span style='color:#008000'>//linkName = $@"\\?\{System.Environment.CurrentDirectory}\{longname}";</span>
            <span style='color:#008000'>////Starting with Windows 10, version 1607, for the unicode version of this function (CreateSymbolicLinkW), you can opt-in to remove the MAX_PATH limitation without prepending "\\?\". See the "Maximum Path Length Limitation" section of Naming Files, Paths, and Namespaces for details.</span>
            <span style='color:#008000'>//var lenLinkTotal = linkName.Length;</span>

            <span style='color:#0000ff'>if</span> (CreateSymbolicLinkW(linkName, linkTarget, flag))
            {
                OutputString(<span style='color:#a31515'>$"Successfully created link from '</span>{linkName}<span style='color:#a31515'>' to '</span>{linkTarget}<span style='color:#a31515'>'"</span>);
            }
            <span style='color:#0000ff'>else</span>
            {
                <span style='color:#0000ff'>var</span> lastErr = Marshal.GetLastWin32Error();
                <span style='color:#0000ff'>var</span> errInfo = <span style='color:#0000ff'>string</span>.Empty;
                <span style='color:#0000ff'>switch</span> (lastErr)  <span style='color:#008000'>// from Tools-&gt;Error Lookup</span>
                {
                    <span style='color:#0000ff'>case</span> 3: <span style='color:#008000'>//The system cannot find the path specified. </span>
                        errInfo = <span style='color:#a31515'>"The system cannot find the path specified."</span>;
                        <span style='color:#0000ff'>break</span>;
                    <span style='color:#0000ff'>case</span> 123: <span style='color:#008000'>//The filename, directory name, or volume label syntax is incorrect. </span>
                        errInfo = <span style='color:#a31515'>"The filename, directory name, or volume label syntax is incorrect."</span>;
                        <span style='color:#0000ff'>break</span>;
                    <span style='color:#0000ff'>case</span> 183: <span style='color:#008000'>//Cannot create a file when that file already exists. </span>
                        errInfo = <span style='color:#a31515'>"Cannot create a file when that file already exists."</span>;
                        <span style='color:#0000ff'>break</span>;
                    <span style='color:#0000ff'>case</span> 1314: <span style='color:#008000'>// A required privilege is not held by the client. </span>
                        errInfo = <span style='color:#a31515'>"A required privilege is not held by the client. Are you running as Admin?"</span>;
                        <span style='color:#0000ff'>break</span>;
                    <span style='color:#0000ff'>default</span>:
                        <span style='color:#0000ff'>break</span>;
                }
                OutputString(<span style='color:#a31515'>$"Failed to create link from '</span>{linkName}<span style='color:#a31515'>' to '</span>{linkTarget}<span style='color:#a31515'>'   </span>{Marshal.GetLastWin32Error()}<span style='color:#a31515'> </span>{errInfo}<span style='color:#a31515'>"</span>);
            }
            <span style='color:#0000ff'>return</span> 0; <span style='color:#008000'>// success</span>
        }

        <span style='color:#0000ff'>private</span> <span style='color:#0000ff'>int</span> ShowHelp()
        {
            OutputString(<span style='color:#a31515'>"Symbolic Link"</span>);
            OutputString(<span style='color:#a31515'>"Usage: SymbolicLink [/D] link target"</span>);
            OutputString(<span style='color:#a31515'>"  link is the name to create for the link"</span>);
            OutputString(<span style='color:#a31515'>"  target is the redirected location"</span>);
            OutputString(<span style='color:#a31515'>"To delete the link, delete from File Explorer as if it were a normal file or directory"</span>);
            <span style='color:#0000ff'>return</span> 1; <span style='color:#008000'>//failure</span>
        }
        <span style='color:#0000ff'>void</span> OutputString(<span style='color:#0000ff'>string</span> str)
        {
            Debug.WriteLine(str);
            Console.WriteLine(str);
        }

        [DllImport(<span style='color:#a31515'>"kernel32.dll"</span>, SetLastError = <span style='color:#0000ff'>true</span>, CharSet = CharSet.Unicode)]
        [<span style='color:#0000ff'>return</span>: MarshalAs(System.Runtime.InteropServices.UnmanagedType.I1)]
        <span style='color:#0000ff'>static</span> <span style='color:#0000ff'>extern</span> <span style='color:#0000ff'>bool</span> CreateSymbolicLinkW(<span style='color:#0000ff'>string</span> lpSymlinkFileName, <span style='color:#0000ff'>string</span> lpTargetFileName, SYMBOLIC_LINK_FLAG dwFlags);
        <span style='color:#0000ff'>public</span> <span style='color:#0000ff'>enum</span> <span style='color:#2b91af'>SYMBOLIC_LINK_FLAG</span>
        {
            File = 0,
            Directory = 1
        }


    }
}</code></pre></div><p>&lt;/code&gt;</p>]]></content:encoded>
    </item>
    <item>
      <title>Lasers bouncing off elliptical mirrors in C#</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/lasers-bouncing-off-elliptical-mirrors-in-c</link>
      <pubDate>Mon, 30 Apr 2018 17:54:55 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7645</guid>
      <description><![CDATA[The NumberPhile Illumination Problem https://www.youtube.com/watch?v=xhj5er1k6GQ describes...]]></description>
      <content:encoded><![CDATA[<p>The NumberPhile Illumination Problem <a href="https://www.youtube.com/watch?v=xhj5er1k6GQ">https://www.youtube.com/watch?v=xhj5er1k6GQ</a> describes reflecting light beams off mirrored walls to see if all parts of an oddly shaped room can be illuminated.</p> <p>In the last 2 posts (Lasers reflecting off an ellipse&nbsp; and&nbsp; Reflect laser beams off multiple mirrors) I showed some code to simulate laser beams reflecting off multiple mirrors in C++</p> <p>Here is a solution in C# that includes the prior C++ functionality and also an ellipse very close to that described in the video.</p> <p>The C# code for Reflection is 1600 lines, too big to put in a blog post. So it’s here:<br><a href="https://github.com/calvinhsia/HwndHost/blob/nlasers/Reflect/Reflect.xaml.cs">https://github.com/calvinhsia/HwndHost/blob/nlasers/Reflect/Reflect.xaml.cs</a></p> <p><br>I’ve been hosting the code in VSOnline using GIT. Moving the code to use a different backend was pretty simple. First I created an empty repo in GitHub.<br>Then:</p> <p>git remote set-url origin <a href="https://github.com/calvinhsia/HwndHost.git">https://github.com/calvinhsia/HwndHost.git</a><br>git push</p> <p>&nbsp;</p> <p>Just Start Visual Studio, View-&gt;Team Explorer, Manage Connections, Clone <a href="https://github.com/calvinhsia/HwndHost.git">https://github.com/calvinhsia/HwndHost.git</a><br>Then open the HWndHost.sln, right click on Reflect (or any other project in the solution) Set as Startup, then F5 to run the code</p> <p>Which one is faster the C++ or the C# solution? The number of bounces per second is displayed in the status bar for each.</p> <p>Issues:<br>1.&nbsp;&nbsp;&nbsp; When a beam hits a corner, what should it do? right now the angle can be anything depending on how “close” to the corner it is. It’s the same problem as finding a tangent to a point. You can find a tangent to a curve, but what if it’s a point? Thus currently, the light beams can escape. Different starting window sizes make a difference in the calculations for the light beams.<br>2.&nbsp;&nbsp;&nbsp; The code doesn’t remember whether a particular laser beam is identical to a prior laser beam. If so, then we know that spot has been illuminated and we can terminate the laser beam (if that’s possible). It’s still interesting to watch as the laser beams change color and traverse the shape.</p> <p><br>In the same HWndHost solution&nbsp; there are several other projects that do some fancy graphics stuff:</p> <p>Bouncing balls on the screen (written in VB) <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2008/11/29/you-can-use-hwndhost-to-host-a-win32-hwnd-window-inside-a-wpf-element/">You can use HWndHost to host a Win32 HWnd window inside a WPF element</a></p> <p><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2014/09/30/fish-vs-sharks-predator-prey-simulation/">Fish vs Sharks: Predator Prey simulation</a> based on the same base class “HWndHost” as the Bouncing balls.</p> <p><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2014/08/29/logo-turtle-graphics-in-wpf/">Logo Turtle Graphics in WPF</a> where you have a very fast turtle with a pen, also based on the same base class.</p>]]></content:encoded>
    </item>
    <item>
      <title>Lasers reflecting off an ellipse</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/lasers-reflecting-off-an-ellipse</link>
      <pubDate>Fri, 30 Mar 2018 20:40:06 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7635</guid>
      <description><![CDATA[Various conic sections (hyperbolas, parabolas, ellipses) have interesting reflective properties....]]></description>
      <content:encoded><![CDATA[<p>Various conic sections (hyperbolas, parabolas, ellipses) have interesting reflective properties. Parabolas are used for antennae and even car headlight and flashlight reflectors to focus a beam of light. </p> <p><a href="https://msdnshared.blob.core.windows.net/media/2018/03/image413.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/03/image_thumb384.png" width="371" height="198"></a></p> <p>In the last post <a href="https://blogs.msdn.microsoft.com/calvin_hsia/2018/02/28/reflect-laser-beams-off-multiple-mirrors">https://blogs.msdn.microsoft.com/calvin_hsia/2018/02/28/reflect-laser-beams-off-multiple-mirrors</a> I showed some code to bounce a laser off various mirrors that the user can draw on the screen. I also mentioned that an elliptically shaped water tank will reflect waves and that Lithotripter uses ellipses to remove kidney stones<br>Let’s enhance that code:<br>•&nbsp;&nbsp;&nbsp; Add an ellipse<br>•&nbsp;&nbsp;&nbsp; Allow multiple lasers, initially emanating from a single point, thus simulating a point source of light<br>•&nbsp;&nbsp;&nbsp; Added a context menu that allows the user to set the initial laser point. E.g. what happens if you put the lasers initially at a focus of the ellipse?<br>•&nbsp;&nbsp;&nbsp; Added an options dialog that allows the user to control the number of lasers</p> <p><br>The code involves multiple files, one of which has 1300 lines and thus is hard to publish as a single blog entry, so I’ve put it at <a href="https://github.com/calvinhsia/ReflectCpp">https://github.com/calvinhsia/ReflectCpp</a> <br>Just clone the repo locally, open the solution ReflectCPP.sln and run it.</p> <p>Note how the code has multiple kinds of mirrors (currently 2), all of which implement an interface IMirror, which has methods like Draw, IntersectingPoint and Reflect</p> <p><br>Things to try:<br>•&nbsp;&nbsp;&nbsp; Slow it down, use 1 laser, watch how it reflects off the ellipse walls<br>•&nbsp;&nbsp;&nbsp; Use your mouse and draw a mirror or several and watch how it affects the pattern.<br>•&nbsp;&nbsp;&nbsp; Try to isolate the light into patterns stuck in just a portion of the ellipse without a mirror touching the ellipse (try setting the laser count to 1 first)</p> <p>The name “ReflectCPP” implies it is the C++ version of the code, and that there’s another version. Next time!<br>The patterns generated from the code are pretty remarkable. You can see the symmetry around the focal points (the little dots)</p>]]></content:encoded>
    </item>
    <item>
      <title>Reflect laser beams off multiple mirrors</title>
      <link>https://docs.microsoft.com/archive/blogs/calvin_hsia/reflect-laser-beams-off-multiple-mirrors</link>
      <pubDate>Wed, 28 Feb 2018 02:33:43 GMT</pubDate>
      <dc:creator><![CDATA[CalvinH]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/calvin_hsia/?p=7605</guid>
      <description><![CDATA[In some science museums there are exhibits demonstrating the paths of light rays. A typical one...]]></description>
      <content:encoded><![CDATA[<p><br>In some science museums there are exhibits demonstrating the paths of light rays. A typical one might have a table with small walls consisting of blocks a few inches high, with each vertical face being a mirror. A small horizontal laser can be positioned anywhere on the table. Many blocks be placed on the table to reflect the light. The room can be darkened, and chalk dust can be sprinkled to see the laser beams as the reflect from mirror to mirror. Blocks can be arranged in various shapes to vary the light patterns produced.<br>Creating such an environment requires a laser, several mirrors, etc. Simulating the setup with software however, is much easier.</p> <p>I was talking to my son about this laser table idea and he pointed me to the The NumberPhile Illumination Problem <a href="https://www.youtube.com/watch?v=xhj5er1k6GQ">https://www.youtube.com/watch?v=xhj5er1k6GQ</a> </p> <p>I remember years ago playing with ripple tanks years ago. A tray with e.g. circular 2 inch walls was filled with water. A point source like the tip of a vertical stick was repeatedly immersed, removed from the water to cause a point source of waves. The pattern of waves could easily be seen. If the stimulant was in the center of the circle, the ripples would reach the edges simultaneously. What if the edges were an ellipse? We learned in math class that an ellipse has many interesting properties. If you stimulate one focus of the ellipse, the other waves will converge on the other.<br>I remember reading about real applications of the ellipse in eliminating kidney stones with an <a href="http://mathcentral.uregina.ca/beyond/articles/Lithotripsy/lithotripsy1.html">elliptical shock wave, which pulverizes the stones without surgery using a Lithotripter</a></p> <p>Imagine drawing arbitrary shapes on the screen with your mouse or your finger, each representing an arrangement of mirrors on the laser table. Turn on the laser and watch the laser beam bounce off the mirrors. Is it possible to create a region in which the light never goes? Sure: create a closed shape like a triangle. How about a non-closed shape?</p> <p>Because the laser beam is so fast, the area gets colored very quickly. To make the light beam more visible, the code varies the color of the laser beam with time so that it’s easier to see where the laser is. If not, thousands of lasers per second would quickly fill the entire screen with the same color.<br>Try drawing mirrors while the light is bouncing around. Even though one thread is modifying the list of mirrors, the reflections continue.</p> <p>If the walls are only horizontal or vertical, then reflecting is easy: for a horizontal wall, just negate the vertical component of the velocity. It gets more complicated when the mirrors can be any angle.</p> <p>Notice how the drawing can be done in a background thread, even though WPF or GDI demands UI control access on the main thread.</p> <p>Notice that there are no explicit memory allocations in this C++ program: no operator new<br><br>Various places in the code do mathematical manipulations such as multiplication, additions, square root. You can see how the optimized Release build inlines a lot of these to make the more efficient. The generated instructions are vastly different if using an Enhanced Instruction Set. Project-&gt;Properties=&gt;C/C++-&gt;Code Generation-&gt;Enabled Enhanced Instruction Set</p> <p><br>Below is a C++ program that models the mirror table. <br>A Vector (with a capital “V”) is a physics vector. (A “vector” with a lower-case “v” is a std collection of a list of elements.)<br>A light beam is modeled as a point (from which the laser beam emanates) and a Vector indicating direction, with x and y components.<br>A mirror interface IMirror is defined. A mirror can:<br>1.&nbsp;&nbsp;&nbsp; determine if a light beam intersects it (returning the Point of intersection) <br>2.&nbsp;&nbsp;&nbsp; draw itself<br>3.&nbsp;&nbsp;&nbsp; determine the Vector of a reflecting incoming laser beam</p> <p>A MyPoint class is a Point in the x,y plane.<br>A CLine class is a line, consisting of 2 points and a bool indicating whether the line is infinite (like a laser beam) or is a line segment (like a finite length mirror)</p> <p>Various accelerator keys are defined, such as “R” to run/stop the simulation, “S” and “F” for slower and faster to control the reflection speed, etc.</p> <p><br>Try turning on drag mode (right-click) and control-mouse move to draw continuous curved wall mirrors.<br>Try creating long angled corridors to watch the light bounce around in interesting ways. (as the light gets further down a narrowing corridor, the angles change and the light reflects out without going all the way down the corridor: a kind of light valve.<br>Try capturing the laser light in various shapes.<br>Try slowing down the light rays and follow them, while creating more mirrors<br>Try modifying the code to have multiple lasers at a time, simulating a point source of light.<br>Try comparing the performance of&nbsp; 32 and 64 bit builds (to build 64 bit, Menu-&gt;Build-&gt;Configurations-&gt;Active Solution Platform-&gt;x64</p> <p>&lt;code&gt;</p> <div class="codeBlock"><pre><code><span style="color: #008000">// ReflectCpp.cpp : Defines the entry point for the application.</span>
<span style="color: #008000">//</span>

<span style="color: #008000">// Team Explorer-&gt;Connections-&gt;New Repository "ReflectCPP"</span>
<span style="color: #008000">// DblClick the newly created Repo to get to the Team Explorer Home pane.</span>
<span style="color: #008000">// Solutions-&gt;New-&gt;C++ Win32Project. Select all the defaults in the Win32 App Wizard</span>
<span style="color: #008000">// add natvis: https://msdn.microsoft.com/en-us/library/jj620914.aspx?f=255&amp;MSPPError=-2147217396</span>

<span style="color: #808080">#include</span> <span style="color: #a31515">"stdafx.h"</span>
<span style="color: #808080">#include</span> <span style="color: #a31515">"ReflectCpp.h"</span>
<span style="color: #808080">#include</span> <span style="color: #a31515">"windowsx.h"</span>
<span style="color: #808080">#include</span> <span style="color: #a31515">"vector"</span>
<span style="color: #808080">#include</span> <span style="color: #a31515">"memory"</span>
<span style="color: #808080">#include</span> <span style="color: #a31515">"string"</span>
<span style="color: #808080">#include</span> <span style="color: #a31515">"atlbase.h"</span>

<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> std;
<span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> ATL;

<span style="color: #808080">#define</span> MAX_LOADSTRING 100

<span style="color: #008000">// Global Variables:</span>
HINSTANCE g_hInstance;                                <span style="color: #008000">// current instance</span>
WCHAR szTitle[MAX_LOADSTRING];                  <span style="color: #008000">// The title bar text</span>
WCHAR szWindowClass[MAX_LOADSTRING];            <span style="color: #008000">// the main window class name</span>

												<span style="color: #008000">// Forward declarations of functions included in this code module:</span>
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, <span style="color: #0000ff">int</span>);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
<span style="color: #0000ff">class</span> BounceFrame;
BounceFrame *g_pBounceFrame;

HWND g_hWnd;

<span style="color: #008000">//</span>
<span style="color: #008000">//  FUNCTION: MyRegisterClass()</span>
<span style="color: #008000">//</span>
<span style="color: #008000">//  PURPOSE: Registers the window class.</span>
<span style="color: #008000">//</span>
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEXW wcex;

	wcex.cbSize = <span style="color: #0000ff">sizeof</span>(WNDCLASSEX);

	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_REFLECTCPP));
	wcex.hCursor = LoadCursor(<span style="color: #0000ff">nullptr</span>, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_REFLECTCPP);
	wcex.lpszClassName = szWindowClass;
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	<span style="color: #0000ff">return</span> RegisterClassExW(&amp;wcex);
}

BOOL InitInstance(HINSTANCE hInstance, <span style="color: #0000ff">int</span> nCmdShow)
{
	g_hInstance = hInstance; <span style="color: #008000">// Store instance handle in our global variable</span>

	HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, <span style="color: #0000ff">nullptr</span>, <span style="color: #0000ff">nullptr</span>, hInstance, <span style="color: #0000ff">nullptr</span>);

	<span style="color: #0000ff">if</span> (!hWnd)
	{
		<span style="color: #0000ff">return</span> FALSE;
	}

	ShowWindow(hWnd, nCmdShow);
	g_hWnd = hWnd;
	UpdateWindow(hWnd);
	<span style="color: #0000ff">return</span> TRUE;
}

<span style="color: #0000ff">template</span> &lt;<span style="color: #0000ff">typename</span> T&gt; <span style="color: #0000ff">int</span> sgn(T val) {
	<span style="color: #0000ff">return</span> (T(0) &lt; val) - (val &lt; T(0));
}

<span style="color: #0000ff">typedef</span> <span style="color: #0000ff">double</span> MyPrecision;
<span style="color: #0000ff">const</span> <span style="color: #0000ff">double</span> epsilon = .00001;
<span style="color: #0000ff">const</span> <span style="color: #0000ff">int</span> SpeedMult = 1000;
<span style="color: #0000ff">class</span> MyPoint
{
<span style="color: #0000ff">public</span>:
	MyPoint()
	{
		<span style="color: #0000ff">this</span>-&gt;X = 0;
		<span style="color: #0000ff">this</span>-&gt;Y = 0;
	}
	MyPoint(MyPrecision x, MyPrecision y)
	{
		<span style="color: #0000ff">this</span>-&gt;X = x;
		<span style="color: #0000ff">this</span>-&gt;Y = y;
	}
	MyPoint(POINTS pt)
	{
		<span style="color: #0000ff">this</span>-&gt;X = pt.x;
		<span style="color: #0000ff">this</span>-&gt;Y = pt.y;
	}
	<span style="color: #008000">// assignment</span>
	MyPoint &amp; <span style="color: #0000ff">operator</span>=(<span style="color: #0000ff">const</span> MyPoint other)
	{
		<span style="color: #0000ff">this</span>-&gt;X = other.X;
		<span style="color: #0000ff">this</span>-&gt;Y = other.Y;
		<span style="color: #0000ff">return</span> *<span style="color: #0000ff">this</span>;
	}
	<span style="color: #008000">// equality</span>
	<span style="color: #0000ff">bool</span> <span style="color: #0000ff">operator</span> ==(<span style="color: #0000ff">const</span> MyPoint other)
	{
		<span style="color: #0000ff">if</span> (abs(<span style="color: #0000ff">this</span>-&gt;X - other.X) &lt; epsilon &amp;&amp; abs(<span style="color: #0000ff">this</span>-&gt;Y - other.Y) &lt; epsilon)
		{
			<span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span>;
		}
		<span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>;
	}
	<span style="color: #0000ff">bool</span> <span style="color: #0000ff">operator</span> !=(<span style="color: #0000ff">const</span> MyPoint other)
	{
		<span style="color: #0000ff">return</span> !(*<span style="color: #0000ff">this</span> == other);
	}
	<span style="color: #0000ff">bool</span> IsNull()
	{
		<span style="color: #0000ff">return</span> X == 0 &amp;&amp; Y == 0;
	}
	<span style="color: #0000ff">void</span> Clear()
	{
		X = Y = 0;
	}
	<span style="color: #0000ff">double</span> DistanceFromPoint(MyPoint other)
	{
		<span style="color: #0000ff">auto</span> deltax = <span style="color: #0000ff">this</span>-&gt;X - other.X;
		<span style="color: #0000ff">auto</span> deltay = <span style="color: #0000ff">this</span>-&gt;Y - other.Y;
		<span style="color: #0000ff">auto</span> d = sqrt(deltax * deltax + deltay * deltay);
		<span style="color: #0000ff">return</span> d;
	}
	MyPrecision X;
	MyPrecision Y;
};

<span style="color: #0000ff">typedef</span> MyPoint Vector; <span style="color: #008000">// as in physics vector with speed and direction</span>

<span style="color: #0000ff">interface</span> IMirror
{
	<span style="color: #0000ff">virtual</span> MyPoint IntersectingPoint(MyPoint ptcLight, Vector vecLight) = 0;
	<span style="color: #0000ff">virtual</span> Vector Reflect(MyPoint ptLight, Vector vecLight, MyPoint ptIntersect) = 0;
	<span style="color: #0000ff">virtual</span> <span style="color: #0000ff">void</span> Draw(HDC hDC) = 0;
	<span style="color: #0000ff">virtual</span> ~IMirror() {};
};

<span style="color: #0000ff">class</span> CLine : <span style="color: #0000ff">public</span> IMirror
{
<span style="color: #0000ff">public</span>:
	CLine(MyPoint &amp;pt0, MyPoint &amp;pt1, <span style="color: #0000ff">bool</span> IsLimitedInLength = <span style="color: #0000ff">true</span>)
	{
		<span style="color: #0000ff">this</span>-&gt;pt0 = pt0;
		<span style="color: #0000ff">this</span>-&gt;pt1 = pt1;
		<span style="color: #0000ff">this</span>-&gt;IsLimitedInLength = IsLimitedInLength;
	}
	MyPrecision LineLength()
	{
		<span style="color: #0000ff">return</span> sqrt(LineLengthSquared());
	}
	MyPrecision LineLengthSquared()
	{
		<span style="color: #0000ff">return</span> deltaX()*deltaX() + deltaY()*deltaY();
	}
	MyPrecision deltaX()
	{
		<span style="color: #0000ff">return</span> pt1.X - pt0.X;
	}
	MyPrecision deltaY()
	{
		<span style="color: #0000ff">return</span> pt1.Y - pt0.Y;
	}

	MyPoint IntersectingPoint(MyPoint ptLight, Vector vecLight)
	{
		MyPoint ptIntersect;
		CLine lnIncident(ptLight, MyPoint(ptLight.X + vecLight.X, ptLight.Y + vecLight.Y));
		<span style="color: #0000ff">auto</span> ptIntersectTest = IntersectingPoint(lnIncident);
		<span style="color: #008000">// the incident line intersects the mirror. Our mirrors have finite width</span>
		<span style="color: #008000">// let's see if the intersection point is within the mirror's edges</span>
		<span style="color: #0000ff">if</span> (!ptIntersectTest.IsNull())
		{
			<span style="color: #0000ff">if</span> (<span style="color: #0000ff">this</span>-&gt;IsLimitedInLength)
			{
				<span style="color: #0000ff">if</span> (pt0.DistanceFromPoint(ptIntersectTest) +
					ptIntersectTest.DistanceFromPoint(pt1) - LineLength() &lt; epsilon)
				{
					<span style="color: #0000ff">if</span> (abs(vecLight.X) &lt; epsilon) <span style="color: #008000">// vert</span>
					{
						<span style="color: #0000ff">auto</span> ss = sgn(vecLight.Y);
						<span style="color: #0000ff">auto</span> s2 = sgn(ptIntersectTest.Y - ptLight.Y);
						<span style="color: #0000ff">if</span> (ss * s2 == 1) <span style="color: #008000">// in our direction?</span>
						{
							ptIntersect = ptIntersectTest;
						}
					}
					<span style="color: #0000ff">else</span>  <span style="color: #008000">// non-vertical</span>
					{
						<span style="color: #0000ff">auto</span> ss = sgn(vecLight.X);
						<span style="color: #0000ff">auto</span> s2 = sgn(ptIntersectTest.X - ptLight.X);
						<span style="color: #0000ff">if</span> (ss * s2 == 1) <span style="color: #008000">// in our direction?</span>
						{
							ptIntersect = ptIntersectTest;
						}
					}
				}
			}
			<span style="color: #0000ff">else</span>
			{
				ptIntersect = ptIntersectTest;
			}
		}
		<span style="color: #0000ff">return</span> ptIntersect;
	}

	MyPoint IntersectingPoint(CLine otherLine)
	{
		MyPoint result;
		<span style="color: #0000ff">auto</span> denom = (<span style="color: #0000ff">this</span>-&gt;pt0.X - <span style="color: #0000ff">this</span>-&gt;pt1.X) * (otherLine.pt0.Y - otherLine.pt1.Y) - (<span style="color: #0000ff">this</span>-&gt;pt0.Y - <span style="color: #0000ff">this</span>-&gt;pt1.Y) * (otherLine.pt0.X - otherLine.pt1.X);
		<span style="color: #0000ff">if</span> (denom != 0)
		{
			result.X = ((<span style="color: #0000ff">this</span>-&gt;pt0.X * <span style="color: #0000ff">this</span>-&gt;pt1.Y - <span style="color: #0000ff">this</span>-&gt;pt0.Y * <span style="color: #0000ff">this</span>-&gt;pt1.X) * (otherLine.pt0.X - otherLine.pt1.X) - (<span style="color: #0000ff">this</span>-&gt;pt0.X - <span style="color: #0000ff">this</span>-&gt;pt1.X) * (otherLine.pt0.X * otherLine.pt1.Y - otherLine.pt0.Y * otherLine.pt1.X)) / denom;
			result.Y = ((<span style="color: #0000ff">this</span>-&gt;pt0.X * <span style="color: #0000ff">this</span>-&gt;pt1.Y - <span style="color: #0000ff">this</span>-&gt;pt0.Y * <span style="color: #0000ff">this</span>-&gt;pt1.X) * (otherLine.pt0.Y - otherLine.pt1.Y) - (<span style="color: #0000ff">this</span>-&gt;pt0.Y - <span style="color: #0000ff">this</span>-&gt;pt1.Y) * (otherLine.pt0.X * otherLine.pt1.Y - otherLine.pt0.Y * otherLine.pt1.X)) / denom;
		}
		<span style="color: #0000ff">return</span> result;
	}

	Vector Reflect(MyPoint ptLight, Vector vecLight, MyPoint ptIntersect)
	{
		<span style="color: #0000ff">if</span> (abs(pt0.X - pt1.X) &lt; epsilon) <span style="color: #008000">// vertical line</span>
		{
			vecLight.X = -vecLight.X;
		}
		<span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (abs(pt0.Y - pt1.Y) &lt; epsilon)<span style="color: #008000">// horiz line</span>
		{
			vecLight.Y = -vecLight.Y;
		}
		<span style="color: #0000ff">else</span>
		{
			<span style="color: #008000">//// create incident line endpoint to intersection with correct seg length</span>
			CLine lnIncident(ptLight, ptIntersect);
			<span style="color: #008000">//var angBetween = lnIncidentTest.angleBetween(lnMirror);</span>
			<span style="color: #008000">//var angClosest = Math.Atan(lnMirror.slope) / _piOver180;</span>
			<span style="color: #008000">//var angIncident = Math.Atan(lnIncidentTest.slope) / _piOver180;</span>
			<span style="color: #008000">//var angReflect = 2 * angClosest - angIncident;</span>
			<span style="color: #0000ff">auto</span> newSlope = tan(2 * atan(slope()) - atan(lnIncident.slope()));
			<span style="color: #008000">// now we have the slope of the desired reflection line: </span>
			<span style="color: #008000">// now we need to determine the reflection direction (x &amp; y) along the slope</span>
			<span style="color: #008000">// The incident line came from one side (half plane) of the mirror. We need to leave on the same side.</span>
			<span style="color: #008000">// to do so, we assume we're going in a particular direction</span>
			<span style="color: #008000">// then we create a test point using the new slope</span>
			<span style="color: #008000">// we see which half plane the test point is in relation to the mirror.</span>
			<span style="color: #008000">// and which half plane the light source is. If they're different, we reverse the vector</span>

			<span style="color: #008000">// first set the new vector to the new slope in a guessed direction. </span>
			vecLight.X = SpeedMult;
			vecLight.Y = SpeedMult * newSlope;
			<span style="color: #008000">// create a test point along the line of reflection</span>
			MyPoint ptTest(ptIntersect.X + vecLight.X, ptIntersect.Y + vecLight.Y);
			<span style="color: #0000ff">auto</span> halfplaneLight = LeftHalf(ptLight);
			<span style="color: #0000ff">auto</span> halfplaneTestPoint = LeftHalf(ptTest);
			<span style="color: #0000ff">if</span> (halfplaneLight ^ halfplaneTestPoint) <span style="color: #008000">// xor</span>
			{
				vecLight.X = -vecLight.X;
				vecLight.Y = -vecLight.Y;
			}
		}
		<span style="color: #0000ff">return</span> vecLight;
	}

	MyPrecision slope()
	{
		<span style="color: #0000ff">return</span> deltaY() / deltaX();
	}

	<span style="color: #0000ff">bool</span> LeftHalf(MyPoint c)
	{
		<span style="color: #0000ff">auto</span> a = pt0;
		<span style="color: #0000ff">auto</span> b = pt1;
		<span style="color: #0000ff">auto</span> res = (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);
		<span style="color: #0000ff">return</span> res &gt; 0;
	}
	<span style="color: #0000ff">void</span> Draw(HDC hDC)
	{
		MoveToEx(hDC, (<span style="color: #0000ff">int</span>)pt0.X, (<span style="color: #0000ff">int</span>)pt0.Y, <span style="color: #0000ff">nullptr</span>);
		LineTo(hDC, (<span style="color: #0000ff">int</span>)pt1.X, (<span style="color: #0000ff">int</span>)pt1.Y);
	}

	<span style="color: #0000ff">bool</span> IsNull()
	{
		<span style="color: #0000ff">return</span> pt0.IsNull() || pt1.IsNull();
	}
	MyPoint pt0;
	MyPoint pt1;
	<span style="color: #0000ff">bool</span> IsLimitedInLength;
};


<span style="color: #0000ff">class</span> BounceFrame
{
	CComAutoCriticalSection csLstMirrors;
<span style="color: #808080">#define</span> LOCKMirrors CComCritSecLock&lt;CComAutoCriticalSection&gt; lock(csLstMirrors)
	vector&lt;shared_ptr&lt;IMirror&gt;&gt; _lstMirrors; <span style="color: #008000">// as in a List&lt;MyLine&gt;</span>
<span style="color: #808080">#define</span>  margin  5
<span style="color: #808080">#define</span> xScale 1
<span style="color: #808080">#define</span> yScale 1

	MyPoint _frameSize; <span style="color: #008000">// size of drawing area</span>
	HPEN _clrLine;
	HPEN _clrFillReflection;
	<span style="color: #0000ff">int</span> _colorReflection;
	<span style="color: #0000ff">int</span> _nPenWidth;
	HBRUSH _hBrushBackGround;
	MyPoint _ptOldMouseDown;
	MyPoint _ptCurrentMouseDown;
	<span style="color: #0000ff">bool</span> _fPenModeDrag = <span style="color: #0000ff">false</span>;
	<span style="color: #0000ff">bool</span> _fPenDown = <span style="color: #0000ff">false</span>;
	<span style="color: #0000ff">bool</span> _fIsRunning = <span style="color: #0000ff">false</span>;
	<span style="color: #0000ff">bool</span> _fCancelRequest = <span style="color: #0000ff">false</span>;
	<span style="color: #0000ff">int</span> _nDelayMsecs = 0;
	<span style="color: #0000ff">int</span> _nBounces = 0;
	DWORD _timeStartmSecs;
	Vector _vecLightInit;
	MyPoint _ptLightInit;
	<span style="color: #0000ff">int</span> _nOutofBounds;
<span style="color: #0000ff">public</span>:
	BounceFrame()
	{
		_nPenWidth = 1;
		_hBrushBackGround = CreateSolidBrush(0xffffff);
		_clrLine = CreatePen(0, _nPenWidth, 0x0);
		_colorReflection = 0xff;
		_clrFillReflection = CreatePen(0, _nPenWidth, _colorReflection);
		_ptLightInit.X = 140;
		_ptLightInit.Y = 140;
	}
	~BounceFrame()
	{
		DeleteObject(_hBrushBackGround);
		DeleteObject(_clrLine);
		DeleteObject(_clrFillReflection);
	}
<span style="color: #0000ff">private</span>:
	<span style="color: #0000ff">void</span> ShowStatusMsg(LPCWSTR pText, ...)
	{
		va_list args;
		va_start(args, pText);
		wstring strtemp(1000, <span style="color: #a31515">'\0'</span>);
		_vsnwprintf_s(&amp;strtemp[0], 1000, _TRUNCATE, pText, args);
		va_end(args);
		<span style="color: #0000ff">auto</span> len = wcslen(strtemp.c_str());
		strtemp.resize(len);
		HDC hDC = GetDC(g_hWnd);
		HFONT hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT);
		HFONT hOldFont = (HFONT)SelectObject(hDC, hFont);
		TextOut(hDC, 0, (<span style="color: #0000ff">int</span>)_frameSize.Y + 1, strtemp.c_str(), (<span style="color: #0000ff">int</span>)strtemp.size());
		SelectObject(hDC, hOldFont);
		ReleaseDC(g_hWnd, hDC);
	}
	<span style="color: #0000ff">void</span> DrawMirrors()
	{
		<span style="color: #0000ff">if</span> (g_hWnd != <span style="color: #0000ff">nullptr</span>)
		{
			HDC hDC = GetDC(g_hWnd);
			LOCKMirrors;
			SelectObject(hDC, _clrLine);
			<span style="color: #0000ff">for</span> (<span style="color: #0000ff">auto</span> line : _lstMirrors)
			{
				line-&gt;Draw(hDC);
			}
			<span style="color: #008000">//            Arc(hDC, 20, 20, 800, 400, 800, 200, 0, 200);</span>
			ReleaseDC(g_hWnd, hDC);
		}
	}
	<span style="color: #0000ff">void</span> SetColor(<span style="color: #0000ff">int</span> color)
	{
		_colorReflection = color;
		DeleteObject(_clrFillReflection);
		_clrFillReflection = CreatePen(<span style="color: #008000">/*nPenStyle:*/</span> 0, _nPenWidth, _colorReflection);

	}
	<span style="color: #0000ff">void</span> ChooseRandomStartingRay()
	{
		_ptLightInit.X = (MyPrecision)(margin + (_frameSize.X - 2 * margin)* ((<span style="color: #0000ff">double</span>)rand()) / RAND_MAX);
		_ptLightInit.Y = (MyPrecision)(margin + (_frameSize.Y - 2 * margin)* ((<span style="color: #0000ff">double</span>)rand()) / RAND_MAX);
		_vecLightInit.X = 1;
		_vecLightInit.Y = (MyPrecision)(((<span style="color: #0000ff">double</span>)rand()) / RAND_MAX);
	}

	<span style="color: #0000ff">void</span> Clear(<span style="color: #0000ff">bool</span> fKeepUserMirrors)
	{
		MyPoint topLeft = { margin, margin };
		MyPoint topRight = { _frameSize.X - margin, margin };
		MyPoint botLeft = { margin, _frameSize.Y - margin };
		MyPoint botRight = { _frameSize.X - margin,_frameSize.Y - margin };
		_ptCurrentMouseDown.Clear();
		_ptOldMouseDown.Clear();
		_fPenDown = <span style="color: #0000ff">false</span>;
		_fPenModeDrag = <span style="color: #0000ff">false</span>;
		_ptLightInit.X = 140;
		_ptLightInit.Y = 140;
		_vecLightInit.X = 11;
		_vecLightInit.Y = 10;
		_nBounces = 0;
		_nOutofBounds = 0;
		_colorReflection = 0;
		<span style="color: #0000ff">if</span> (!fKeepUserMirrors)
		{
			LOCKMirrors;
			_lstMirrors.clear();
			_lstMirrors.push_back(make_shared&lt;CLine&gt;(topLeft, topRight));
			_lstMirrors.push_back(make_shared&lt;CLine&gt;(topRight, botRight));
			_lstMirrors.push_back(make_shared&lt;CLine&gt;(botRight, botLeft));
			_lstMirrors.push_back(make_shared&lt;CLine&gt;(botLeft, topLeft));
		}
		<span style="color: #0000ff">if</span> (g_hWnd != <span style="color: #0000ff">nullptr</span>)
		{
			HDC hDC = GetDC(g_hWnd);
			RECT rect;
			GetClientRect(g_hWnd, &amp;rect);
			FillRect(hDC, &amp;rect, _hBrushBackGround);
			ReleaseDC(g_hWnd, hDC);
			DrawMirrors();
		}
	}

	<span style="color: #0000ff">int</span> DoReflecting()
	{
		<span style="color: #0000ff">int</span> nLastBounceWhenStagnant = 0;
		_timeStartmSecs = GetTickCount();
		_nOutofBounds = 0;
		HDC hDC = GetDC(g_hWnd);
		<span style="color: #0000ff">while</span> (_fIsRunning &amp;&amp; !_fCancelRequest)
		{
			<span style="color: #008000">//MyPoint ptEndIncident(_ptLight.x + _vecLight.x, _ptLight.y + _vecLight.y);</span>
			<span style="color: #008000">//auto lnIncident = MyLine(_ptLight, ptEndIncident);</span>
			<span style="color: #0000ff">auto</span> lnIncident = CLine(_ptLightInit, MyPoint(_ptLightInit.X + _vecLightInit.X, _ptLightInit.Y + _vecLightInit.Y));
			<span style="color: #0000ff">auto</span> minDist = 1000000.0;
			shared_ptr&lt;IMirror&gt; mirrorClosest;
			MyPoint ptIntersect = { 0,0 };
			{
				LOCKMirrors;
				<span style="color: #0000ff">for</span> (<span style="color: #0000ff">auto</span> mirror : _lstMirrors)
				{
					<span style="color: #0000ff">auto</span> ptIntersectTest = mirror-&gt;IntersectingPoint(_ptLightInit, _vecLightInit);;
					<span style="color: #0000ff">if</span> (!ptIntersectTest.IsNull())
					{
						<span style="color: #0000ff">auto</span> dist = _ptLightInit.DistanceFromPoint(ptIntersectTest);

						<span style="color: #0000ff">if</span> (dist &gt; epsilon &amp;&amp; dist &lt; minDist)
						{
							minDist = dist;
							mirrorClosest = mirror;
							ptIntersect = ptIntersectTest;
						}
					}
				}
			}
			<span style="color: #0000ff">if</span> (mirrorClosest == <span style="color: #0000ff">nullptr</span>)
			{
				<span style="color: #0000ff">if</span> (nLastBounceWhenStagnant == _nBounces)
				{<span style="color: #008000">// both the last bounce and this bounce were stagnant</span>
					nLastBounceWhenStagnant = _nBounces;
					_nOutofBounds++;
					ChooseRandomStartingRay();
				}
				<span style="color: #0000ff">else</span>
				{
					_vecLightInit.X = -_vecLightInit.X;
					nLastBounceWhenStagnant = _nBounces;
				}
				<span style="color: #0000ff">continue</span>;
			}
			<span style="color: #008000">// now draw incident line from orig pt to intersection</span>
			SelectObject(hDC, _clrFillReflection);
			<span style="color: #0000ff">if</span> (_nBounces == 1)
			{
				MoveToEx(hDC, (<span style="color: #0000ff">int</span>)(xScale * _ptLightInit.X), (<span style="color: #0000ff">int</span>)(yScale * _ptLightInit.Y), <span style="color: #0000ff">nullptr</span>);
			}
			LineTo(hDC, (<span style="color: #0000ff">int</span>)(xScale * ptIntersect.X), (<span style="color: #0000ff">int</span>)(yScale * ptIntersect.Y));

			<span style="color: #008000">// now reflect vector</span>
			_vecLightInit = mirrorClosest-&gt;Reflect(_ptLightInit, _vecLightInit, ptIntersect);


			<span style="color: #008000">// now set new pt </span>
			_ptLightInit = ptIntersect;
			SetColor((<span style="color: #0000ff">int</span>)_colorReflection + 1 &amp; 0xffffff);

			<span style="color: #0000ff">if</span> (_nDelayMsecs &gt; 0)
			{
				Sleep(_nDelayMsecs);
			}
			<span style="color: #0000ff">if</span> (_nBounces % 1000 == 0)
			{
				ShowStatus();
			}
			_nBounces++;

		}
		ReleaseDC(g_hWnd, hDC);
		_fCancelRequest = <span style="color: #0000ff">false</span>;
		<span style="color: #0000ff">return</span> 0;
	}
	<span style="color: #0000ff">static</span> DWORD WINAPI ThreadRoutine(<span style="color: #0000ff">void</span> *parm)
	{
		BounceFrame *pBounceFrame = (BounceFrame *)parm;
		<span style="color: #0000ff">return</span> pBounceFrame-&gt;DoReflecting();
	}

	<span style="color: #0000ff">void</span> CancelRunning()
	{
		<span style="color: #0000ff">if</span> (_fIsRunning)
		{
			_fCancelRequest = <span style="color: #0000ff">true</span>;
			_fIsRunning = <span style="color: #0000ff">false</span>;
			<span style="color: #0000ff">while</span> (_fCancelRequest)
			{
				Sleep(_nDelayMsecs + 10);
			}
		}
	}

	<span style="color: #0000ff">void</span> DoRunCommand()
	{
		_fIsRunning = !_fIsRunning;
		<span style="color: #0000ff">if</span> (_fIsRunning)
		{
			<span style="color: #0000ff">auto</span> hThread = CreateThread(
				<span style="color: #0000ff">nullptr</span>, <span style="color: #008000">// sec attr</span>
				0,  <span style="color: #008000">// stack size</span>
				ThreadRoutine,
				<span style="color: #0000ff">this</span>, <span style="color: #008000">// param</span>
				0, <span style="color: #008000">// creationflags</span>
				<span style="color: #0000ff">nullptr</span> <span style="color: #008000">// threadid</span>
			);
		}
		<span style="color: #0000ff">else</span>
		{
			CancelRunning();
		}
	}

	<span style="color: #0000ff">void</span> ShowStatus()
	{
		<span style="color: #0000ff">int</span> nBouncesPerSecond = 0;
		DWORD nTicks = GetTickCount() - _timeStartmSecs;
		<span style="color: #0000ff">if</span> (_fIsRunning)
		{
			nBouncesPerSecond = (<span style="color: #0000ff">int</span>)(_nBounces / (nTicks / 1000.0));
		}
		ShowStatusMsg(<span style="color: #a31515">L"Drag %d PenDown %d (%d,%d)-(%d,%d) Delay=%4d #M=%d OOB=%d #Bounces=%-10d # b/sec = %d      "</span>,
			_fPenModeDrag,
			_fPenDown,
			(<span style="color: #0000ff">int</span>)_ptOldMouseDown.X, (<span style="color: #0000ff">int</span>)_ptOldMouseDown.Y,
			(<span style="color: #0000ff">int</span>)_ptCurrentMouseDown.X, (<span style="color: #0000ff">int</span>)_ptCurrentMouseDown.Y,
			_nDelayMsecs,
			_lstMirrors.size(),
			_nOutofBounds,
			_nBounces,
			nBouncesPerSecond
		);
	}
<span style="color: #0000ff">public</span>:
	LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
	{
		<span style="color: #0000ff">switch</span> (message)
		{
		<span style="color: #0000ff">case</span> WM_SIZE:
		{
			_frameSize = MAKEPOINTS(lParam);
			_frameSize.Y -= 14; <span style="color: #008000">// room for status</span>
			Clear(<span style="color: #008000">/*fKeepUserMirrors=*/</span><span style="color: #0000ff">false</span>);
		}
		<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_RBUTTONDOWN:
			_fPenModeDrag = !_fPenModeDrag;
			_ptOldMouseDown = MAKEPOINTS(lParam);
			ShowStatus();
			<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_LBUTTONDOWN:
			<span style="color: #0000ff">if</span> (_fPenModeDrag)
			{
				_ptOldMouseDown = MAKEPOINTS(lParam);
			}
			<span style="color: #0000ff">else</span>
			{
				_ptCurrentMouseDown = MAKEPOINTS(lParam);
				<span style="color: #0000ff">if</span> (!_ptOldMouseDown.IsNull() &amp;&amp; _ptOldMouseDown != _ptCurrentMouseDown)
				{
					LOCKMirrors;
					_lstMirrors.push_back(make_shared&lt;CLine&gt;(_ptOldMouseDown, _ptCurrentMouseDown));
					DrawMirrors();
				}
				_ptOldMouseDown = _ptCurrentMouseDown;
			}
			ShowStatus();
			<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_MOUSEMOVE:
		{
			<span style="color: #0000ff">if</span> (_fPenModeDrag)
			{
				<span style="color: #0000ff">if</span> (GetAsyncKeyState(VK_CONTROL) &amp; 0x8000)
				{
					<span style="color: #0000ff">if</span> (!_ptOldMouseDown.IsNull())
					{
						_ptCurrentMouseDown = MAKEPOINTS(lParam);
						<span style="color: #0000ff">if</span> (_ptCurrentMouseDown != _ptOldMouseDown)
						{
							LOCKMirrors;
							_lstMirrors.push_back(make_shared&lt;CLine&gt;(_ptOldMouseDown, _ptCurrentMouseDown));
							_ptOldMouseDown = _ptCurrentMouseDown;
							DrawMirrors();
						}
					}
				}
				<span style="color: #0000ff">else</span>
				{
					_ptOldMouseDown.Clear();
				}
			}
			<span style="color: #0000ff">else</span>
			{
				<span style="color: #0000ff">if</span> (_fPenDown)
				{
					<span style="color: #0000ff">if</span> (!_ptOldMouseDown.IsNull())
					{
						_ptCurrentMouseDown = MAKEPOINTS(lParam);
					}
				}
			}
		}
		ShowStatus();
		<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_LBUTTONUP:
			<span style="color: #0000ff">if</span> (_fPenDown)
			{
				_ptCurrentMouseDown = MAKEPOINTS(lParam);
				<span style="color: #0000ff">if</span> (_ptCurrentMouseDown != _ptOldMouseDown)
				{
					LOCKMirrors;
					_lstMirrors.push_back(make_shared&lt;CLine&gt;(_ptOldMouseDown, _ptCurrentMouseDown));
					_ptOldMouseDown = _ptCurrentMouseDown;
					_fPenDown = <span style="color: #0000ff">false</span>;
					DrawMirrors();
				}
			}
			ShowStatus();
			<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_COMMAND:
		{
			<span style="color: #0000ff">int</span> wmId = LOWORD(wParam);
			<span style="color: #008000">// Parse the menu selections:</span>
			<span style="color: #0000ff">switch</span> (wmId)
			{
			<span style="color: #0000ff">case</span> ID_FILE_RUN:
				DoRunCommand();
				<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> ID_CLEAR:
				Clear(<span style="color: #008000">/*fKeepUserMirrors=*/</span><span style="color: #0000ff">true</span>);
				<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> ID_CLEARMIRRORS:
				Clear(<span style="color: #008000">/*fKeepUserMirrors=*/</span><span style="color: #0000ff">false</span>);
				<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> ID_FILE_SLOWER:
			{
				<span style="color: #0000ff">if</span> (_nDelayMsecs == 0)
				{
					_nDelayMsecs = 1;
				}
				<span style="color: #0000ff">else</span>
				{
					_nDelayMsecs *= 8;
				}
				ShowStatus();
			}
			<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> ID_FILE_FASTER:
			{
				_nDelayMsecs /= 8;
				ShowStatus();
			}
			<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> ID_FILE_UNDOLASTLINE:
				<span style="color: #008000">// don't erase the 4 walls</span>
				<span style="color: #0000ff">if</span> (_lstMirrors.size() &gt; 4)
				{
					LOCKMirrors;
					<span style="color: #0000ff">auto</span> last = _lstMirrors[_lstMirrors.size() - 1];
					_lstMirrors.pop_back();
					Clear(<span style="color: #008000">/*fKeepUserMirrors=*/</span><span style="color: #0000ff">true</span>);
					<span style="color: #0000ff">auto</span> lastLine = dynamic_pointer_cast&lt;CLine&gt;(last);
					<span style="color: #0000ff">if</span> (lastLine != <span style="color: #0000ff">nullptr</span>)
					{
						_ptOldMouseDown = lastLine-&gt;pt1;
					}
					ShowStatus();
				}
				<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> IDM_ABOUT:
				DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
				<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">case</span> IDM_EXIT:
				DestroyWindow(hWnd);
				<span style="color: #0000ff">break</span>;
			<span style="color: #0000ff">default</span>:
				<span style="color: #0000ff">return</span> DefWindowProc(hWnd, message, wParam, lParam);
			}
		}
		<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hWnd, &amp;ps);
			DrawMirrors();
			EndPaint(hWnd, &amp;ps);
		}
		<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">case</span> WM_DESTROY:
			CancelRunning();
			PostQuitMessage(0);
			<span style="color: #0000ff">break</span>;
		<span style="color: #0000ff">default</span>:
			<span style="color: #0000ff">return</span> DefWindowProc(hWnd, message, wParam, lParam);
		}
		<span style="color: #0000ff">return</span> 0;
	}
};

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	<span style="color: #0000ff">return</span> g_pBounceFrame-&gt;WndProc(hWnd, message, wParam, lParam);
}

<span style="color: #008000">// Message handler for about box.</span>
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	<span style="color: #0000ff">switch</span> (message)
	{
	<span style="color: #0000ff">case</span> WM_INITDIALOG:
		<span style="color: #0000ff">return</span> (INT_PTR)TRUE;

	<span style="color: #0000ff">case</span> WM_COMMAND:
		<span style="color: #0000ff">if</span> (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			<span style="color: #0000ff">return</span> (INT_PTR)TRUE;
		}
		<span style="color: #0000ff">break</span>;
	}
	<span style="color: #0000ff">return</span> (INT_PTR)FALSE;
}

<span style="color: #0000ff">int</span> APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine,
	_In_ <span style="color: #0000ff">int</span>       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	<span style="color: #008000">//create an instance of BounceFrame on the stack</span>
	<span style="color: #008000">// that lives until the app exits</span>
	BounceFrame bounceFrame;
	g_pBounceFrame = &amp;bounceFrame;

	<span style="color: #008000">// Initialize global strings</span>
	LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadStringW(hInstance, IDC_REFLECTCPP, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	<span style="color: #008000">// Perform application initialization:</span>
	<span style="color: #0000ff">if</span> (!InitInstance(hInstance, SW_MAXIMIZE))
	{
		<span style="color: #0000ff">return</span> FALSE;
	}

	HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_REFLECTCPP));

	MSG msg;

	<span style="color: #008000">// Main message loop:</span>
	<span style="color: #0000ff">while</span> (GetMessage(&amp;msg, <span style="color: #0000ff">nullptr</span>, 0, 0))
	{
		<span style="color: #0000ff">if</span> (!TranslateAccelerator(msg.hwnd, hAccelTable, &amp;msg))
		{
			TranslateMessage(&amp;msg);
			DispatchMessage(&amp;msg);
		}
	}

	<span style="color: #0000ff">return</span> (<span style="color: #0000ff">int</span>)msg.wParam;
}</code></pre></div>
<p>&lt;/code&gt;</p>
<p>&nbsp;</p>
<p>See also <br>Bouncing balls sample:<br><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2014/07/31/dpi-aware-sample/">https://blogs.msdn.microsoft.com/calvin_hsia/2014/07/31/dpi-aware-sample/</a></p>
<p><a href="https://blogs.msdn.microsoft.com/calvin_hsia/2018/01/31/store-different-derived-classes-in-collections-in-c-and-c-covariance-shared_ptr-unique_ptr/">https://blogs.msdn.microsoft.com/calvin_hsia/2018/01/31/store-different-derived-classes-in-collections-in-c-and-c-covariance-shared_ptr-unique_ptr/</a></p>
<p><a href="https://en.wikipedia.org/wiki/Illumination_problem">https://en.wikipedia.org/wiki/Illumination_problem</a> <br><a href="http://mathworld.wolfram.com/IlluminationProblem.html">http://mathworld.wolfram.com/IlluminationProblem.html</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>