diff --git a/QuickLook/App.xaml.cs b/QuickLook/App.xaml.cs index 58855d1..a150764 100644 --- a/QuickLook/App.xaml.cs +++ b/QuickLook/App.xaml.cs @@ -145,19 +145,26 @@ public partial class App : Application { ProcessHelper.WriteLog(e.Exception.ToString()); - var result = System.Windows.Forms.MessageBox.Show( - $"{e.Exception.Message} most often due to a lack of graphics resources or hardware/driver limitations in allocating a sufficiently large texture.\nAre you want to fall back to use software render only?", + // Under this exception, WPF rendering has crashed + // and the user must be notified using native MessageBox + var result = User32.MessageBoxW( + new WindowInteropHelper(Current.MainWindow).Handle, + $""" + {e.Exception.Message} was most often due to a lack of graphics resources or hardware/driver constraints when attempting to allocate large textures. + + Although not usually recommended, would you prefer to use software rendering exclusively? + """, "Fatal", - System.Windows.Forms.MessageBoxButtons.YesNo, - System.Windows.Forms.MessageBoxIcon.Error + User32.MessageBoxType.YesNo | User32.MessageBoxType.IconError | User32.MessageBoxType.DefButton2 ); - if (result == System.Windows.Forms.DialogResult.Yes) + if (result == User32.MessageBoxResult.IDYES) { SettingHelper.Set("ProcessRenderMode", (int)RenderMode.SoftwareOnly, "QuickLook"); } TrayIconManager.GetInstance().Restart(forced: true); + e.Handled = true; return; } diff --git a/QuickLook/NativeMethods/SHCore.cs b/QuickLook/NativeMethods/SHCore.cs index fa11a2b..084c59c 100644 --- a/QuickLook/NativeMethods/SHCore.cs +++ b/QuickLook/NativeMethods/SHCore.cs @@ -1,4 +1,21 @@ -using System.Runtime.InteropServices; +// Copyright © 2017-2025 QL-Win Contributors +// +// This file is part of QuickLook program. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Runtime.InteropServices; namespace QuickLook.NativeMethods; diff --git a/QuickLook/NativeMethods/User32.cs b/QuickLook/NativeMethods/User32.cs new file mode 100644 index 0000000..a75db2d --- /dev/null +++ b/QuickLook/NativeMethods/User32.cs @@ -0,0 +1,75 @@ +// Copyright © 2017-2025 QL-Win Contributors +// +// This file is part of QuickLook program. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Runtime.InteropServices; + +namespace QuickLook.NativeMethods; + +internal static class User32 +{ + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + public static extern MessageBoxResult MessageBoxW(nint hWnd, string text, string caption, MessageBoxType type); + + [Flags] + public enum MessageBoxType : uint + { + Ok = 0x00000000, // Buttons + OkCancel = 0x00000001, + AbortRetryIgnore = 0x00000002, + YesNoCancel = 0x00000003, + YesNo = 0x00000004, + RetryCancel = 0x00000005, + CancelTryContinue = 0x00000006, + + IconHand = 0x00000010, // Icons + IconQuestion = 0x00000020, + IconExclamation = 0x00000030, + IconAsterisk = 0x00000040, + IconWarning = IconExclamation, + IconError = IconHand, + IconInformation = IconAsterisk, + + DefButton1 = 0x00000000, // Default button + DefButton2 = 0x00000100, + DefButton3 = 0x00000200, + DefButton4 = 0x00000300, + + ApplModal = 0x00000000, // Modality + SystemModal = 0x00001000, + TaskModal = 0x00002000, + + Help = 0x00004000, // Other options + SetForeground = 0x00010000, + TopMost = 0x00040000, + Right = 0x00080000, + RtlReading = 0x00100000, + } + + public enum MessageBoxResult : int + { + IDOK = 1, + IDCANCEL = 2, + IDABORT = 3, + IDRETRY = 4, + IDIGNORE = 5, + IDYES = 6, + IDNO = 7, + IDTRYAGAIN = 10, + IDCONTINUE = 11 + } +}