Mouse click on the frame of a form (C#)

N

NeoAsimov

Hello,



There is what I want to do. I worked on the problem since 6 hours but
I had a problem (probably stupid) and I dont know how to resolve it.


I need to have an Mouse Event Click when I click on the frame of a
window form ( like the title bar of a window).


If I handle the mousee events with my window's forme instance, i only
can handle it on the ClientSize area.

After, I tryed to handle the messages with WndProc and DefWndProc. The
problem is that this is the same messages.


What I what, it's only be notified when I click on the title bar of my
my application's window. The problem is how to handle this with C#
becose in old Win32 this is not a problem.


Any hints?


Tahnk for you help!


Salutations,
 
N

Nicholas Paldino [.NET/C# MVP]

NeoAsimov,

Actually, the messages are not the same. For non-client areas, you have
to process the WM_NC* versions of the messages. So, for the left button
event in the title bar, you have to process the WM_NCLBUTTONUP message.
Handling this in your WndProc implementation is all you need. Of course,
rembmer to call the base class implementation of WndProc.

Hope this helps.
 
1

100

Hi NeoAsimov,
The problem is in windows, I believe. I'm using Win2k and it doesn't send
WM_NCLBUTTONUP message to the window. Instead windows sends WM_NCMOUSEMOVE.
I believe this is a *bug* in windows. I don't know if this problem exists in
WinXP, though.

B\rgds
100
 
1

100

Hi,
I just found that I made a mistake docs says that WM_NCLBUTTONUP won't be
send if the windows has set the mouse capture. releasing the capture makes
the messages come but mess up with dragging the window

B\rgds
100
 
N

NeoAsimov

Hello everybody,


Thank for your help, it's really appreciated. I'll check what can
I do with your informations :)



Thank alot,


Salutations,
 
1

100

Hi NeoAsimov,
I found probably one of the solutions of your problem.
This solution is not perfect and has flaws, but is good for a starter, I
believe.

private const int WM_NCMOUSEMOVE = 0xa0;
private const int WM_NCLBUTTONDOWN = 0xa1;
private const int WM_NCLBUTTONUP = 0xa2;
private const int HTCAPTION = 2;
private const int SC_MOVE = 0xF010;
private const int WM_SYSCOMMAND = 0x0112;

protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case WM_NCLBUTTONDOWN:
if((int)m.WParam == HTCAPTION)
{
this.Capture = false;
m.Result = new IntPtr(0);
return;
}
break;

case WM_NCMOUSEMOVE:
if(MouseButtons == MouseButtons.Left)
{
m.Msg = WM_SYSCOMMAND;
m.WParam = new IntPtr(SC_MOVE + 2);
}
break;
case WM_NCLBUTTONUP:
if((int)m.WParam == HTCAPTION)
{
this.OnClick(EventArgs.Empty);
}
break;
}

base.WndProc (ref m);
}

I release the mouse capture when the left button is down over the caption.
this will make the OS to send mouse up message. However, releasing the
capture has the efect that the form cannot be moved with the mouse.
That's why we have to start the dragging procedure if necessary by hand.
This is done in responce to WM_NCMOUSEMOVE when the left button is down.
To start moving(dragging) a window with the mouse WM_SYSCOMMAND with SC_MOVE
should be pass to the DefWindowProc. the same command is send if the windows
is moved from the system meny with the keyboard. To distinguish between the
two methods windows uses the low for bits of the wParam. if the low four
bits are 0 - the system menu, 2 - the mouse. These numbers are not
documented and can be changed. Anyway they stay the same for quite long and
I don't thing they will be changed. I thing the number 2 comes form the
value of HTCAPTION returned by WM_NCHITTEST message when the mouse is over
the caption (HTCAPTION) and I thing it won't be changed. Can't be sure,
though.

How I said the solution has flaws:
1. If the left mouse button is pressed outside the window, moved over the
caption and released then there are prolems with form activation (the
caption to become blue).
2. The applpication may miss WM_NCBUTTONDOWN message if the mouse is moved
quickly out of the caption bar. The form will remain on the same position
instead of moving along with the mouse cursor. That makes the form picky
when ot comes for moving it up or down.

You can try register the form for WM_NCMOUSE LEAVE (TrackMouseEvent API
function) and maintain internal flag for mouse down over the caption bar.
Then you can use that flag in WM_NCMOUSEMOVE instead of MouseButtons ==
MouseButtons.Left. I believe this is more correct and you want miss mouse
moves. I haven't tried and can't say if it's gonna help or not. Anyways good
luck ;)

HTH
B\rgds
100
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi NeoAsimov,
I'm just curious.
Did you find any solution?
 
N

NeoAsimov

Hello,
Hi NeoAsimov,
I'm just curious.
Did you find any solution?


No, it seem that the only way that windows xp (not sure for 2000) to
send the WM_NCLBUTTONDOWN message is when the focus of the mouse is
off(like when app's window if full sreen) but after you can't drag the
window.... not really usefull.



Salutations
 
N

NeoAsimov

Hello,


I'll try this out and give you feedbacks and improvements if I found somes ;)

thank!


Salutations,



100 said:
Hi NeoAsimov,
I found probably one of the solutions of your problem.
This solution is not perfect and has flaws, but is good for a starter, I
believe.

....
 

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