当 showdialogwindow 阻止我尝试访问的 window 时,是否有事件或我可以使用的东西
Is there an event or something i can use when a showdialogwindow is blocking the window i try to access
我有 2 个windows。让我们称它们为 A 和 B。
A 正在使用 ShowDialog() 打开 B。
所以我打开 B - 当用户最小化 B 或以某种方式将它放到后面并且他尝试再次单击 window A 时它被阻止了(应该如此),但是是否有一个事件我可以在什么时候赶上发生这种情况?
当他试图访问 window A 并打开 window B 时,我正在努力实现将阻塞 window B 置于前面。
代码示例:
这就是 Window A 从 Main 打开的方式window
WindowA windowA = new WindowA();
windowA.Owner = Application.Current.MainWindow;
windowA.Show();
windowA.Activate();
这就是 Window B 的打开方式
WindowB windowB = new WindowB();
windowB.Owner = this; //(this = windowA)
windowB.ShowDialog();
除了
,windows都没有设置特殊属性
WindowStartupLocation="CenterScreen"
当您在模态 window 外部单击时,不会引发任何托管事件,但您应该能够使用某些 p/invoke 在模态 window 中处理此事件。这是一个例子:
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);
}
}
如果你想在第二个 window 最小化并且用户点击第一个(阻塞)window 时恢复它,那么你可以这样做(将此代码添加到 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");
}
所以你必须在第二个 window 开始鼠标捕获,因为如果用户点击 WindowA
这可以在 WindowB
.[=23= 上处理]
由于 window 被最小化,它会丢失鼠标捕获(因此你必须在 LostMouseCapture
上监听),你必须防止。
在 WindowA
上按下鼠标左键会恢复 WindowB
。
我有 2 个windows。让我们称它们为 A 和 B。 A 正在使用 ShowDialog() 打开 B。 所以我打开 B - 当用户最小化 B 或以某种方式将它放到后面并且他尝试再次单击 window A 时它被阻止了(应该如此),但是是否有一个事件我可以在什么时候赶上发生这种情况?
当他试图访问 window A 并打开 window B 时,我正在努力实现将阻塞 window B 置于前面。
代码示例:
这就是 Window A 从 Main 打开的方式window
WindowA windowA = new WindowA();
windowA.Owner = Application.Current.MainWindow;
windowA.Show();
windowA.Activate();
这就是 Window B 的打开方式
WindowB windowB = new WindowB();
windowB.Owner = this; //(this = windowA)
windowB.ShowDialog();
除了
,windows都没有设置特殊属性WindowStartupLocation="CenterScreen"
当您在模态 window 外部单击时,不会引发任何托管事件,但您应该能够使用某些 p/invoke 在模态 window 中处理此事件。这是一个例子:
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);
}
}
如果你想在第二个 window 最小化并且用户点击第一个(阻塞)window 时恢复它,那么你可以这样做(将此代码添加到 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");
}
所以你必须在第二个 window 开始鼠标捕获,因为如果用户点击 WindowA
这可以在 WindowB
.[=23= 上处理]
由于 window 被最小化,它会丢失鼠标捕获(因此你必须在 LostMouseCapture
上监听),你必须防止。
在 WindowA
上按下鼠标左键会恢复 WindowB
。