Archived

This topic is now archived and is closed to further replies.

Zeke

WM_NcLButtonDown problem

Recommended Posts

Ive skinned a dialog window with a bitmap fine and dandy, and i do the trick of using SendMessage(WM_NCLBUTTONDOWN,HTCAPTION,0) in my WM_LBUTTONDOWN message handler to make the window draggable (from anywhere in its window area not just the caption bar- it doesnt have a caption bar its skinned ). Anyway it is working just fine except I know need to do something when the left button is released only i no longer recieve the WM_LButtonDown when the left mouse button is released, I also tried putting into my WM_MouseMove handler: if (lParam&MK_LBUTTONDOWN) //still dragging else //no longer dragging except it doesnt recognise that i have the left button down because of the WM_NcLButtonDown either. Ive also tried catching the WM_NcLButtonUp message but again I dont recieve this message. Does anyone know why if i send this message it stops me recieving the notification of the mouse left button being released? or how to stop it or can anyone tell me how i can drag my window (with no caption bar) without using WM_NCLBUTTONDOWN? Thanks for any help you can offer

Share this post


Link to post
Share on other sites
You need to check for the WM_LBUTTONUP message to find out when the user releases the button. In this case you have to assume that the mouse button is still being held down from the time you get the WM_LBUTTONDOWN message until you receive it.

HTH

[edited by - SysOp_1101 on August 16, 2002 7:41:40 AM]

Share this post


Link to post
Share on other sites
Oops thats what i meant hehe ill go back and edit my post. Thanks for catching that. Yeah when i send the wm_nclbuttondown message i no longer recieve the wm_lbuttonUP message unless i double click the mouse (where upon the last release of the mouse is caught.

Share this post


Link to post
Share on other sites
Well according to the Win32 API:

quote:

The WM_NCLBUTTONUP message is posted when the user releases the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted.



I would take this to mean that if your processing the mouse events in your WndProc (ie the WM_LBUTTONUP message), then it will avoid sending this message altogether. I'm kind of fuzzy on what that last sentence means for sure though. :S

HTH

[edited by - SysOp_1101 on August 16, 2002 7:51:53 AM]

Share this post


Link to post
Share on other sites
Yeah i read that and couldnt quite understand what it meant either but i tried it out with SetCapture and my window doesnt move (so i guess if you set capture it doesnt actually send the message?). But have you got any idea how to get round it or move my window around without using that message?

Share this post


Link to post
Share on other sites
is it correct that you need an event that occurs when you realease the left mouse button after you moved your window? if, yes the following should work (i hope).

Try the following:

somewhere in MainFrm.h

//Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)

...

//add this two lines
afx_msg LRESULT OnEnterSizeMove(WPARAM, LPARAM);
afx_msg LRESULT OnExitSizeMove(WPARAM, LPARAM);

...

//}}AFX_MSG
DECLARE_MESSAGE_MAP()


then in the .cpp

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

...

//add this two lines
ON_MESSAGE(WM_ENTERSIZEMOVE, OnEnterSizeMove)
ON_MESSAGE(WM_EXITSIZEMOVE, OnExitSizeMove)

...

END_MESSAGE_MAP()

after that somewhere in the .cpp

LRESULT CMainFrame::OnEnterSizeMove(WPARAM wParam, LPARAM lParam)
{
return 0;
}

LRESULT CMainFrame::OnExitSizeMove(WPARAM wParam, LPARAM lParam)
{
return 0;
}

Share this post


Link to post
Share on other sites
I think you have your messages confused.
WM_NC[LR]BUTTON[UPDOWN] is sent when actions with the mouse occur in the Non Client [NC] area of the window (which is basically the edges and the titlebar only). If you have a dialog with no titlebar, the whole area is client area so you shouldn't ever receive an NC message. You will recieve WM_LBUTTONDOWN messages and UP messages however.

To make a window move by dragging on it, I capture the mouse on the buttondown, move it accordingly on mousemove and then let it go on the buttonup.


    
switch(uMsg){
case WM_RBUTTONDOWN: {
POINT p;
RECT r;
RECT client;

SetCapture(hwnd);
GetCursorPos(&p);
GetWindowRect(GetParent(hwnd), &r);
g_iMovedX = p.x - r.left;
g_iMovedY = p.y - r.top;
g_fMoving = true;
GetWindowRect(hwnd, &client);
ClipCursor(&client);
IDC_SIZEALL));
} break;
case WM_RBUTTONUP: {
POINT p;
g_fMoving = false;
ClipCursor(NULL);
ReleaseCapture();
} break;
case WM_MOUSEMOVE:
if(g_fMoving && (wparam & MK_RBUTTON)){
POINT p;
RECT client;
GetCursorPos(&p);
SetWindowPos(GetParent(hwnd), NULL, p.x -g_iMovedX, p.y - g_iMovedY, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
GetWindowRect(hwnd, &client);
ClipCursor(&client);
return 0;
} else
g_fMoving = false;
break;
}


This should be all you need once you add some global or member variables for g_iMovedX/Y and g_fMoving.

Since this is for right click, you might want to make it L instead of R in all the RBUTTONs.

The clip cursor is to make sure the mouse doesn't leave the client area while dragging- if it did, the button up message may not be processed if the user was to release the button outside of the client area.

Edit: about the docs, once you capture a cursor using SetCapture() [as in my example] different messages are sent to the window that holds the capture. For this part of the code, capturing the cursor may not be necessary, but I did anyway.

___________________________
Freeware development:
ruinedsoft.com

[edited by - iwasbiggs on August 19, 2002 5:38:14 PM]

Share this post


Link to post
Share on other sites