dotMorten / WinUIEx

WinUI Extensions
https://dotmorten.github.io/WinUIEx
MIT License
572 stars 36 forks source link

WinUI EX Test App crashes when resizing the window (sometimes) #169

Open gmgallo opened 2 months ago

gmgallo commented 2 months ago

Hi @dotMorten, I was trying the Test App controls, mostly interested in the Windows Message logging, and ran into an unhandled exception while resizing. There is no a sure way to reproduce it but happens quite often. Maybe some line in the code is not posting to the UI thread when it should. I haven't delve deep into that yet, here is the screen capture: image

Also, regarding window message capture, I notice that mouse movement is only reported over non client areas (menu bar and edges) of the screen. You also get mouse buton press messages over controls but not button release, which you have otherwise from the UIElement with PointerXX events. Not trying to preach to choire here :-), but I think that this is what is happening: WindowMessageMonitor() is tapping to raw window messages with SetWindowSubclass(), which in theory should get everything, but it seems that WinUI installed an earlier filter in order to trigger all those PointerX events available in UIElement. To get all and every window message there is WindowMessageMonitor() must be instantiated much earlier in the app startup processes.

gmgallo commented 2 months ago

found the problem. It is the UpdateLog() call not enqueueed. By the time WindowEventLog.Text is updated it may have switched away from the UI thread. Hre is the fix:

// in MainWindow.Xaml.cs (much simpler)
public void Log(string message)
{ 
    WindowEvents.Enqueue(message);
    if (WindowEvents.Count > 100)
        WindowEvents.Dequeue();
    logWindow?.UpdateLog();
}

and

// In LogWindow.Xaml.cs
internal void UpdateLog()
{
    var log = MainWindow.WindowEvents;
    if (log != null)
    {
        var multiline_text = string.Join('\n', log.Reverse());
        DispatcherQueue.TryEnqueue(() =>
        {
            WindowEventLog.Text = multiline_text;
        });
    }
}

I ran into that trap thousand times. In my code I don't ever bother to test if I have the UI thread, just TryEnqueue() only the UI update line.

dotMorten commented 2 months ago

D'oh! Thanks for the catch. Much appreciated