1
votes

I am fairly new to C#. In order to get a modern design application, I decided to make my form borderless. I then found a code snippet for making it possible to move my borderless form, which works perfectly fine.

private const int WM_NCHITTEST = 0x84;
private const int HT_CAPTION = 0x2;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg) {
        case WM_NCHITTEST:
            m.Result = (IntPtr)(HT_CAPTION);
            break;
    }
}

I also need to fetch the form maximize event, and found another code snippet, which again, works perfectly. At least if I use them independently.

                case WM_SYSCOMMAND:
                if (IsMaximized == false)
                {
                    IsMaximized = true;
                    Btn_Ribbon_MaximizeMinimize.Image = Properties.Resources.Img_MinimizeForm;
                    this.WindowState = FormWindowState.Maximized;
                }
                else if (IsMaximized == true)
                {
                    IsMaximized = false;
                    Btn_Ribbon_MaximizeMinimize.Image = Properties.Resources.Img_MaximizeForm;
                    this.WindowState = FormWindowState.Normal;
                }
                break;

Now here comes the weird part. If I use them both together...

        #region Move borderless Form
    private const int WM_NCHITTEST = 0x84;
    private const int HT_CLIENT = 0x1;
    private const int HT_CAPTION = 0x2;
    private const int WM_SYSCOMMAND = 0x0112;

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg) {
            case WM_NCHITTEST:
                m.Result = (IntPtr)(HT_CAPTION);
                break;
            case WM_SYSCOMMAND:
                if (IsMaximized == false)
                {
                    IsMaximized = true;
                    Btn_Ribbon_MaximizeMinimize.Image = Properties.Resources.Img_MinimizeForm;
                    this.WindowState = FormWindowState.Maximized;
                }
                else if (IsMaximized == true)
                {
                    IsMaximized = false;
                    Btn_Ribbon_MaximizeMinimize.Image = Properties.Resources.Img_MaximizeForm;
                    this.WindowState = FormWindowState.Normal;
                }
                break;
        }
    }
    #endregion

...I get all kind of weird side effects:

  • A single click on my form is enought for it to maximize itself
  • After minimizing my application, clicking its icon in the windows taskbar again, does not result in it normalizing, but maximizing

How can I get rid of those side effects, or even better than a workaround, is there a better way to make this work?

1
@duDE no, it certainly isn't. I don't want to make my borderless form movable, since it is already working as intended. I wanna get rid of the bugs, caused by it.arvenyon

1 Answers

0
votes

The WM_SYSCOMMAND message can contain information about more than just the maximize event. When you handle the WM_NCHITTEST and tell the OS that the caption bar was clicked, it also causes a WM_SYSCOMMAND when you release the mouse button.

You should inspect the m.WParam value to determine what action was performed.

The documentation mentions SC_MAXIMIZE (0xF030) but on my machine the value is actually SC_MAXIMIZE2 (0xF032). I can't find any documentation about that value, but this answer also mentions it.