WPF:在没有“程序员”的情况下关闭应用程序时关闭辅助窗口;干预

本文关键字:程序员 应用程序 干预 窗口 情况下 WPF | 更新日期: 2023-09-27 18:02:23

很难在标题中解释这一点,如果有人想改变它,那是可以的。

我有一个情况,在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:

回答你的答案,不,我想避免程序员使用我的库进行任何干预,所以理想的解决方案是在我的库中订阅一些应用程序。退出事件并关闭我的窗口,显然我不能使用应用程序。退出,因为我的窗口没有关闭,应用程序没有关闭

也许有一种方法来计算属于一个应用程序的所有窗口?我也可以做点什么

WPF:在没有“程序员”的情况下关闭应用程序时关闭辅助窗口;干预

如果你有一个主窗口,你不能设置应用程序。关闭模式到OnMainWindowClose ?

默认值是OnLastWindowClose,这很可能是您看到此行为的原因。

这是一个便宜的hack,但我认为这可能达到你所追求的…

在你的库中,你需要引用xaml的依赖关系(PresentationCore, PresentationFramework, System. net)。Xaml和WindowsBase)

在库的静态构造函数中,您可以添加类似

的内容
Application.Current.MainWindow.Closed += new EventHandler(MainWindow_Closed);
static void MainWindow_Closed(object sender, EventArgs e)
{
    Dispose();
}

Where dispose关闭你的窗口(_Instance.Close())并处理任何其他清理调用

从概念上讲,唯一想到的是事件消息通知服务,其中第二个窗口正在侦听或等待要关闭的消息,而第一个窗口发送消息以关闭它。这还需要使用MVVM模式。我不能完全确定这一点,我也不确定这是否符合您不让其他程序员知道的想法。

这里有一篇关于它的博客文章:WPF MVVM应用程序中发送通知

相关文章: