Windows命令控制台仅允许您将窗口大小调整为字符大小的倍数。窗口大小的这种“捕捉”是瞬时的并且不会闪烁。在本机代码中,这是通过处理WM_SIZING
消息并相应地修改RECT
结构来完成的。
在C#中,我尝试重写OnResize
方法,计算“snapped”大小,并相应地设置Form的ClientSize
属性。不幸的是,大小不断在捕捉的大小和光标当前所规定的大小之间跳跃。
protected override void OnResize(EventArgs e)
{
int tgtCols = (ClientSize.Width + 4) / 8;
int tgtLines = (ClientSize.Height + 8) / 15;
if (cols != tgtCols || lines != tgtLines)
{
cols = tgtCols;
lines = tgtLines;
int tgtWidth = cols * 8;
int tgtHeight = lines * 15;
//ClientSize = new Size(tgtWidth, tgtHeight);
Size = new Size(tgtWidth + exWidth, tgtHeight + exHeight);
}
base.OnResize(e);
}
正如您所看到的,我已尝试同时使用Size
和ClientSize
属性,但两者都会产生相同的效果。是否有更好的方法来限制大小?或者我是否需要手动拦截WM_SIZING
消息?
编辑:我也尝试手动拦截WM_SIZING
,但我得到的结果相同:
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_SIZING:
DoSizeSnap(ref m);
m.Result = new IntPtr(1);
break;
default:
base.WndProc(ref m);
break;
}
}
private unsafe void DoSizeSnap(ref Message m)
{
int edge = m.WParam.ToInt32();
RECT *pRect = (RECT *)m.LParam.ToPointer();
int tgtCols = (pRect->right - pRect->left - exWidth + 4) / 8;
int tgtLines = (pRect->bottom - pRect->top - exHeight + 8) / 15;
if (cols != tgtCols || lines != tgtLines)
{
cols = tgtCols;
lines = tgtLines;
int tgtWidth = cols * 8;
int tgtHeight = lines * 15;
// TODO: handle edge
pRect->right = pRect->left + tgtWidth + exWidth;
pRect->bottom = pRect->top + tgtHeight + exHeight;
}
}
订阅Resize
事件也不起作用。
答案 0 :(得分:0)
问题是声明if (cols != tgtCols || lines != tgtLines)
。这会导致尺寸捕捉仅在目标线/列发生变化时发生,当窗口宽度/高度发生变化时不。这是为了防止无限递归,但如果大小实际上没有改变,则不会触发Resize
事件,因此if
语句是不必要的。