将窗口大小捕捉到固定倍数
本文关键字:窗口大小 | 更新日期: 2023-09-27 18:21:33
Windows命令控制台只允许将窗口大小调整为字符大小的倍数。窗口大小的这种"捕捉"是即时的,不会闪烁。在本机代码中,这是通过处理WM_SIZING
消息并相应地修改RECT
结构来完成的。
在C#中,我尝试重写OnResize
方法,计算"快照"大小,并相应地设置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
消息?
EDIT:我也尝试手动拦截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
事件也不起作用。
问题在于语句if (cols != tgtCols || lines != tgtLines)
。这将导致只有当目标行/列发生更改时才进行大小捕捉,而当窗口宽度/高度发生更改时,不会。这是为了防止无限递归,但如果大小实际上没有改变,则不会触发Resize
事件,因此if
语句是不必要的。