Snapping windows to the desktop edge
-
Here is what I've coded for the task
case WM_MOVING: { LPRECT lprc = (LPRECT)lParam; RECT WD;//get width and height of window - WD = WindowDimensions GetWindowRect(hwndDlg,&WD); WD.right -= WD.left;//Width WD.bottom -= WD.top;//Height RECT VDR;//VDR = VisibleDesktopRect SystemParametersInfo(SPI_GETWORKAREA,0,&VDR,0); if(lprc->left <= VDR.left + 5 && lprc->left >= VDR.left - 5)//Left { lprc->left = VDR.left; lprc->right = lprc->left + WD.right; } if(lprc->top <= VDR.top + 5 && lprc->top >= VDR.top - 5)//Top { lprc->top = VDR.top; lprc->bottom = lprc->top + WD.bottom; } if(lprc->right >= VDR.right - 5 && lprc->right <= VDR.right + 5)//Right { lprc->right = VDR.right; lprc->left = lprc->right - WD.right; } if(lprc->bottom >= VDR.bottom - 5 && lprc->bottom <= VDR.bottom + 5)//Bottom { lprc->bottom = VDR.bottom; lprc->top = lprc->bottom - WD.bottom; } int HalfHeight = ((VDR.bottom - VDR.top) / 2) - (WD.bottom / 2); int HalfWidth = ((VDR.right - VDR.left) / 2) - (WD.right / 2 ); if ((lprc->top >= HalfHeight - 5 && lprc->top <= HalfHeight) || (lprc->top <= HalfHeight + 5 && lprc->top >= HalfHeight))//Center Up-Down { lprc->top = HalfHeight; lprc->bottom = lprc->top + WD.bottom; } if ((lprc->left >= HalfWidth - 5 && lprc->left <= HalfWidth) || (lprc->left <= HalfWidth + 5 && lprc->left >= HalfWidth))//Center Left-Right { lprc->left = HalfWidth; lprc->right = lprc->left + WD.right; } return TRUE; } break;
The only problem is after it's been snapped, when you move the mouse slowly away from the edge the window will stay put! Why does it do that? I want it to mimic DVD Decrypter Thank you. -
Here is what I've coded for the task
case WM_MOVING: { LPRECT lprc = (LPRECT)lParam; RECT WD;//get width and height of window - WD = WindowDimensions GetWindowRect(hwndDlg,&WD); WD.right -= WD.left;//Width WD.bottom -= WD.top;//Height RECT VDR;//VDR = VisibleDesktopRect SystemParametersInfo(SPI_GETWORKAREA,0,&VDR,0); if(lprc->left <= VDR.left + 5 && lprc->left >= VDR.left - 5)//Left { lprc->left = VDR.left; lprc->right = lprc->left + WD.right; } if(lprc->top <= VDR.top + 5 && lprc->top >= VDR.top - 5)//Top { lprc->top = VDR.top; lprc->bottom = lprc->top + WD.bottom; } if(lprc->right >= VDR.right - 5 && lprc->right <= VDR.right + 5)//Right { lprc->right = VDR.right; lprc->left = lprc->right - WD.right; } if(lprc->bottom >= VDR.bottom - 5 && lprc->bottom <= VDR.bottom + 5)//Bottom { lprc->bottom = VDR.bottom; lprc->top = lprc->bottom - WD.bottom; } int HalfHeight = ((VDR.bottom - VDR.top) / 2) - (WD.bottom / 2); int HalfWidth = ((VDR.right - VDR.left) / 2) - (WD.right / 2 ); if ((lprc->top >= HalfHeight - 5 && lprc->top <= HalfHeight) || (lprc->top <= HalfHeight + 5 && lprc->top >= HalfHeight))//Center Up-Down { lprc->top = HalfHeight; lprc->bottom = lprc->top + WD.bottom; } if ((lprc->left >= HalfWidth - 5 && lprc->left <= HalfWidth) || (lprc->left <= HalfWidth + 5 && lprc->left >= HalfWidth))//Center Left-Right { lprc->left = HalfWidth; lprc->right = lprc->left + WD.right; } return TRUE; } break;
The only problem is after it's been snapped, when you move the mouse slowly away from the edge the window will stay put! Why does it do that? I want it to mimic DVD Decrypter Thank you.The problem is that if the mouse moves slowly, you'll put it back where it was so that the user keeps having to drag it from the same spot. If they don't move enough, you'll keep snapping it back to where it was. I think the easiest way (and I'm happy for someone to correct this) is to keep track of where the window and mouse cursor were when the operation was initiated (handle the
WM_ENTERSIZEMOVE
message) and calculate the full window position each time, rather than using the rectangle that was provided to you in theWM_MOVING
message. Something like this: In WM_ENTERSIZEMOVE: - Get the window rectangle (GetWindowRect()
) - I'll call it oldWindowPos - Get the mouse cursor position (GetMessagePos()
) - I'll call it oldCursorPos In WM_MOVING: - Get the current cursor position (GetMessagePos()
) - I'll call it newCursorPos -newWindowPos.left = newCursorPos.x + (oldWindowPos.left - oldCursorPos.x)
-newWindowPos.right = newCursorPos.x + (oldWindowPos.right - oldCursorPos.x)
-newWindowPos.top = newCursorPos.y + (oldWindowPos.top - oldCursorPos.y)
-newWindowPos.bottom = newCursorPos.y + (oldWindowPos.bottom - oldCursorPos.y)
[edit]Forgot to mention that after this, you'd snap the window position :doh:[/edit] Something like that, anyway :)Ryan
"Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"