Это довольно сложно объяснить в заголовке, если кто-то захочет изменить это, то все в порядке.
У меня есть ситуация, когда в WPF я создаю "скрытое" окно, которое прозрачно для программиста.
Я имею в виду, что это окно создано в статическом конструкторе, скрыто и перемещено за пределы экрана, а его ширина и высота равны 0. Это потому, что я использую это окно, чтобы выполнить некоторые операции взаимодействия и разрешить своего рода обработчики для всех WndProcs переопределить, что кто-то может потребовать (есть список делегатов, который обрабатывает методы, которые должны переопределить WndProc).
В надежде, что вы понимаете, что я сказал (это нелегко), моя проблема в том, что когда я создаю проект WPF и запускаю его, если я закрываю главное окно (которое не прозрачно создано ) программисту), я хочу, чтобы мое приложение закрылось. Однако с кодом, который я создал, этого не произойдет, если я не использую Application.Current.Shutdown ();
Есть ли способ исправить это, не вызывая этот метод? Я хочу прозрачный способ, который другие программисты не должны даже замечать (это библиотека, она не должна изменять поведение работающих программ таким образом).
Спасибо за любые предложения, здесь вы можете увидеть некоторые фрагменты кода:
Окно, созданное lib
public class InteropWindow : Window
{
public HwndSource Source { get; protected set; }
private static InteropWindow _Instance;
static InteropWindow()
{
_WndProcs = new LinkedList<WndProcHandler>();
_Instance = new InteropWindow();
}
private static WindowInteropHelper _InteropHelper;
public static WindowInteropHelper InteropHelper
{
get
{
if (_InteropHelper == null)
{
_InteropHelper = new WindowInteropHelper(_Instance);
_InteropHelper.EnsureHandle();
}
return _InteropHelper;
}
}
public static IntPtr Handle { get { return InteropHelper.Handle; } }
private InteropWindow()
{
Opacity = 0.0;
//We have to "show" the window in order to obtain hwnd to process WndProc messages in WPF
Top = -10;
Left = -10;
Width = 0;
Height = 0;
WindowStyle = WindowStyle.None;
ShowInTaskbar = false;
ShowActivated = false;
Show();
Hide();
}
private static LinkedList<WndProcHandler> _WndProcs;
public static void AddWndProcHandler(WndProcHandler handler)
{
_WndProcs.AddLast(handler);
}
public static void RemoveWndProcHandler(WndProcHandler handler)
{
_WndProcs.Remove(handler);
}
private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
IntPtr result = IntPtr.Zero;
foreach (WndProcHandler handler in _WndProcs)
{
IntPtr tmp = handler(hwnd, msg, wParam, lParam, ref handled);
if (tmp != IntPtr.Zero)
{
if (result != IntPtr.Zero)
throw new InvalidOperationException(string.Format("result should be zero if tmp is non-zero:\nresult: {0}\ntmp: {1}", result.ToInt64().ToString(), tmp.ToInt64().ToString()));
result = tmp;
}
}
return result;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
Source = PresentationSource.FromVisual(this) as HwndSource;
Source.AddHook(WndProc);
OnWindowInitialized(null, e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (Source != null)
Source.RemoveHook(WndProc);
OnWindowClosed(null, e);
}
private static void OnWindowInitialized(object sender, EventArgs e)
{
if (WindowInitialized != null) WindowInitialized(sender, e);
}
private static void OnWindowClosed(object sender, EventArgs e)
{
if (WindowClosed != null) WindowClosed(sender, e);
}
public static event EventHandler WindowInitialized;
public static event EventHandler WindowClosed;
}
Обычное окно, созданное с помощью wpf (базовое окно, созданное из проекта)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ExClipboard.ClipboardUpdate += new RoutedEventHandler(ExClipboard_ClipboardUpdate);
Closed += new EventHandler(MainWindow_Closed);
}
private void MainWindow_Closed(object sender, EventArgs e)
{
//InteropWindow.Dispose();
App.Current.Shutdown(0);
}
}
Обновление 1:
Чтобы ответить на ваши ответы, Нет, я бы хотел избежать вмешательства программиста, использующего мою библиотеку, поэтому идеальным решением является то, что в моей библиотеке я подписываюсь на какое-то событие Application.Exit и закрываю свое окно, очевидно, я не могу используйте Application.Exit, потому что приложение не закрывается из-за того, что мое окно не закрывается
Может быть, есть способ рассчитать все окна, которые принадлежат приложению? Я тоже могу что-то сделать с этим