-
novel method of dragging
Hello again,
so I saw this novel method to initiate dragging of a window:
Code:
SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION,0);
It tricks window into thinking that the title bar is mousedown'ed. The problem is I need to know when the user has finished dragging (i.e mouseupped), but the message for that seems to be intercepted by windows somehow.
Is anyone familiar with the trick and know how to get the mouse-up of this thing? Otherwise, I'll actually have to implement an actual dragging routine, and that will probably be annoying..
Cheers, and thanks in advance!
-
>>I saw this novel method to initiate dragging of a window<<
It's a variation on a theme; another is:
Code:
SendMessage(hwnd,WM_SYSCOMMAND,HTCAPTION|SC_MOVE, lParam);
(search this board for that one). Ultimately, all that's happening is something like:
Code:
case WM_NCHITTEST:
if (GetAsyncKeyState(VK_LBUTTON)&0x8000)
{
return HT_CAPTION;
}
else
{
/*return default handling (DefWindowProc,CallWindowProc etc.)*/
}
(check out WM_NCHITTEST).
From what I understand, WM_NCHITTEST effectively synthesises the other mouse messages so, when you skew its behaviour by telling it it's left-clicked on the caption, this is responsible for the loss of the other mouse messages.
So, you can either
1. synthesise the mouse message of interest yourself, eg for WM_LBUTTONUP, something like:
Code:
case WM_NCHITTEST:
{
static BOOL bIsLButtonDown;
if (GetAsyncKeyState(VK_LBUTTON)&0x8000)
{
bIsLButtonDown=TRUE;
return HTCAPTION;
}
else
{
if (bIsLButtonDown==TRUE)
{
POINT pt={LOWORD(lParam),HIWORD(lParam)};
UINT uFlags=0;
bIsLButtonDown=FALSE;
/*need to convert mouse coords*/
ScreenToClient(hwnd,&pt);
/*synthesise mouse up event*/
/*first get state of other mouse buttons; should, ideally get
key states of SHIFT and CTRL buttons on keyboard, too.*/
if (GetAsyncKeyState(VK_MBUTTON)&0x8000)
{
uFlags|=MK_MBUTTON;
}
if (GetAsyncKeyState(VK_RBUTTON)&0x8000)
{
uFlags|=MK_RBUTTON;
}
SendMessage(hwnd,WM_LBUTTONUP,uFlags,MAKELPARAM( pt.x,pt.y));
}
/*return DefWindowProc,CallWindowProc etc*/
}
or,
2. much simpler, you could just handle the WM_EXITSIZEMOVE message, ie.
Code:
case WM_EXITSIZEMOVE:
{
if (!GetAsyncKeyState(VK_LBUTTON)&0x8000)
{
/*mouse L-button is up*/
}
return 0;
}
Please note that GetAsyncKeyState works with physical mouse buttons so may not necessarily correspond to the way a user may have configured their mouse (GetSystemMetrics will resolve any uncertainty here).
-
thanks, that really clears it up :)