如何防止对话框离开父边界
本文关键字:边界 离开 对话框 何防止 | 更新日期: 2023-09-27 18:18:55
我有一个显示可拖动对话框的窗口,但是我不希望对话框离开父窗口的边界。
using (var dialog = new MyDialog())
{
if (dialog.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{
// do something
}
}
我怎样才能做到这一点?
您可以尝试覆盖对话框表单的WndProc
方法,并监视WM_WINDOWPOSCHANGING
系统消息的新位置和大小:
public class DialogForm : Form
{
private struct WindowPos
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public uint flags;
}
public DialogForm()
{
}
protected override void WndProc(ref Message m)
{
const int WM_WINDOWPOSCHANGING = 0x0046;
if (m.Msg == WM_WINDOWPOSCHANGING)
{
WindowPos mwp = (WindowPos)Marshal.PtrToStructure(m.LParam, typeof(WindowPos));
if (mwp.hwnd == Handle)
{
const int SWP_NOMOVE = 0x0002;
const int SWP_NOSIZE = 0x0001;
int x = mwp.x;
int y = mwp.y;
if (x < Owner.Left || y < Owner.Top || x + mwp.cx > Owner.Right || y + mwp.cy > Owner.Bottom)
{
m.Result = IntPtr.Zero;
mwp.flags |= SWP_NOMOVE | SWP_NOSIZE;
Marshal.StructureToPtr(mwp, m.LParam, true);
}
}
}
base.WndProc(ref m);
}
}
编辑。为了更平滑,使用这个方法:
protected override void WndProc(ref Message m)
{
const int WM_WINDOWPOSCHANGING = 0x0046;
if (m.Msg == WM_WINDOWPOSCHANGING)
{
WindowPos mwp = (WindowPos)Marshal.PtrToStructure(m.LParam, typeof (WindowPos));
if (mwp.hwnd == Handle)
{
int x = mwp.x;
int y = mwp.y;
if (x < Owner.Left || y < Owner.Top || x + mwp.cx > Owner.Right || y + mwp.cy > Owner.Bottom)
{
bool resizing = mwp.cx != Width || mwp.cy != Height;
if (resizing)
{
if (x < Owner.Left)
{
mwp.x = x = Owner.Left;
mwp.cx = Width;
}
if (y < Owner.Top)
{
mwp.y = y = Owner.Top;
mwp.cy = Height;
}
if (mwp.cx > Owner.Right - x)
mwp.cx = Owner.Right - x;
if (mwp.cy > Owner.Bottom - y)
mwp.cy = Owner.Bottom - y;
}
else
{
if (x < Owner.Left)
mwp.x = Owner.Left;
else if (x > Owner.Right - mwp.cx)
mwp.x = Owner.Right - mwp.cx;
if (y < Owner.Top)
mwp.y = Owner.Top;
else if (y > Owner.Bottom - mwp.cy)
mwp.y = Owner.Bottom - mwp.cy;
}
m.Result = IntPtr.Zero;
Marshal.StructureToPtr(mwp, m.LParam, true);
}
}
}
base.WndProc(ref m);
}