防止Win32绘制经典标题栏

Mat*_*Mut 6 c# windows aero dwm winforms

我想为我的无边框形式添加一个漂亮的阴影,而我发现以最小的性能损失实现它的最好方法是使用DwmExtendFrameIntoClientArea.然而,这似乎导致Windows在窗口上绘制经典标题栏,但它是无功能的(即,故障仅仅是图形化的).

Windows标题栏

这是我正在使用的代码:

int v = (int) DWMNCRENDERINGPOLICY.DWMNCRP_ENABLED;
NativeApi.DwmSetWindowAttribute(Handle, DwmWindowAttribute.NCRENDERING_POLICY, ref v, sizeof(int));
int enable = 0;
NativeApi.DwmSetWindowAttribute(Handle, DwmWindowAttribute.ALLOW_NCPAINT, ref enable, sizeof(int));
MARGINS margins = new MARGINS() {
    leftWidth = 0,
    topHeight = 0,
    rightWidth = 0,
    bottomHeight = 1
};
NativeApi.DwmExtendFrameIntoClientArea(Handle, ref margins);
Run Code Online (Sandbox Code Playgroud)

我已经尝试设置ALLOW_NCPAINT为1,我甚至尝试在WM_NCPAINT没有调用的情况下接收窗口时返回0 DefWndProc,但它没有任何区别.

有没有办法在使用时解决这个奇怪的问题DwmExtendFrameIntoClientArea

Mat*_*Mut 3

非常感谢@Erik Philips,我终于按照这个答案的建议解决了这个问题。问题在于CreateParams

/// <summary>
/// Gets the parameters that define the initial window style.
/// </summary>
protected override CreateParams CreateParams {
    get {
        CreateParams cp = base.CreateParams;
        if (!DesignMode) {
            cp.ClassStyle |= (int) ClassStyle.DoubleClicks;
            cp.Style |= unchecked((int) (WindowStyle.Popup | WindowStyle.SystemMenu | WindowStyle.ClipChildren | WindowStyle.ClipSiblings));
            cp.ExStyle |= (int) ExtendedWindowStyle.Layered;
        }
        return cp;
    }
}
Run Code Online (Sandbox Code Playgroud)

|必须从以下位置删除cp.Style

protected override CreateParams CreateParams {
    get {
        CreateParams cp = base.CreateParams;
        if (!DesignMode) {
            cp.ClassStyle |= (int) ClassStyle.DoubleClicks;
            cp.Style = unchecked((int) (WindowStyle.Popup | WindowStyle.SystemMenu | WindowStyle.ClipChildren | WindowStyle.ClipSiblings));
            cp.ExStyle |= (int) ExtendedWindowStyle.Layered;
        }
        return cp;
    }
}
Run Code Online (Sandbox Code Playgroud)

这解决了这个问题,因为显然 WinFormsWS_BORDER默认添加到类样式中,即使FormBorderStyle后来设置为None.