スクロールバーの位置とバックグラウンドの最小値の値をSetScrollRange()
で更新する(古いコード)がありますが、このコードはユーザースクロールバーのノブをドラッグすると、ノブを視覚的に元の位置に戻した後、マウスをドラッグまたはリリースしたときにユーザーの選択した位置にジャンプします。スクロールバーのつまみがユーザーによってドラッグされていることを検出する方法
ドラッグが行われていることを検出する簡単な方法はありますか?
スクロールバーの位置とバックグラウンドの最小値の値をSetScrollRange()
で更新する(古いコード)がありますが、このコードはユーザースクロールバーのノブをドラッグすると、ノブを視覚的に元の位置に戻した後、マウスをドラッグまたはリリースしたときにユーザーの選択した位置にジャンプします。スクロールバーのつまみがユーザーによってドラッグされていることを検出する方法
ドラッグが行われていることを検出する簡単な方法はありますか?
私はこれを行うには2つの方法が考えられます。 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の場合、ドラッグされているかどうかを確認します。
私はこれがの問題に最も接近しているとは思っていませんが、それがうまくいくことは確かです。
ユーザがスクロールバーのサムの周りにドラッグされ、スクロールバーの所有者ウィンドウがwParam
値のLO-ワードが設定され、(スクロールバーの向きに応じて)WM_VSCROLL
(垂直)またはWM_HSCROLL
(水平)メッセージを受信しますSB_THUMBTRACK
に、ハイワードが新しい位置に設定されます。
SB_THUMBPOSITION
に設定wParam
値とハイワードのLO-ワードを有する:ユーザーが親指を離すと は、所有者ウィンドウは2つの最終WM_(V|H)SCROLL
メッセージを受信しますポジション。
wParam
のlo-wordがTB_ENDTRACK
に設定されています。スクロールバーを所有するUIコントロールをサブクラス化して、これらのメッセージを傍受することができます。 WM_(V|H)SCROLL
メッセージが表示された場合は、SB_ENDTRACK
通知が表示されるまでスクロールバーを更新しないでください。
私は最初の 'SB_THUMBTRACK'を取得したときにグローバル/静的状態をいくつか設定でき、' TB_ENDTRACK'を見るとこれをリセットしますか? –
@ErikElmgrenはい –
['SB_THUMBTRACK'](https://msdn.microsoft.com/en-us/library/windows/desktop/bb787577(v = vs.85).aspx) – zett42
@ zett42これはドラッグされた最近このメッセージを扱うときには、他のメッセージ(この場合はバックグラウンドタイマー)を扱うときではありません。 –