<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel><title>Simon Mourier's blog</title>
<description>Simon Mourier's blog about Microsoft technologies C#, C/C++, .NET, WinRT, COM, DirectX, Direct2D, Direct Composition, Windows Shell, Windows Imaging (Wic), P/Invoke, Web, Desktop, Winforms, WPF, WinUI3, MAUI, SQLite, etc.</description>
<generator>SmoBlog</generator>
<link>https://www.simonmourier.com/</link><atom:link rel="self" type="application/rss+xml" href="https://www.simonmourier.com/feed/rss" xmlns:atom="http://www.w3.org/2005/Atom" />
<item>
  <title>How to do background scheduling (like Hangfire/Quartz) in a packaged WinUI 3 app that still passes the Store WACK?</title>
  <link>https://www.simonmourier.com/blog/79979643/</link>
  <description>&lt;p&gt;As stated in &lt;a href="https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/applifecycle/applifecycle" rel="nofollow noreferrer"&gt;Windows App SDK app lifecycle&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Windows App SDK apps, like UWP apps, are started and stopped. They are either running or not running. [...] unlike UWP apps, they cannot be suspended and resumed&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So if you run your background work in-process, you're fine, depending on what you really need, even a &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/system.threading.periodictimer" rel="nofollow noreferrer"&gt;PeriodicTimer&lt;/a&gt; is ok.&lt;/p&gt;
&lt;p&gt;If you must run out-of-process, the easiest is probably to write another .exe doing your cron work, add it to the package, and declare it as a &lt;a href="https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-extensions#start-an-executable-file-when-users-log-into-windows" rel="nofollow noreferrer"&gt;Startup Task&lt;/a&gt; for example:&lt;/p&gt;
&lt;pre class="lang-xml prettyprint-override"&gt;&lt;code class="language-cpp"&gt;&amp;lt;Package
  xmlns:desktop=&amp;quot;http://schemas.microsoft.com/appx/manifest/desktop/windows10&amp;quot;
  IgnorableNamespaces=&amp;quot;desktop&amp;quot;&amp;gt;
  &amp;lt;Applications&amp;gt;
    &amp;lt;Application&amp;gt;
      &amp;lt;Extensions&amp;gt;
        &amp;lt;desktop:Extension
          Category=&amp;quot;windows.startupTask&amp;quot;
          Executable=&amp;quot;bin\MyStartupTask.exe&amp;quot;
          EntryPoint=&amp;quot;Windows.FullTrustApplication&amp;quot;&amp;gt;
        &amp;lt;desktop:StartupTask
          TaskId=&amp;quot;MyStartupTask&amp;quot;
          Enabled=&amp;quot;false&amp;quot;
          DisplayName=&amp;quot;My App Service&amp;quot; /&amp;gt;
        &amp;lt;/desktop:Extension&amp;gt;
      &amp;lt;/Extensions&amp;gt;
    &amp;lt;/Application&amp;gt;
  &amp;lt;/Applications&amp;gt;
 &amp;lt;/Package&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See here to programmatically enable or disable your startup task: &lt;a href="https://learn.microsoft.com/en-us/uwp/api/windows.applicationmodel.startuptask#example" rel="nofollow noreferrer"&gt;StartupTask example&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As for local database storage, as long as you store it in the official package-relative &lt;a href="https://learn.microsoft.com/en-us/uwp/api/windows.storage.applicationdata.localfolder" rel="nofollow noreferrer"&gt;ApplicationData.Current.LocalFolder&lt;/a&gt;, it should be accessible by both applications.&lt;/p&gt;
</description>
  <category>winui</category>
  <category>concurrency</category>
  <category>winapi</category>
  <category>store</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79979643/</guid>
  <pubDate>Fri, 10 Jul 2026 14:19:37 GMT</pubDate>
</item>
<item>
  <title>Flickering when drawing to Windows.Forms with Direct2</title>
  <link>https://www.simonmourier.com/blog/79976399/</link>
  <description>&lt;p&gt;What happens is Winforms is based on Win32's GDI which draws the background first (using default window color) when painting and you then call &lt;code&gt;Clear(...)&lt;/code&gt; with some other color.&lt;/p&gt;
&lt;p&gt;There are at least two solutions to this (you can use both without harm):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;add this to your constructor (the control is drawn opaque and the background is not painted):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt; SetStyle(ControlStyles.Opaque,true);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;override OnPaintBackground and do nothing in it&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt; protected override void OnPaintBackground(PaintEventArgs e)
 {
     // do nothing
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;PS: that should be a full question, not an advice&lt;/p&gt;
</description>
  <category>c#</category>
  <category>winforms</category>
  <category>direct2D</category>
  <category>directx</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79976399/</guid>
  <pubDate>Tue, 07 Jul 2026 17:03:07 GMT</pubDate>
</item>
<item>
  <title>NtQuerySystemInformation returns zero ImageBase on Windows 11 25H2 — how to get kernel base without admin?</title>
  <link>https://www.simonmourier.com/blog/79950607/</link>
  <description>&lt;p&gt;It's documented here for &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumdevicedrivers" rel="nofollow noreferrer"&gt;EnumDeviceDrivers function&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Starting in Windows 11 Version 24H2, EnumDeviceDrivers will require SeDebugPrivilege to return valid ImageBase values. The function will still succeed if the caller does not have this privilege enabled, but the returned lpImageBase array will contain addresses that are all NULL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It sems logical and security consistent it's been extended to all (kernel) functions returning &lt;code&gt;ImageBase&lt;/code&gt; values.&lt;/p&gt;
</description>
  <category>winapi</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79950607/</guid>
  <pubDate>Wed, 03 Jun 2026 07:33:09 GMT</pubDate>
</item>
<item>
  <title>What Windows API should I use to create a blurred window?</title>
  <link>https://www.simonmourier.com/blog/79936602/</link>
  <description>&lt;p&gt;Layered Windows are an old thing. Technically on modern Windows, transparency like that is indeed achieved using the &amp;quot;Visual layer&amp;quot;, aka &amp;quot;Direct Composition&amp;quot;, the closest thing to the Desktop Windows Manager (the OS compositor).&lt;/p&gt;
&lt;p&gt;This is a Windows' WinRT API so you can use it from any language with WinRT binding (Microsoft provides .NET and C++). This API is located in the &lt;a href="https://learn.microsoft.com/en-us/uwp/api/windows.ui.composition" rel="nofollow noreferrer"&gt;Windows.UI.Composition&lt;/a&gt; WinRT namespace (&amp;quot;WUC&amp;quot;).&lt;/p&gt;
&lt;p&gt;The WinAppSDK with &lt;a href="https://learn.microsoft.com/en-us/windows/apps/winui/winui3/" rel="nofollow noreferrer"&gt;WinUI3&lt;/a&gt; provides another implementation of a Direct Composition client in the &lt;a href="https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.composition" rel="nofollow noreferrer"&gt;Microsoft.UI.Composition&lt;/a&gt; (&amp;quot;MUC&amp;quot;) namespace partially decoupled from Windows, this is today what Microsoft promote for what you want to do (again usable in .NET or C++).&lt;/p&gt;
&lt;p&gt;This sample here &lt;a href="https://github.com/aelyo-softworks/Wice" rel="nofollow noreferrer"&gt;https://github.com/aelyo-softworks/Wice&lt;/a&gt; demonstrates using WUC w/o any framework (it's C# but only using Win32/WinRT interop over WUC)&lt;/p&gt;
&lt;p&gt;Note another solution for what you want to do is to host a WebView2 (you can host it using Direct Composition instead of the traditional HWND way) with transparency enabled and let the WebView use its CSS (this project does that again using C# but using 100% native API). This other sample demonstrates that &lt;a href="https://github.com/smourier/ShellBat" rel="nofollow noreferrer"&gt;https://github.com/smourier/ShellBat&lt;/a&gt; (&amp;quot;Acrylic Almond theme shows a 100% transparent WebView2), cf &lt;a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2controller.defaultbackgroundcolor#remarks" rel="nofollow noreferrer"&gt;CoreWebView2Controller.DefaultBackgroundColor Property&lt;/a&gt;&lt;/p&gt;
</description>
  <category>c/c++</category>
  <category>winapi</category>
  <category>direct-composition</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79936602/</guid>
  <pubDate>Tue, 05 May 2026 21:26:45 GMT</pubDate>
</item>
<item>
  <title>IWebBrowser2::Quit Do not work on some explorer tabs</title>
  <link>https://www.simonmourier.com/blog/79919134/</link>
  <description>&lt;p&gt;Well, I can reproduce &amp;quot;sometimes&amp;quot;... It's strange but here is a workaround that should work, it uses &lt;a href="https://learn.microsoft.com/en-us/previous-versions/mt725310(v=vs.85)" rel="nofollow noreferrer"&gt;IWebBrowser2::HWND&lt;/a&gt; and &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-postmessagew" rel="nofollow noreferrer"&gt;PostMessage&lt;/a&gt; asking the owner window to close:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var staThread = new Thread(() =&amp;gt;
{
    var shellType = Type.GetTypeFromCLSID(new Guid(&amp;quot;9BA05972-F6A8-11CF-A442-00A0C90A8F39&amp;quot;))!;
    dynamic shellWindows = Activator.CreateInstance(shellType!)!;

    // we need to loop here because some windows may not close immediately
    do
    {
        var toClose = new List&amp;lt;dynamic&amp;gt;();
        foreach (var window in shellWindows)
        {
            // add your logic here...
            toClose.Add(window);
        }
        if (toClose.Count == 0)
            break;

        foreach (var window in toClose)
        {
            nint hwnd;
            try
            {
                hwnd = (nint)window.HWND;
            }
            catch
            {
                continue;
            }

            const uint WM_CLOSE = 0x0010;
            PostMessage(hwnd, WM_CLOSE, 0, 0);
        }
    } while (true);
});

staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();

[DllImport(&amp;quot;user32&amp;quot;)]
public static extern nint PostMessage(nint hWnd, uint Msg, nint wParam, nint lParam);

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PS: your definition of &lt;code&gt;IShellWindows&lt;/code&gt; is useless since you use &lt;code&gt;dynamic&lt;/code&gt; (&lt;code&gt;IDispatch&lt;/code&gt; undercovers).&lt;/p&gt;
</description>
  <category>c#</category>
  <category>winapi</category>
  <category>com</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79919134/</guid>
  <pubDate>Thu, 02 Apr 2026 17:06:06 GMT</pubDate>
</item>
<item>
  <title>What/How is `D3DKMT_BRIGHTNESS_INFO` used for?</title>
  <link>https://www.simonmourier.com/blog/79910661/</link>
  <description>&lt;p&gt;These functions are for kernel mode. In user mode you can use &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/highlevelmonitorconfigurationapi/nf-highlevelmonitorconfigurationapi-getmonitorbrightness" rel="nofollow noreferrer"&gt;GetMonitorBrightness&lt;/a&gt; but it will only work if your monitor supports it.&lt;/p&gt;
</description>
  <category>c/c++</category>
  <category>winapi</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79910661/</guid>
  <pubDate>Thu, 19 Mar 2026 14:37:20 GMT</pubDate>
</item>
<item>
  <title>Providing stubs to a static library</title>
  <link>https://www.simonmourier.com/blog/79910129/</link>
  <description>&lt;p&gt;In the end, you should always be able to provide ABI-compatible .obj files that you compiled yourself (not necessarily in assembler, C or &amp;quot;extern C&amp;quot; C++ for example)&lt;/p&gt;
</description>
  <category>system</category>
  <category>winapi</category>
  <category>c/c++</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79910129/</guid>
  <pubDate>Wed, 18 Mar 2026 17:29:51 GMT</pubDate>
</item>
<item>
  <title>How to check if Windows TPM is available and enabled using NCrypt API?</title>
  <link>https://www.simonmourier.com/blog/79909778/</link>
  <description>&lt;p&gt;AI probably told you that crap :-) Here's the official way &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/tbs/nf-tbs-tbsi_getdeviceinfo" rel="nofollow noreferrer"&gt;Tbsi_GetDeviceInfo&lt;/a&gt; There's also the simple function &lt;code&gt;BOOL WINAPI Tbsi_Is_Tpm_Present()&lt;/code&gt; in the same tbs.h file, it's not visible in the doc but works.&lt;/p&gt;
</description>
  <category>c/c++</category>
  <category>winapi</category>
  <category>cryptography</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79909778/</guid>
  <pubDate>Wed, 18 Mar 2026 08:18:31 GMT</pubDate>
</item>
<item>
  <title>Windows application packaging project for native AOT</title>
  <link>https://www.simonmourier.com/blog/76359820/</link>
  <description>&lt;p&gt;Here's one solution (works for any .exe in fact), not sure it's officially sanctified though:&lt;/p&gt;
&lt;p&gt;Once you have created your packaging project, instead of adding a reference, just change the  &lt;code&gt;.wapproj&lt;/code&gt;, add these properties (adapt to your context):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;  &amp;lt;PropertyGroup&amp;gt;
    ...
    &amp;lt;AppxBundlePlatforms&amp;gt;x64&amp;lt;/AppxBundlePlatforms&amp;gt;
    &amp;lt;EntryPointExe&amp;gt;MyApp.exe&amp;lt;/EntryPointExe&amp;gt;
    ...
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    ...
    &amp;lt;Content Include=&amp;quot;..\MyApp\bin\x64\Release\net10.0-windows10.0.22000.0\publish\MyApp.exe&amp;quot;&amp;gt;
      &amp;lt;Link&amp;gt;MyApp.exe&amp;lt;/Link&amp;gt;
      &amp;lt;CopyToOutputDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToOutputDirectory&amp;gt;
    &amp;lt;/Content&amp;gt;
    ...
  &amp;lt;/ItemGroup&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
</description>
  <category>c#</category>
  <category>console</category>
  <category>windows-shell</category>
  <category>aot</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/76359820/</guid>
  <pubDate>Thu, 05 Mar 2026 09:06:25 GMT</pubDate>
</item>
<item>
  <title>Integrating Windows Explorer as a control in Windows 11</title>
  <link>https://www.simonmourier.com/blog/79900361/</link>
  <description>&lt;p&gt;Yes, you can use &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-inamespacetreecontrol" rel="nofollow noreferrer"&gt;INameSpaceTreeControl&lt;/a&gt; as shown here &lt;a href="https://stackoverflow.com/a/48591421/403671"&gt;https://stackoverflow.com/a/48591421/403671&lt;/a&gt;&lt;/p&gt;
</description>
  <category>winapi</category>
  <category>com</category>
  <category>windows-shell</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79900361/</guid>
  <pubDate>Tue, 03 Mar 2026 23:11:22 GMT</pubDate>
</item>
<item>
  <title>How to ask Windows if a printer spools or not (in either .NET or Win32)?</title>
  <link>https://www.simonmourier.com/blog/79897185/</link>
  <description>&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/printdocs/getprinter" rel="nofollow noreferrer"&gt;GetPrinter(...,2,...)&lt;/a&gt; should get you a &lt;a href="https://learn.microsoft.com/en-us/windows/win32/printdocs/printer-info-2" rel="nofollow noreferrer"&gt;PRINTER_INFO_2&lt;/a&gt; that has an &lt;code&gt;Attribute&lt;/code&gt; field that can contain &lt;code&gt;PRINTER_ATTRIBUTE_DIRECT&lt;/code&gt; (=2) if job is sent directly to the printer, not spooled.&lt;/p&gt;
</description>
  <category>.net</category>
  <category>winapi</category>
  <category>printing</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79897185/</guid>
  <pubDate>Thu, 26 Feb 2026 16:38:33 GMT</pubDate>
</item>
<item>
  <title>How do I get SCons to work on the Windows 10 command line?</title>
  <link>https://www.simonmourier.com/blog/59097128/</link>
  <description>&lt;p&gt;FWIW, in case this can be useful to anyone, I had &lt;strong&gt;no&lt;/strong&gt; &lt;code&gt;scons.bat&lt;/code&gt; anywhere in the tons of my python directories (much could be said also about python install mess...) after having done all the usual python pip trials.&lt;/p&gt;
&lt;p&gt;So what I did is create a &lt;code&gt;scons.bat&lt;/code&gt; file manually in a folder that I know is in my &lt;em&gt;PATH&lt;/em&gt; with simply this inside:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-python"&gt;python -m SCons %*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note SCons is here &lt;strong&gt;case-sensitive&lt;/strong&gt;&lt;/p&gt;
</description>
  <category>python</category>
  <category>winapi</category>
  <category>console</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/59097128/</guid>
  <pubDate>Sat, 31 Jan 2026 12:08:19 GMT</pubDate>
</item>
<item>
  <title>How to prevent "appstarting" cursor when calling IContextMenu::QueryContextMenu?</title>
  <link>https://www.simonmourier.com/blog/79851038/</link>
  <description>&lt;p&gt;This is not officially documented but you can implement the &lt;code&gt;IWaitCursorManager&lt;/code&gt; interface, here is its definition (in C#):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;[Guid(&amp;quot;fc992f1f-debb-4596-b355-50c7a6dd1222&amp;quot;)]
public interface IWaitCursorManager
{
    HRESULT Start(CURSORID id);
    HRESULT Restore();
    HRESULT Stop(CURSORID id);
}

public enum CURSORID
{
    CID_WAIT = 0,
    CID_APPSTARTING = 1,
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To implement it you must pass a &amp;quot;site&amp;quot; to the &lt;code&gt;IContextMenu&lt;/code&gt; implementation. For that just &lt;code&gt;QueryInterface&lt;/code&gt; it for the &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/ocidl/nn-ocidl-iobjectwithsite" rel="nofollow noreferrer"&gt;IObjectWithSite&lt;/a&gt; interface, something like this (again in C#)&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;var ows = (IObjectWithSite)contextMenu;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then pass a COM object of yours that must implement &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/servprov/nn-servprov-iserviceprovider" rel="nofollow noreferrer"&gt;IServiceProvider&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;var mySite = new MySite();
ows.SetSite(mySite);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your COM object will be called on &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/servprov/nf-servprov-iserviceprovider-queryservice(refguid_refiid_void)" rel="nofollow noreferrer"&gt;QueryService&lt;/a&gt; for a &lt;code&gt;IWaitCursorManager&lt;/code&gt;'s IID (among other IIDs). Pass an implementation of it that does nothing, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;public class MySite : IServiceProvider, IWaitCursorManager
{
    HRESULT QueryService(Guid siid,  Guid iid,  out object obj)
    {
       if (iid == typeof(IWaitCursorManager).Guid)
       {
          obj = this;
          return 0;
       }
          
       ...
    }

    HRESULT Start(CURSORID id)
    {
        return 0;
    }   
    
    HRESULT Restore()
    {
        return 0;
    }   

    HRESULT Stop(CURSORID id)
    {
        return 0;
    }   
}

&lt;/code&gt;&lt;/pre&gt;
</description>
  <category>winapi</category>
  <category>rust</category>
  <category>windows-shell</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79851038/</guid>
  <pubDate>Mon, 22 Dec 2025 16:17:29 GMT</pubDate>
</item>
<item>
  <title>Is it possible to connect the New Outlook for Windows to our own server?</title>
  <link>https://www.simonmourier.com/blog/79847805/</link>
  <description>&lt;p&gt;Outlook for Windows is a pure web app, so you can't use COM addins, see here &lt;a href="https://learn.microsoft.com/en-us/microsoft-365-apps/outlook/get-started/state-of-com-add-ins" rel="nofollow noreferrer"&gt;https://learn.microsoft.com/en-us/microsoft-365-apps/outlook/get-started/state-of-com-add-ins&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The new Outlook for Windows doesn't support COM add-ins, but it does support Office web add-ins. To learn more about Office Add-ins, see Office Add-ins platform overview.&lt;/p&gt;
&lt;p&gt;For guidance to migrate COM add-ins to web add-ins, see Migrate from COM to web add-ins.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
  <category>com</category>
  <category>outlook</category>
  <category>winapi</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79847805/</guid>
  <pubDate>Mon, 15 Dec 2025 17:11:04 GMT</pubDate>
</item>
<item>
  <title>What are the strengths and weaknesses of using VTable/COM-centric APIs?</title>
  <link>https://www.simonmourier.com/blog/79842064/</link>
  <description>&lt;p&gt;This is why Microsoft has taken the COM approach more than 30 years ago and sticks with it (WinRT &lt;em&gt;is&lt;/em&gt; COM) almost everywhere in Windows. At its root, COM is &amp;quot;just&amp;quot; a &lt;em&gt;binary&lt;/em&gt; (not source code, this is fundamental) reusable contract, the vtable, plus the &lt;code&gt;IUnknown&lt;/code&gt; interface. Then, on top of this you have many optional other services (factory, registration, automation, threading, etc.). Just using vtable + IUnknown is often called &amp;quot;Nano COM&amp;quot; today. Typically the DirectX devs (Direct3D, Direct2D, DirectWrite, DirectComposition, etc.) have chosen this path, they provide an initial factory (no &lt;code&gt;CoCreateInstance&lt;/code&gt;/registry needed) and you can program the whole API using binary interfaces. If you can get a copy of &amp;quot;Essential COM&amp;quot; by Don Box, that may be of interest (especially the first pages that explain history, links with C++, etc.).&lt;/p&gt;
</description>
  <category>c/c++</category>
  <category>com</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79842064/</guid>
  <pubDate>Tue, 09 Dec 2025 15:16:36 GMT</pubDate>
</item>
<item>
  <title>How to force the Application.Run to wait for all async void handlers?</title>
  <link>https://www.simonmourier.com/blog/79821798/</link>
  <description>&lt;p&gt;Since what causes Application.Run to return is the main form closing, the most simple not hacky way to do it for me seems to prevent the form from closing (duh).&lt;/p&gt;
&lt;p&gt;For example with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;internal static class Program
{
    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();
        var completedOperations = 0;
        var form = new Form();

        form.FormClosing += EarlyClosingBlocker.HandleFormClosing;
        form.Load += (s, e) =&amp;gt; _ = EarlyClosingBlocker.Run(async () =&amp;gt;
        {
            await Task.Delay(1000);
            completedOperations++;
        });

        form.Shown += (s, e) =&amp;gt; _ = EarlyClosingBlocker.Run(async () =&amp;gt;
        {
            await Task.Delay(2000);
            completedOperations++;
        });

        Application.Run(form);
        MessageBox.Show($&amp;quot;Completed operations: {completedOperations}&amp;quot;);
    }
}

public static class EarlyClosingBlocker
{
    private static readonly ConcurrentDictionary&amp;lt;AutoResetEvent, object?&amp;gt; _waitEvents = new();

    public static async Task Run(Func&amp;lt;Task&amp;gt; action)
    {
        var are = new AutoResetEvent(false);
        _waitEvents[are] = null;
        try
        {
            await action();
        }
        finally
        {
            are.Set();
            _waitEvents.TryRemove(are, out _);
        }
    }

    public static void HandleFormClosing(object? sender, FormClosingEventArgs e)
    {
        var events = _waitEvents.ToArray();
        if (events.Length == 0)
            return;

        // note we could use e.CloseReason to decide not to wait whatsoever
        e.Cancel = true;
        var form = (Form)sender!;
        form.Hide(); // or put a message, etc.
        _ = Task.Run(() =&amp;gt;
        {
            // wait for all events to finish, note this cannot run in an STA thread
            WaitHandle.WaitAll([.. events.Select(e =&amp;gt; e.Key)]);
            form.BeginInvoke(form.Close);
        });
    }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
  <category>c#</category>
  <category>winforms</category>
  <category>algorithms</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79821798/</guid>
  <pubDate>Wed, 19 Nov 2025 07:29:10 GMT</pubDate>
</item>
<item>
  <title>Flickering when drawing to IDCompositionSurface</title>
  <link>https://www.simonmourier.com/blog/79822270/</link>
  <description>&lt;p&gt;If you want to use Direct2D with Direct Composition, you want to use &lt;code&gt;IDCompositionSurface::BeginDraw&lt;/code&gt; asking for a D2D device context. Note for that you must create the Direct Composition device using a D2D device.&lt;/p&gt;
&lt;p&gt;This code should work better:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;int main()
{
    constexpr const wchar_t* WINDOW_CLASS_NAME = _T(&amp;quot;a&amp;quot;);
    constexpr const wchar_t* WINDOW_TITLE_NAME = _T(&amp;quot;a&amp;quot;);

    HRESULT hr = S_OK;

    CComPtr&amp;lt;ID3D11Device&amp;gt; d3dDevice;
    hr = D3D11CreateDevice(
        nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr,
        D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG,
        nullptr, 0, D3D11_SDK_VERSION, &amp;amp;d3dDevice, nullptr, nullptr
    );
    CComPtr&amp;lt;IDXGIDevice&amp;gt; dxgiDevice;
    hr = d3dDevice-&amp;gt;QueryInterface(IID_PPV_ARGS(&amp;amp;dxgiDevice));

    CComPtr&amp;lt;ID2D1Device&amp;gt; d2dDevice;
    D2D1_CREATION_PROPERTIES creationProc = {};
    creationProc.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
    hr = D2D1CreateDevice(dxgiDevice, creationProc, &amp;amp;d2dDevice);

    // *use D2D device to create DComp device*
    CComPtr&amp;lt;IDCompositionDesktopDevice&amp;gt; dcDesktopDevice;
    hr = DCompositionCreateDevice3(d2dDevice, IID_PPV_ARGS(&amp;amp;dcDesktopDevice));

    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.style = CS_NOCLOSE | CS_VREDRAW | CS_HREDRAW;
    wndClass.lpfnWndProc = DefWindowProc;
    wndClass.hInstance = GetModuleHandle(NULL);
    wndClass.lpszClassName = WINDOW_CLASS_NAME;
    hr = RegisterClassEx(&amp;amp;wndClass) ? S_OK : E_FAIL;

    HWND hwnd;
    hwnd = CreateWindowEx(
        WS_EX_OVERLAPPEDWINDOW | WS_EX_TRANSPARENT | WS_EX_NOREDIRECTIONBITMAP,
        WINDOW_CLASS_NAME, WINDOW_TITLE_NAME,
        WS_POPUP | WS_VISIBLE,
        1100, 980, 800, 80,
        nullptr, nullptr, GetModuleHandle(nullptr), nullptr
    ); hr = hwnd ? S_OK : E_FAIL;
    SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

    CComPtr&amp;lt;IDCompositionTarget&amp;gt; dcTarget;
    hr = dcDesktopDevice-&amp;gt;CreateTargetForHwnd(hwnd, FALSE, &amp;amp;dcTarget);

    CComPtr&amp;lt;IDCompositionVisual2&amp;gt; dcVisual;
    hr = dcDesktopDevice-&amp;gt;CreateVisual(&amp;amp;dcVisual);
    dcTarget-&amp;gt;SetRoot(dcVisual);

    CComPtr&amp;lt;IDCompositionSurface&amp;gt; surface;
    hr = dcDesktopDevice-&amp;gt;CreateSurface(
        800, 80,
        DXGI_FORMAT_B8G8R8A8_UNORM,
        DXGI_ALPHA_MODE_PREMULTIPLIED,
        &amp;amp;surface
    );
    hr = dcVisual-&amp;gt;SetContent(surface);

    while (true)
    {
        POINT drawOffset = { 0,0 };
        CComPtr&amp;lt;ID2D1DeviceContext&amp;gt; d2dContext;
        hr = surface-&amp;gt;BeginDraw(nullptr, IID_PPV_ARGS(&amp;amp;d2dContext), &amp;amp;drawOffset);

        d2dContext-&amp;gt;Clear();

        // you *MUST* use the drawoffset you get back 
        d2dContext-&amp;gt;SetTransform(D2D1::Matrix3x2F::Translation((FLOAT)drawOffset.x, (FLOAT)drawOffset.y));

        CComPtr&amp;lt;ID2D1SolidColorBrush&amp;gt; brush;
        hr = d2dContext-&amp;gt;CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &amp;amp;brush);
        d2dContext-&amp;gt;FillRoundedRectangle(D2D1_ROUNDED_RECT{ D2D1::RectF(10,10,200,50), 10, 10 }, brush);

        hr = surface-&amp;gt;EndDraw();
        hr = dcDesktopDevice-&amp;gt;Commit();
        hr = dcDesktopDevice-&amp;gt;WaitForCommitCompletion(); // optional
        Sleep(50); // this and the loop is optional see remarks
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note you don't need to call Sleep and do it again as with Direct Composition, you &lt;em&gt;compose&lt;/em&gt; your scene usually once (unless you want to animate it of course), you don't need to refresh it again at each vblank.&lt;/p&gt;
&lt;p&gt;Also, it's much better to use &lt;a href="https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/ui/visual-layer-in-desktop-apps" rel="nofollow noreferrer"&gt;Windows Visual Layer&lt;/a&gt; wich is simply the evolution of Direct Composition. It's not at all restricted to UWP, but it does require using WinRT API. There's an official example here &lt;a href="https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/HelloComposition" rel="nofollow noreferrer"&gt;https://github.com/microsoft/Windows.UI.Composition-Win32-Samples/tree/master/cpp/HelloComposition&lt;/a&gt; and a less bloated one here &lt;a href="https://gist.github.com/kennykerr/62923cdacaba28fedc4f3dab6e0c12ec" rel="nofollow noreferrer"&gt;https://gist.github.com/kennykerr/62923cdacaba28fedc4f3dab6e0c12ec&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With the Visual Layer the idea is roughly the same you can use a &lt;a href="https://learn.microsoft.com/en-us/uwp/api/windows.ui.composition.spritevisual" rel="nofollow noreferrer"&gt;SpriteVisual&lt;/a&gt; and from that SpriteVisual you can get a D2D context to write &lt;a href="https://learn.microsoft.com/en-us/windows/uwp/composition/composition-native-interop" rel="nofollow noreferrer"&gt;https://learn.microsoft.com/en-us/windows/uwp/composition/composition-native-interop&lt;/a&gt;&lt;/p&gt;
</description>
  <category>winapi</category>
  <category>directx</category>
  <category>direct2D</category>
  <category>direct-composition</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79822270/</guid>
  <pubDate>Tue, 18 Nov 2025 07:37:32 GMT</pubDate>
</item>
<item>
  <title>CsWin32 how to create an instance of PWSTR for e.g. GetWindowText</title>
  <link>https://www.simonmourier.com/blog/78300830/</link>
  <description>&lt;p&gt;With the latest version of &lt;a href="https://microsoft.github.io/CsWin32/docs/getting-started.html" rel="nofollow noreferrer"&gt;CsWin32&lt;/a&gt;, currently 0.3.242, this is much more simple and natural than it used to be:&lt;/p&gt;
&lt;p&gt;NativeMethods.txt:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;GetWindowTextW
GetWindowTextLengthW

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Program.cs:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;...
var len = PInvoke.GetWindowTextLength(hwnd);
Span&amp;lt;char&amp;gt; chars = new char[len + 1];
PInvoke.GetWindowText(hwnd, chars);
var text = chars.ToString();
...
&lt;/code&gt;&lt;/pre&gt;
</description>
  <category>c#</category>
  <category>winapi</category>
  <category>interop</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/78300830/</guid>
  <pubDate>Tue, 04 Nov 2025 21:58:28 GMT</pubDate>
</item>
<item>
  <title>COM CCertRequest via CSWin32</title>
  <link>https://www.simonmourier.com/blog/79808656/</link>
  <description>&lt;p&gt;It should work, but it depends on your configuration. Also note CsWin32 has been &lt;a href="https://microsoft.github.io/CsWin32/docs/getting-started.html" rel="nofollow noreferrer"&gt;greatly improved lately&lt;/a&gt; and you want to use the &lt;code&gt;CsWin32RunAsBuildTask &lt;/code&gt;directive, so here's an example that works:&lt;/p&gt;
&lt;p&gt;csproj:
`&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;&amp;lt;PropertyGroup&amp;gt;
    &amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net9.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;
    &amp;lt;AllowUnsafeBlocks&amp;gt;true&amp;lt;/AllowUnsafeBlocks&amp;gt;
    &amp;lt;CsWin32RunAsBuildTask&amp;gt;true&amp;lt;/CsWin32RunAsBuildTask&amp;gt;
    &amp;lt;DisableRuntimeMarshalling&amp;gt;true&amp;lt;/DisableRuntimeMarshalling&amp;gt;
    &amp;lt;InvariantGlobalization&amp;gt;true&amp;lt;/InvariantGlobalization&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;

&amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include=&amp;quot;Microsoft.Windows.CsWin32&amp;quot; Version=&amp;quot;0.3.242&amp;quot;&amp;gt;
        &amp;lt;PrivateAssets&amp;gt;all&amp;lt;/PrivateAssets&amp;gt;
        &amp;lt;IncludeAssets&amp;gt;runtime; build; native; contentfiles; analyzers; buildtransitive&amp;lt;/IncludeAssets&amp;gt;
    &amp;lt;/PackageReference&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

`
&lt;p&gt;NativeMethods.txt:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;ICertAdmin
CCertRequest
ICertRequest
ICertRequest2
ICertRequest3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Program.cs:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-cpp"&gt;using System;
using System.Runtime.Versioning;
using Windows.Win32.Security.Cryptography.Certificates;

[assembly: SupportedOSPlatform(&amp;quot;windows5.1.2600&amp;quot;)]

namespace Test;

internal class Program
{
    static void Main()
    {
        var instance = CCertRequest.CreateInstance&amp;lt;ICertRequest&amp;gt;();
        Console.WriteLine(instance);
    }
}

&lt;/code&gt;&lt;/pre&gt;
</description>
  <category>winapi</category>
  <category>com</category>
  <category>interop</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79808656/</guid>
  <pubDate>Tue, 04 Nov 2025 08:56:14 GMT</pubDate>
</item>
<item>
  <title>How to get the HWND handle of elements in .Net MAUI</title>
  <link>https://www.simonmourier.com/blog/79772961/</link>
  <description>&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/apps/winui/winui3/" rel="nofollow noreferrer"&gt;WinUI3&lt;/a&gt; is the technology used by MAUI on Windows, and you can refer to &lt;a href="https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/windowing-overview" rel="nofollow noreferrer"&gt;Windowing overview for WinUI and Windows App SDK&lt;/a&gt; to understand the link between a WinUI3 Window to a Win32 HWND.&lt;/p&gt;
&lt;p&gt;Then, you can use &lt;a href="https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/app-lifecycle#windows" rel="nofollow noreferrer"&gt;Platform lifecycle events&lt;/a&gt; to get it, something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Microsoft.Maui.LifecycleEvents;

namespace MauiApp1
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp&amp;lt;App&amp;gt;()
                .ConfigureLifecycleEvents(events =&amp;gt;
                {
#if WINDOWS
                    events.AddWindows(bld =&amp;gt;
                    {
                        // window here is of Microsoft.UI.Xaml.Window type (WinUI3)
                        bld.OnWindowCreated(window =&amp;gt;
                        {
                            var hwnd = Microsoft.UI.Win32Interop.GetWindowFromWindowId(window.AppWindow.Id);
                        });
                    });
#endif
                });

            return builder.Build();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
  <category>c#</category>
  <category>wpf</category>
  <category>maui</category>
  <category>winui</category>
  <guid isPermaLink="false">https://www.simonmourier.com/blog/79772961/</guid>
  <pubDate>Tue, 23 Sep 2025 20:00:57 GMT</pubDate>
</item></channel>
</rss>