Art*_*kyi 5 c# dwm winforms-interop
我正在尝试使用DWM为我的表单创建自定义窗口框架.该平台是C#WinForms,Pinvoking DWM.
在关于使用DWM制作自定义窗口框架的MSDN文章之后,主要步骤如下:
我以下一种方式处理WM_NCCALCSIZE消息:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
当wParam为TRUE时,只返回0而不处理NCCALCSIZE_PARAMS矩形将导致客户区调整大小到窗口大小,包括窗口框架.这将从窗口中删除窗口框架和标题项目,仅显示客户区域.
一切都很好,除了一个问题,对我有用.当我最大化/恢复窗口时,它在恢复时总是会增长一点.我想,问题是这样的:
所以,每当我最大化/恢复它时,这个窗口就会增长一点.我需要删除非客户区域以使用DWM绘制自定义表单框架.我不能简单地将窗口边框样式设置为无,因为DWM不会绘制窗口标题和边框.
请帮助解决问题,并愉快地拥有自定义窗口框架.
这实际上是 Windows 窗体中的一个错误,并且有一个解决方法。在函数中,Form.SizeFromClientSize(int, int)该AdjustWindowRectEx函数用于转换尺寸,它始终使用默认测量值并且不能被覆盖。这个函数从两个地方调用:
RestoreWindowBoundsIfNecessary 在 WM_WINDOWPOSCHANGED 窗口消息处理程序中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;
}
}
Run Code Online (Sandbox Code Playgroud)覆盖 WndProc 并插入以下代码来处理 WM_WINDOWPOSCHANGED:
if (m.Msg == WM_WINDOWPOSCHANGED)
{
createParamsHack = true;
base.WndProc(ref m);
createParamsHack = false;
}
Run Code Online (Sandbox Code Playgroud)覆盖 SetClientSizeCore:
protected override void SetClientSizeCore(int x, int y)
{
createParamsHack = true;
base.SetClientSizeCore(x, y);
createParamsHack = false;
}
Run Code Online (Sandbox Code Playgroud)重写SizeFromClientSize(Size)以返回正确的测量值也可能是个好主意,但这并不是绝对必要的。