Zac*_*son 9 .net minimum-size winforms
在我正在开发的应用程序中,我需要能够使窗口形式小于操作系统施加的最小高度限制(在Vista中为36像素).我试图拦截WM_GETMINMAXINFO并提供我自己的信息来覆盖操作系统限制,但这仅适用于用户.从代码我可以将高度设置为小于限制的值,但我的更改只有在WM_WINDOWPOSCHANGED发布到消息队列(这是在我更改高度之后发生)之后才有效.
Zac*_*son 15
经过大量的实验和反复试验,我发现了一个解决方案.我重写了OnResize,并将表单的大小与其中的ListBox一致(请参阅我对John Saunders的评论).
正如我在我的问题中提到的,我注意到在发送WM_WINDOWPOSCHANGED之后表单的大小会消退.进一步的调查显示,当发送WM_WINDOWPOSCHANGING时,大小回归实际上开始了.
WM_WINDOWPOSCHANGING是WM_WINDOWPOSCHANGED的姐妹消息,它在窗口大小实际发生变化之前发生.我不知道为什么,但由于某种原因,WM_WINDOWPOSCHANGING盲目地将窗体的大小与OS指定的限制一致(显然它不会使用WM_GETMINMAXINFO查询窗口).因此,我需要拦截WM_WINDOWPOSCHANGING并用我真正想要的大小覆盖它.
这意味着我不再使用OnResize来符合表单的大小,而是在接收WM_WINDOWPOSCHANGING时符合表单大小.这甚至比OnResize更好,因为在更改大小时没有相关的闪烁,然后在OnResize期间符合大小时再次更改.
此外,有必要拦截和覆盖WM_GETMINMAXINFO,否则,即使拦截WM_WINDOWPOSCHANGING也没有用.
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3727 次 |
| 最近记录: |