You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PrintDialog is not compatible with multithreaded WPF apps that create windows on threads other than the one specified by Application.Current.Dispatcher.CurrentThread.
//// Get the process main window handle//IntPtrowner= IntPtr.Zero;if((System.Windows.Application.Current !=null)&&(System.Windows.Application.Current.MainWindow !=null)){
System.Windows.Interop.WindowInteropHelper helper=new System.Windows.Interop.WindowInteropHelper(System.Windows.Application.Current.MainWindow);owner= helper.CriticalHandle;}
publicWindowMainWindow{
get
{base.VerifyAccess();returnthis._mainWindow;}
set {}}
If the PrintDialog needs to force an owner window, it should use the active window for the thread not the global window saved in Application.MainWindow. Unfortunately WPF seems to offer no way to do this. Individual Dispatchers don't seem to keep track of windows. Win32PrintDialog could use Win32's GetActiveWindow() directly because it doesn't use the Window object only the HWND value.
To prevent PrintDialog from being unusable in the interim, the if-statement could at least be stripped out completely or patched to the following:
PrintDialog is not compatible with multithreaded WPF apps that create windows on threads other than the one specified by Application.Current.Dispatcher.CurrentThread.
PrintDialog.ShowDialog() copies the properties to an internal Win32PrintDialog class then calls Win32PrintDialog.ShowDialog():
https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/PrintDialog.cs
In the beginning of Win32PrintDialog.ShowDialog() you have this:
https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Printing/Win32PrintDialog.cs
The problem is that if you are not running on the same thread as Application.Current.Dispatcher.CurrentThread, then you are not allowed to even access the MainWindow property because it does a hard thread check with VerifyAccess() which throws an InvalidOperationException. Furthermore, there doesn't even seem to be clear guarantees that MainWindow itself was created on the thread.
https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs
If the PrintDialog needs to force an owner window, it should use the active window for the thread not the global window saved in Application.MainWindow. Unfortunately WPF seems to offer no way to do this. Individual Dispatchers don't seem to keep track of windows. Win32PrintDialog could use Win32's GetActiveWindow() directly because it doesn't use the Window object only the HWND value.
To prevent PrintDialog from being unusable in the interim, the if-statement could at least be stripped out completely or patched to the following:
or more cleanly:
The text was updated successfully, but these errors were encountered: