我有(舊...)代碼在SetScrollRange()
的背景中更新滾動條位置和最小最大值,但此代碼不應該在用戶是拖動滾動條旋鈕,因爲它使旋鈕在視覺上跳回到原始位置,然後在拖動或釋放鼠標時跳回到用戶選擇的位置。如何檢測用戶正在拖動滾動條旋鈕
是否有一些簡單的方法來檢測拖動正在進行?
我有(舊...)代碼在SetScrollRange()
的背景中更新滾動條位置和最小最大值,但此代碼不應該在用戶是拖動滾動條旋鈕,因爲它使旋鈕在視覺上跳回到原始位置,然後在拖動或釋放鼠標時跳回到用戶選擇的位置。如何檢測用戶正在拖動滾動條旋鈕
是否有一些簡單的方法來檢測拖動正在進行?
我可以想到兩種方法來做到這一點。簡單(和哈希)的方法是調用GetCapture()。它將返回已捕獲鼠標的當前窗口的HWND值,如果未捕獲到鼠標,則返回NULL。這只是表示用戶在滾動條控件內按下了鼠標按鈕而不釋放鼠標按鈕。
更好的方法是將控件進行子類化。下面是關於如何你可以設置一個標誌一些示例代碼,如果滾動條的「拇指」被拖動:
// Somewhere in your code, subclass the scrollbar
WNDPROC originalScrollBarWndProc = (WNDPROC) SetWindowLongPtr(scrollBarHwnd, GWLP_WNDPROC, (LONG_PTR) myScrollBarWndProc);
LRESULT CALLBACK myScrollBarWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_LBUTTONDOWN:
{
// Get Y position of the mouse
uint16_t mouseYPos = HIWORD(lParam); // Change this to LOWORD for horizontal scrollbars
// Get the top and bottom coordinates of the scrollbar thumb
SCROLLBARINFO sbi = {0};
sbi.cbSize = sizeof(SCROLLBARINFO);
if(GetScrollBarInfo(hwnd, OBJID_CLIENT, &sbi) == 0)
{
// Failed to get scroll bar info, handle however you want
break;
}
// Check if the WM_LBUTTONDOWN event happened over the scrollbar thumb
if(mouseYPos >= sbi.xyThumbTop && mouseYPos <= sbi.xyThumbBottom)
{
// Set a flag to indicate that the thumb is being "dragged"
// I chose to do this using SetWindowLongPtr; Do it however you like.
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) 1);
}
}
break;
case WM_LBUTTONUP:
{
// Mouse button was released, clear the flag
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) 0);
}
break;
/* ... other cases here, if needed ... */
}
return CallWindowProc(originalScrollBarWndProc, hwnd, message, wParam, lParam);
}
使用上面的代碼,所有你需要做的就是調用GetWindowLongPtr(scrollBarHwnd,GWLP_USERDATA),並檢查如果該值爲0或1以查看是否被拖動。
我不是積極的,這是最好的方法的問題,但我相信它至少是一個很好的工作。
當用戶圍繞滾動條的拇指拖動,滾動條的所有者窗口接收WM_VSCROLL
(垂直)或WM_HSCROLL
(水平)消息(取決於滾動條的定向),其中wParam
值的LO-字被設定到SB_THUMBTRACK
並且hi-word被設置爲新的位置。
當用戶釋放拇指,所有者窗口接收到兩個最終WM_(V|H)SCROLL
消息:
wParam
值設置爲SB_THUMBPOSITION
和Hi-字設置爲新的LO-字位置。wParam
,設置爲TB_ENDTRACK
。您可以繼承擁有滾動條的UI控件來攔截這些消息。當看到任何WM_(V|H)SCROLL
消息時,請勿更新滾動條,直至看到SB_ENDTRACK
通知。
因此,當我看到'TB_ENDTRACK'時,我可以在獲得第一個'SB_THUMBTRACK'時設置一些全局/靜態狀態並重置該狀態? –
@ErikElmgren是的 –
['SB_THUMBTRACK'](https://msdn.microsoft.com/en-us/library/windows/desktop/bb787577(v = vs.85).aspx) – zett42
@ zett42那會告訴我它被拖動最近在處理該消息時,而不是在處理其他消息時(在本例中爲後臺計時器)。 –