正如您從下面的代碼片段中看到的,我已經實現了一種通過其客戶區拖動Windows命令提示符的方法。使用ReadConsoleInput()拖動控制檯窗口
這段代碼的問題是,如果用戶遵循下列步驟:
- 無焦點控制檯窗口
- 焦點控制檯窗口通過點擊和拖動它(不釋放)
- 拖動窗口,以便光標逃離窗口區域(這可能意味着移動光標太快,或超出設置範圍(第二個顯示器),或通過任務欄/其他永遠在頂部的窗口)
控制檯窗口將停在光標後面,直到它再次移動到窗口內。
事實上,當控制檯窗口在步驟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;
}
你怎麼又解釋說,如果窗口有焦點的整個時間的鼠標事件產生,而光標仍在窗口邊界之外?此外,即使這是預期的行爲(我懷疑,從UX的角度來看,加上其他窗口的行爲並沒有這種方式),我仍然有興趣提供一種方法來規避這種行爲。 – user4780006
我編輯了我的答案來覆蓋那個部分。不知道有一種解決方法,因爲控制檯窗口本身是相當特殊的。 – dxiv
很好的編輯,很好的解釋。但我仍然在尋找(至少有點)理智的方式......我猜即使在第一次(聚焦)點擊時,模擬全局捕獲鼠標移動的命令提示符。我假設這會以某種方式手動跟蹤鼠標。 – user4780006