Reputation: 137
As you can see from the code snippet below, I've implemented a way to drag the Windows command prompt by its client area.
The problem with this code is that if the user follows these steps:
The console window will stop following the cursor, until it's moved to be inside the window again.
The fact that this does not happen when the console window is already in-focus at step 1, is what's really weird to me. I've tried debugging this for so many hours now, I just can't do it anymore. I'd appreciate any help regarding this.
// Continuously read input
while(ReadConsoleInput(hIn, &ir, 1, &nr))
{
switch(ir.EventType)
{
// Left mouse button down that either focuses or unfocuses console window
case FOCUS_EVENT:
// Left mouse button down that focuses console window
if(ir.Event.FocusEvent.bSetFocus)
{
GetCursorPos(&firstPos);
ScreenToClient(hWnd, &firstPos);
}
break;
case MOUSE_EVENT:
// Mouse did something inside console window
switch(ir.Event.MouseEvent.dwButtonState)
{
// Left mouse button down or up
case FROM_LEFT_1ST_BUTTON_PRESSED:
// Left mouse down or up, no drag
if(!ir.Event.MouseEvent.dwEventFlags)
{
GetCursorPos(&firstPos);
ScreenToClient(hWnd, &firstPos);
}
// Left button down, and mouse move. -> drag
if(ir.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
{
GetCursorPos(¤tRelativeToScreen);
// Calculate window position while dragging
// |
// v
if(currentRelativeToScreen.x - firstPos.x > scrnSz.right - ca.right)
wndPos.X = scrnSz.right - ca.right;
else if(currentRelativeToScreen.x - firstPos.x < 0)
wndPos.X = 0;
else
wndPos.X = currentRelativeToScreen.x - firstPos.x;
if(currentRelativeToScreen.y - firstPos.y > scrnSz.bottom - ca.bottom)
wndPos.Y = scrnSz.bottom - ca.bottom;
else if(currentRelativeToScreen.y - firstPos.y < 0)
wndPos.Y = 0;
else
wndPos.Y = currentRelativeToScreen.y - firstPos.y;
// End window position calculations
SetWindowPos(hWnd, 0, wndPos.X, wndPos.Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
break;
default:
break;
}
break;
default:
break;
}
Upvotes: 0
Views: 484
Reputation: 2180
on mouse move do:
if(button==leftButton){
ReleaseCapture();
SenMessage(hWnd,WM_NCLBUTTON_DOWN,HTCAPTION,lParam);
}
Upvotes: 0
Reputation: 17628
Drag the window so that the cursor escapes window area [...] The console window will stop following the cursor, until it's moved to be inside the window again.
This is the expected behavior, as documented at https://msdn.microsoft.com/en-us/library/windows/desktop/ms684239.aspx (emphasis added).
Mouse events are generated whenever the user moves the mouse, or presses or releases one of the mouse buttons. Mouse events are placed in a console's input buffer only when the console group has the keyboard focus and the cursor is within the borders of the console's window.
this does not happen when the console window is already in-focus at step 1
Though not obvious from the official documentation, the console window appears to capture the mouse when clicked (and thus track it even when moved outside the console window) only if it already had the focus at the time of the click. For a console window out of focus, the 1st click gives it the focus (without globally capturing the mouse, so it only receives MOUSE_MOVE notifications while the cursor is within its client area), while the 2nd click enters exclusive capture mode (and receives all MOUSE_MOVE notifications regardless of cursor position).
This can be verified with a standard console window set to quick-edit mode. If the window has the input focus, then click-and-drag selects text in the console, even if the mouse is moved outside the window. However, if the window does not have the focus. the 1st click just gives it the focus, but does not enter any capture mode and dragging does not select any text.
Upvotes: 1