Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Win32 from drawing classic title bar

I wanted to add a nice shadow to my borderless form, and the best way I found to do it with minimal performance loss is to use DwmExtendFrameIntoClientArea. However, this seems to be causing Windows to draw a classic title bar over the window, but it is non-functional (ie. the glitch is merely graphical).

Windows Title Bar

This is the code I am using:

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);

I have tried setting ALLOW_NCPAINT to 1, and I even tried returning 0 when the window receives WM_NCPAINT without calling DefWndProc, but it made no difference.

Is there a way to resolve this weird issue while still using DwmExtendFrameIntoClientArea?

like image 345
MathuSum Mut Avatar asked Oct 16 '17 18:10

MathuSum Mut


1 Answers

Big thanks to @Erik Philips, I have finally resolved the issue by following this answer's advice. The issue was in 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;
    }
}

The | had to be removed from 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;
    }
}

This solved the issue, as apparently WinForms adds WS_BORDER by default to the class style, even if FormBorderStyle is later set to None.

like image 162
MathuSum Mut Avatar answered Nov 15 '22 04:11

MathuSum Mut