4

I have a form created in Windows Forms which is draggable wherever I click. I made it by overriding WndProc function which in turn modifies each click as it was a title bar click:

    //found at: http://stackoverflow.com/questions/3995009/how-to-make-a-window-draggablec-winforms
    private const int WM_NCHITTEST = 0x84;
    private const int HTCLIENT = 0x1;
    private const int HTCAPTION = 0x2;

    ///
    /// Handling the window messages 
    ///
    protected override void WndProc(ref Message message)
    {
        base.WndProc(ref message);

        if (message.Msg == WM_NCHITTEST && (int)message.Result == HTCLIENT)
            message.Result = (IntPtr)HTCAPTION;
    }

The problem is that now when I double click, the window becomes fullscreen, which is unwanted. How can I block this behavior?

pmichna
  • 4,800
  • 13
  • 53
  • 90

5 Answers5

2

In addition to JaredPar I would suggest don not create draggable form in that way, but handle it in 3 steps

  • identify mouse down on the form
  • capture mouse
  • identify mouse up event

It is not a complicated to handle, and it's better, imo, then disabling a double click on the form.

For complete example of how you can do that can have a look on

Creating a Draggable Borderless Form

Tigran
  • 61,654
  • 8
  • 86
  • 123
2

I was having the same problem today in C++. I used JaredPar's solution but with WM_NCLBUTTONDBLCLK (0x00A3) instead of WM_LBUTTONDBLCLK, that did the trick for me! It's working because the double click message is being sent from a non-client (NC) area, which is the "virtual" title bar (HTCAPTION) in this case.

Jex
  • 131
  • 1
  • 10
2

I've done the same as Jex which is working great.

private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;
private const int WM_LBUTTONDBLCLK = 0x00A3;

protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_LBUTTONDBLCLK)
        {
            return;
        }
        switch (m.Msg)
        {

            case WM_NCHITTEST:      
                base.WndProc(ref m);
                if ((int)m.Result == HTCLIENT)
                    m.Result = (IntPtr)HTCAPTION;
                return;
        }
        base.WndProc(ref m);
    }
KPRDave
  • 21
  • 1
1

It seems you found a solution to a problem with caused another problem that you're trying to solve. If I could suggest something simple, just a better solution to make a window drag-able:

Add InteropServices to the using declarations:

using System.Runtime.InteropServices;

And for the code:

    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;

    [DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd,
                     int Msg, int wParam, int lParam);
    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

Then go to the form's MouseDown event and paste this:

        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }

Done.

MasterMastic
  • 20,711
  • 12
  • 68
  • 90
-1

If you just want to stop the double click from having it's default behavior in the window for which you've overridden the WndProc then intercept the WM_LBUTTONDBLCLK message

private const int WM_LBUTTONDBLCLK = 0x0203;

...

protected override void WndProc(ref Message message) {
  if (message.Msg == WM_LBUTTONDBLCLK) {
    return;
  }

  base.WndProc(ref message);

  if (message.Msg == WM_NCHITTEST && (int)message.Result == HTCLIENT)
    message.Result = (IntPtr)HTCAPTION;
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • That's one of the first things I tried. Unfortunately, it doesn't work work and I can't figure out why. – pmichna Apr 07 '12 at 14:26
  • After double clicking the form becomes full screen just as before. However, Tigran's tips helped. – pmichna Apr 07 '12 at 14:41
  • So, the issue here is if the user double-clicks where the title bar normally will be, the message is WM_NCLBUTTONDBLCLK instead. So you need to test for both. – EricLaw Aug 12 '15 at 17:01