C# 使用DWM自定义窗口框架:如何正确处理WM\u NCCALCSIZE
我正在尝试使用DWM为我的表单创建自定义窗口框架。 平台是C#WinForms,Pinvoking DWM 以下是主要步骤:C# 使用DWM自定义窗口框架:如何正确处理WM\u NCCALCSIZE,c#,winforms-interop,dwm,C#,Winforms Interop,Dwm,我正在尝试使用DWM为我的表单创建自定义窗口框架。 平台是C#WinForms,Pinvoking DWM 以下是主要步骤: 删除标准帧(非客户端区域),在回答WM_NCCALCSIZE消息时返回0 使用DwmExtendFrameIntoClientArea函数将框架扩展到客户端区域 我用下一种方式处理WM_NCCALCSIZE消息: protected override void WndProc(ref Message m) { switch (m.Msg) { c
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_NCCALCSIZE:
if (isDwmWindowFramePaintEnabled() && m.WParam != IntPtr.Zero)
{
m.Result = IntPtr.Zero;
}
else
{
base.WndProc(ref m);
}
return;
}
}
根据,
当wParam为TRUE时,只返回0而不处理
NCCALCSIZE_参数矩形将导致客户端区域调整为
窗口的大小,包括窗框。这将删除
从窗口中删除窗口框架和标题项,只保留
显示客户端区域
除了一个问题,一切都很好,对我来说都很好。
当我最大化/还原窗口时,当它被还原时,它总是增长一点。
我认为,问题是这样的:
请帮助解决此问题,并愉快地拥有一个自定义窗口框架。这实际上是Windows窗体中的一个错误,有一个解决方法。在函数
Form.SizeFromClientSize(int,int)
中,AdjustWindowRectEx
函数用于转换大小,它始终使用默认测量值,不能被覆盖。此函数从两个位置调用:
在WM_WINDOWPOSCHANGED窗口消息处理程序中必要时恢复Windows边界
SetClientSizeCore
- 重写形式中的CreateParams:
private bool createParamsHack; protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; // Remove styles that affect the border size if (createParamsHack) cp.Style &= ~(int)(WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_THICKFRAME); return cp; } }
- 重写WndProc并插入以下代码以处理WM_WINDOWPOSCHANGED:
if (m.Msg == WM_WINDOWPOSCHANGED) { createParamsHack = true; base.WndProc(ref m); createParamsHack = false; }
- 覆盖SetClientSizeCore:
protected override void SetClientSizeCore(int x, int y) { createParamsHack = true; base.SetClientSizeCore(x, y); createParamsHack = false; }
覆盖
SizeFromClientSize(Size)
以返回正确的测量值也可能是个好主意,但这并不是绝对必要的。谢谢!我很快就会试试看,看有没有用!很抱歉,这个答复耽搁了。我尝试了你的建议,覆盖了CreateParams
,效果很好!另外,我尝试重写方法“Form.SizeFromClientSize(Size)”,只返回客户端大小,该大小作为参数传递给该方法。但那没用。