克服操作系统强加的 Windows 窗体最小大小限制 [英] Overcome OS Imposed Windows Form Minimum Size Limit

查看:23
本文介绍了克服操作系统强加的 Windows 窗体最小大小限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在开发的应用程序中,我需要能够使窗体小于操作系统施加的最小高度限制(Vista 中为 36 像素).我曾尝试拦截 WM_GETMINMAXINFO 并提供我自己的信息来覆盖操作系统限制,但这仅适用于用户.从代码中,我可以将高度设置为小于限制的值,但我的更改仅在 WM_WINDOWPOSCHANGED 发布到消息队列之前有效(这发生在我更改高度之后).

In an application I am developing, I need to be able to make a windows form smaller than the minimum height limit imposed by the operating system (36 px in Vista). I have tried intercepting WM_GETMINMAXINFO and providing my own information to override the OS limits, but this only works for the user. From code I can set the height to a value smaller than the limit, but my change only works until WM_WINDOWPOSCHANGED is posted to the message queue (which happens just after I change the height).

推荐答案

经过多次试验和反复试验,我找到了解决方案.我覆盖了 OnResize 并使表单的大小与其中的 ListBox 相符(请参阅我对 John Saunders 回答的评论).

After much experimentation and trial-and-error, I have discovered a solution. I was overriding OnResize and conforming the size of the form to the ListBox in it (see my comment on John Saunders answer).

正如我在我的问题中提到的,我注意到在发送 WM_WINDOWPOSCHANGED 后表单的大小会下降.进一步的调查显示,当发送 WM_WINDOWPOSCHANGING 时,大小回归实际上开始了.

As I mentioned in my question, I noticed that the size of the form regresses after WM_WINDOWPOSCHANGED is sent. Further investigation revealed that the size regression actually begins when WM_WINDOWPOSCHANGING is sent.

WM_WINDOWPOSCHANGING 是 WM_WINDOWPOSCHANGED 的姊妹消息,它发生在窗口大小实际改变之前.我不知道为什么,但出于某种原因,WM_WINDOWPOSCHANGING 盲目地使表单的大小符合操作系统指定的限制(显然它不会使用 WM_GETMINMAXINFO 查询窗口).因此,我需要拦截 WM_WINDOWPOSCHANGING 并用我真正想要的大小覆盖它.

WM_WINDOWPOSCHANGING is the sister message of WM_WINDOWPOSCHANGED which occurs before the window size actually changes. I don't know why, but for some reason WM_WINDOWPOSCHANGING blindly conforms the size of the form to the OS specified limits (apparently it does not query the window with WM_GETMINMAXINFO). Thus, I needed to intercept WM_WINDOWPOSCHANGING and override it with the size I really wanted.

这意味着我不再使用 OnResize 来匹配表单的大小,而是在收到 WM_WINDOWPOSCHANGING 时匹配表单的大小.这甚至比 OnResize 更好,因为没有相关联的闪烁,即在大小更改时发生,然后在 OnResize 期间符合大小时再次更改.

This means that I am no longer conforming the size of the form using OnResize, but instead I am conforming the form size when I receive WM_WINDOWPOSCHANGING. This is even better than OnResize, because there is no associated flicker which occurs when the size is changed and then changed again when the size is conformed during OnResize.

另外,需要拦截并覆盖WM_GETMINMAXINFO,否则拦截WM_WINDOWPOSCHANGING也无济于事.

Also, it is necessary to intercept and override WM_GETMINMAXINFO, otherwise, even intercepting WM_WINDOWPOSCHANGING will do you no good.

using System.Runtime.InteropServices;

private const int WM_WINDOWPOSCHANGING = 0x0046;
private const int WM_GETMINMAXINFO = 0x0024;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_WINDOWPOSCHANGING)
    {
        WindowPos windowPos = (WindowPos)m.GetLParam(typeof(WindowPos));

        // Make changes to windowPos

        // Then marshal the changes back to the message
        Marshal.StructureToPtr(windowPos, m.LParam, true);
    }

    base.WndProc(ref m);

    // Make changes to WM_GETMINMAXINFO after it has been handled by the underlying
    // WndProc, so we only need to repopulate the minimum size constraints
    if (m.Msg == WM_GETMINMAXINFO)
    {
        MinMaxInfo minMaxInfo = (MinMaxInfo)m.GetLParam(typeof(MinMaxInfo));
        minMaxInfo.ptMinTrackSize.x = this.MinimumSize.Width;
        minMaxInfo.ptMinTrackSize.y = this.MinimumSize.Height;
        Marshal.StructureToPtr(minMaxInfo, m.LParam, true);
   }
}

struct WindowPos
{
     public IntPtr hwnd;
     public IntPtr hwndInsertAfter;
     public int x;
     public int y;
     public int width;
     public int height;
     public uint flags;
}

struct POINT
{
    public int x;
    public int y;
}

struct MinMaxInfo
{
    public POINT ptReserved;
    public POINT ptMaxSize;
    public POINT ptMaxPosition;
    public POINT ptMinTrackSize;
    public POINT ptMaxTrackSize;
}

这篇关于克服操作系统强加的 Windows 窗体最小大小限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆