从下面的代码段中可以看出,我已经实现了一种通过客户区域拖动Windows命令提示符的方法。
此代码的问题在于,如果用户遵循以下步骤:
控制台窗口将停止跟随光标,直到它再次移动到窗口内。
当控制台窗口在第1步已经处于焦点时,这种情况不会发生,这对我来说真的很奇怪。我已经尝试了这么多小时的调试,我再也不能这样做了。我很感激任何帮助。
// 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;
}
答案 0 :(得分:1)
拖动窗口,使光标逃离窗口区域[...]控制台窗口将停止跟随光标,直到它再次移动到窗口内。
这是预期的行为,如https://msdn.microsoft.com/en-us/library/windows/desktop/ms684239.aspx(强调添加)所述。
只要用户移动鼠标,或按下或释放其中一个鼠标按钮,就会生成鼠标事件。 仅当控制台组具有键盘焦点 并且光标位于控制台窗口的边框内时,鼠标事件才会放置在控制台的输入缓冲区中 强>
<小时/> [编辑]回答关于此的后续评论。
当控制台窗口已在步骤1中处于焦点时,不会发生这种情况
虽然官方文档中并不明显,但控制台窗口似乎在单击时捕获鼠标(因此即使在移出控制台窗口之外也会跟踪它)仅如果它已经在焦点位于点击的时间。对于没有焦点的控制台窗口,第一次单击使其成为焦点(没有全局捕获鼠标,因此它仅在光标位于其客户区域内时接收MOUSE_MOVE通知),而第二次单击进入独占捕获模式(并接收所有MOUSE_MOVE通知,无论光标位置如何)。
这可以通过设置为快速编辑模式的标准控制台窗口进行验证。如果窗口具有输入焦点,则即使鼠标移动到窗口外,单击并拖动也会在控制台中选择文本。但是,如果窗口没有焦点。第一次单击只是给它焦点,但没有进入任何捕获模式,拖动不会选择任何文本。
答案 1 :(得分:0)
:
if(button==leftButton){
ReleaseCapture();
SenMessage(hWnd,WM_NCLBUTTON_DOWN,HTCAPTION,lParam);
}