将窗口大小固定为固定倍数

时间:2014-09-10 15:05:40

标签: c# forms resize

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);
}

正如您所看到的,我已尝试同时使用SizeClientSize属性,但两者都会产生相同的效果。是否有更好的方法来限制大小?或者我是否需要手动拦截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事件也不起作用。

1 个答案:

答案 0 :(得分:0)

问题是声明if (cols != tgtCols || lines != tgtLines)。这会导致尺寸捕捉仅在目标线/列发生变化时发生,当窗口宽度/高度发生变化时。这是为了防止无限递归,但如果大小实际上没有改变,则不会触发Resize事件,因此if语句是不必要的。