Borderless Form drag and drop.

D

David Gouge

Hi All,

I have a borderless form that i can drag around fine when dragging
anywhere on the form by using the following code:

protected override void WndProc(ref Message m)
{

const int WM_NCHITTEST = 0x84;
const int HTCLIENT = 0x01;
const int HTCAPTION = 0x02;

if (m.Msg == WM_NCHITTEST)
{
this.DefWndProc(ref m);
if (m.Result == new IntPtr(HTCLIENT))
{
m.Result = new IntPtr(HTCAPTION);
}
else
{
base.WndProc(ref m);
}
}
else
{
base.WndProc(ref m);
}
}

What i also need to be able to do is detect when the user stops the drag
and lets go of the mouse button. MouseUp does not seem to be firing
when using this code, is that because the code above is somehow 'heading
off' the message so the Up is not getting as far as MouseUp?

Anyway, if someone has any idea on how i could capture the mouseup when
using this drag code i would be most grateful.

Cheers,

Dave
 
G

Guest

I have a simple piece of code that doesn't involve overriding the WndProc
method.

private bool moving;
private Point loc;

private void Form1_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
moving = true;
loc = new Point(e.X, e.Y);
}
}

private void Form1_MouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (moving)
Location = new Point(Location.X + e.X - loc.X, Location.Y + e.Y - loc.Y);
}

private void Form1_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
moving = false;
}

You will have to just register these methods for their respective events.
I've used it and it works.
 
D

David Gouge

Thanks for the reply!

I have used this code (or similar) before to obtain the dragging
functionality, but in this particular instance there are problems
arising and i thought i would try the WndProc method instead.

So does anyone know how to capture the mouseUp when using the WndProc
method?

Thanks again. :D
 
M

Mick Doherty

I don't think you're going to get an actual MouseUp message, but a simple
workaround is to check for the first MouseMove message after the MouseDown
message. This message seems to be fired immediately after the mouse is
released whether there is an actual movement or not. A simple code example
follows:

private bool AwaitingRelease = false;

protected override void WndProc(ref Message m)
{
// Pre WndProc() checks.
// We just want to catch the message.
if (m.Msg == 0xa1) // WM_NCMOUSEDOWN
{
this.AwaitingRelease = true;
Point pt = PointToClient(new Point(m.LParam.ToInt32()));
MouseEventArgs ev = new MouseEventArgs(MouseButtons.Left, 0, pt.X,
pt.Y, 0);
base.OnMouseDown(ev);
}
else if (m.Msg == 0xa0) // WM_NCMOUSEMOVE
{
if (this.AwaitingRelease )
{
this.AwaitingRelease = false;
Point pt = PointToClient(new Point(m.LParam.ToInt32()));
MouseEventArgs ev = new MouseEventArgs(MouseButtons.Left, 0,
pt.X, pt.Y, 0);
base.OnMouseUp(ev);
}
}

base.WndProc(ref m);

// Post WndProc() checks.
// We want to modify the result.
if (m.Msg == 0x84) // WM_NCHITTEST
{
if (m.Result.ToInt32() == 0x1) // HTCLIENT
m.Result = (IntPtr)0x2; // HTCAPTION
}

}
 
D

David Gouge

Mick said:
I don't think you're going to get an actual MouseUp message, but a simple
workaround is to check for the first MouseMove message after the MouseDown
message. This message seems to be fired immediately after the mouse is
released whether there is an actual movement or not. A simple code example
follows:

private bool AwaitingRelease = false;

protected override void WndProc(ref Message m)
{
// Pre WndProc() checks.
// We just want to catch the message.
if (m.Msg == 0xa1) // WM_NCMOUSEDOWN
{
this.AwaitingRelease = true;
Point pt = PointToClient(new Point(m.LParam.ToInt32()));
MouseEventArgs ev = new MouseEventArgs(MouseButtons.Left, 0, pt.X,
pt.Y, 0);
base.OnMouseDown(ev);
}
else if (m.Msg == 0xa0) // WM_NCMOUSEMOVE
{
if (this.AwaitingRelease )
{
this.AwaitingRelease = false;
Point pt = PointToClient(new Point(m.LParam.ToInt32()));
MouseEventArgs ev = new MouseEventArgs(MouseButtons.Left, 0,
pt.X, pt.Y, 0);
base.OnMouseUp(ev);
}
}

base.WndProc(ref m);

// Post WndProc() checks.
// We want to modify the result.
if (m.Msg == 0x84) // WM_NCHITTEST
{
if (m.Result.ToInt32() == 0x1) // HTCLIENT
m.Result = (IntPtr)0x2; // HTCAPTION
}

}

That is just the job! Thanks very much. I wont pretend to completely
understand what's going on, but if it works its good enough for me. :D

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top