2017-07-06 19 views
1

スクロールバーの位置とバックグラウンドの最小値の値をSetScrollRange()で更新する(古いコード)がありますが、このコードはユーザースクロールバーのノブをドラッグすると、ノブを視覚的に元の位置に戻した後、マウスをドラッグまたはリリースしたときにユーザーの選択した位置にジャンプします。スクロールバーのつまみがユーザーによってドラッグされていることを検出する方法

ドラッグが行われていることを検出する簡単な方法はありますか?

+0

['SB_THUMBTRACK'](https://msdn.microsoft.com/en-us/library/windows/desktop/bb787577(v = vs.85).aspx) – zett42

+0

@ zett42これはドラッグされた最近このメッセージを扱うときには、他のメッセージ(この場合はバックグラウンドタイマー)を扱うときではありません。 –

答えて

1

私はこれを行うには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の場合、ドラッグされているかどうかを確認します。

私はこれがの問題に最も接近しているとは思っていませんが、それがうまくいくことは確かです。

2

ユーザがスクロールバーのサムの周りにドラッグされ、スクロールバーの所有者ウィンドウがwParam値のLO-ワードが設定され、(スクロールバーの向きに応じて)WM_VSCROLL(垂直)またはWM_HSCROLL(水平)メッセージを受信しますSB_THUMBTRACKに、ハイワードが新しい位置に設定されます。

  • 最初のメッセージは、新たに設定SB_THUMBPOSITIONに設定wParam値とハイワードのLO-ワードを有する:ユーザーが親指を離すと

    は、所有者ウィンドウは2つの最終WM_(V|H)SCROLLメッセージを受信しますポジション。

  • 2番目のメッセージはwParamのlo-wordがTB_ENDTRACKに設定されています。

スクロールバーを所有するUIコントロールをサブクラス化して、これらのメッセージを傍受することができます。 WM_(V|H)SCROLLメッセージが表示された場合は、SB_ENDTRACK通知が表示されるまでスクロールバーを更新しないでください。

+0

私は最初の 'SB_THUMBTRACK'を取得したときにグローバル/静的状態をいくつか設定でき、' TB_ENDTRACK'を見るとこれをリセットしますか? –

+1

@ErikElmgrenはい –

関連する問題