Is there an event or something i can use when a showdialogwindow is blocking the window i try to access

六月ゝ 毕业季﹏ 提交于 2019-12-10 15:57:12

问题


I have 2 windows. Lets call them A and B. A is opening B with a ShowDialog(). So I am opening B - When the user minimizes B or gets it into the back somehow and he tries clicking window A again its blocked (as it should be), but is there an Event that I can catch up onto when this happens ?

I am trying to achieve bringing the blocking window B into the front when hes trying to access window A with window B opened.

Codeexample:

Thats how Window A is opened from the Mainwindow

            WindowA windowA = new WindowA();

            windowA.Owner = Application.Current.MainWindow;

            windowA.Show();
            windowA.Activate();

And thats how Window B is opened

            WindowB windowB = new WindowB();
            windowB.Owner = this; //(this = windowA)
            windowB.ShowDialog();

Both windows have no special properties set except

WindowStartupLocation="CenterScreen"

回答1:


If you want to restore second window when it is minimized and user does click on first(blocked) window, then you can go this way(add this code to the WindowB):

public WindowB()
{
    PreviewMouseDown += WindowB_PreviewMouseDown;
    StateChanged += WindowB_StateChanged;
    InitializeComponent();
    LostMouseCapture += WindowB_LostMouseCapture;

}

private void WindowB_LostMouseCapture(object sender, MouseEventArgs e)
{
    //You can also evaluate here a mouse coordinates.
    if (WindowState == WindowState.Minimized)
    {
        e.Handled = true;
        CaptureMouse();
    }
}

private void WindowB_StateChanged(object sender, EventArgs e)
{
    if (WindowState== WindowState.Minimized)
    {
        CaptureMouse();
    }
    else
    {
        ReleaseMouseCapture();
    }
}

private void WindowB_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    WindowState = WindowState.Normal;
    Debug.WriteLine("WindowB PreviewMouseDown");
}

So you have to start mouse capturing on second window on it being minimized, for if user does click on WindowA this can be handled on WindowB.
As window being minimized it going to lost a mouse capture(therefore you have to listen on LostMouseCapture), that you have to prevent.

Left mouse button down on WindowA does restore thenWindowB.




回答2:


There is no managed event being raised when you click outside of a modal window but you should be able to handle this in the modal window using some p/invoke. Here is an example for you:

public sealed partial class ModalWindow : Window, IDisposable
{
    [DllImport("User32.dll")]
    public static extern IntPtr SetWindowsHookEx(int idHook, HookDelegate lpfn, IntPtr hmod, int dwThreadId);

    [DllImport("User32.dll")]
    public static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("User32.dll")]
    public static extern IntPtr UnhookWindowsHookEx(IntPtr hHook);

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out POINT lpPoint);

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;

        public static implicit operator Point(POINT point)
        {
            return new Point(point.X, point.Y);
        }
    }

    public delegate IntPtr HookDelegate(int code, IntPtr wParam, IntPtr lParam);

    private const int WH_MOUSE_LL = 14;
    private const int WM_LBUTTONDOWN = 0x0201;
    private HookDelegate mouseDelegate;
    private IntPtr mouseHandle;

    public ModalWindow()
    {
        InitializeComponent();
        mouseDelegate = MouseHookDelegate;
        mouseHandle = SetWindowsHookEx(WH_MOUSE_LL, mouseDelegate, IntPtr.Zero, 0);
    }

    private IntPtr MouseHookDelegate(int code, IntPtr wParam, IntPtr lParam)
    {
        if (code < 0)
            return CallNextHookEx(mouseHandle, code, wParam, lParam);

        switch ((int)wParam)
        {
            case WM_LBUTTONDOWN:
                POINT lpPoint;
                GetCursorPos(out lpPoint);
                if (lpPoint.X < Left || lpPoint.X > (Left + Width) || lpPoint.Y < Top || lpPoint.Y > (Top + Height))
                {
                    //Outside click detected...
                }
                break;
        }

        return CallNextHookEx(mouseHandle, code, wParam, lParam);
    }

    protected override void OnClosed(EventArgs e)
    {
        Dispose();
        base.OnClosed(e);
    }

    public void Dispose()
    {
        if (mouseHandle != IntPtr.Zero)
            UnhookWindowsHookEx(mouseHandle);
    }
}


来源:https://stackoverflow.com/questions/55948944/is-there-an-event-or-something-i-can-use-when-a-showdialogwindow-is-blocking-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!