CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Mar 2003
    Posts
    13

    mouse button down

    In my dialog based MFC app i want a slider to be in the middle, moved by a mouse drag like it does normally, but then return to the middle when the mouse button is released.

    Ive had a go at a few things but my C++ aint good enuf to iron out the problems.

  2. #2
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    First of all, this is the Non Visual C++ forum. Did you know that
    MFC is only developed with Visual C++? Thus, this message does
    not belong here.

    However, I will indulge [until it's moved]. You know the position
    of the slider before it's moved, right? After it's moved, just set
    its position back to what it was before. I have no idea why you'd
    want to do this, though; you're basically making the control NOT
    a slider by allowing it to be set to only one value.

    --Paul

  3. #3
    Join Date
    Mar 2003
    Posts
    13
    Ill describe what i want it to do. I am creating an analogue rewind/fastforward slider. The user holds the mouse down on the slider and drags it left/right. The further in that direction the user drags, the faster speed of rewind/fastforward. Im gonna start with it just 1 speed for rewind, 1 for fastforward.

    All i am really asking is how do i set up a function that is called when the mouse button is pressed and another function that is called when the mouse button is released. Is question still in the wrong place? The MFC stuff i mentioned was just to add a bit of context to the problem.

  4. #4
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Of course it's in the wrong place Each class hierarchy for GUI
    components will have different methods of taking care of mouse
    input. Having said that, with WIN32, every window receives a
    message when an event happens. When the left mouse button
    is pressed down, your window receives the WM_LBUTTONDOWN
    message; when it's released, your window receives the
    WM_LBUTTONUP message. With MFC, you typically use a
    message map to map these messages to function calls. You
    need to read the documentation to figure out how to do this.
    Do a search on MSDN for WM_LBUTTONUP and "message map"
    and you will probably figure it out.

    --Paul

  5. #5
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    Actually I had a client that wanted something similar. In my
    case, basically simulating a thumbwheel with a slider control.

    Here is how I did it (there are probably better ways -
    my MFC use is minimal and knowledge limitted). Maybe
    you can adapt it to do what you want. (at any rate, with
    you move the slider windows sends WM_H_SCROLL message (or
    WM_V_SCROLL if vertical). Look up OnHScroll for more info.

    • associate a CSliderCtrl variable with your slider control.
      (in sample code below I named it : m_xTranslation_slider)
    • process WM_H_SCROLL for the dialog (if a horizontal slider)
    • add additional member variables to the dialog :
      Code:
      int m_xTranslation_old_position;  // saved position of slider control
      int m_xTranslation;               // current value of variable you are tracking
    • Initialize everything in dialog's OnInitDialog()
      Code:
      int minRange =   0;
      int maxRange = 100;
      int avgRange = (minRange+maxRange)/2;
      
      m_xTranslation_slider.SetRange(minRange,maxRange);
      m_xTranslation_slider.SetPos( avgRange );
      m_xTranslation_old_position = avgRange;
      
      m_xTranslation = 0;
    • process WM_H_SCROLL for the dialog (see where I have
      the TRACE() for the updated value)
      Code:
      void CNozzleEditorDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
      {
      
          if (pScrollBar->GetSafeHwnd() == m_xTranslation_slider.GetSafeHwnd())
          {
              int minRange , maxRange , avgRange;
              m_xTranslation_slider.GetRange(minRange,maxRange);
              avgRange = (minRange + maxRange)/2;
      
              int xTranslation_new_position = m_xTranslation_slider.GetPos();
      
              if (xTranslation_new_position != avgRange)
              {
                  if (xTranslation_new_position == m_xTranslation_old_position)
                  {
                      m_xTranslation_old_position = avgRange;
                      m_xTranslation_slider.SetPos(avgRange);
                  }
                  else
                  {
                      m_xTranslation += (xTranslation_new_position - m_xTranslation_old_position);
                      m_xTranslation_old_position = xTranslation_new_position;
                      TRACE("new value for xTranslation = %d\n",m_xTranslation);
                  }
              }
          }
      	
          CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
      }

  6. #6
    Join Date
    Mar 2003
    Posts
    13
    Thanks Philp!

    Do i have permission to use this for an application im making for a university project. Its not an integral function of the app but it will be a nice touch. Have a look at it if you want here .

  7. #7
    Join Date
    Mar 2003
    Posts
    13
    1 more thing

    The method that is called from the ON_HSCROLL message thingy works but when the slider is dragged to one side and held there i want a function to be called repeatedly whereas at the moment it can only be called once.
    To repeatedly call the function i need to release the mouse and click and drag again OR drag mouse to another position and then back again.

  8. #8
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,725
    So basically, what you want to do is this:

    As the user moves the slider, call some function
    with the slider position as an argument. If the user
    hold the slider at one particluar postion, you still
    want to keep calling the function. Currently it does
    not call the function, since WM_H_SCROLL message
    is not sent when the slider is not moving/moved.

    Here is one way around this. It is somehat messy, so
    I imagine there is a better way to do this. Basically,
    you are going to add a timer. Start the timer when the
    user first moves the slider and stop the timer when
    the slider goes back to the center position. In the
    timer function you can call your function.

    • process the WM_TIMER message for the dialog
    • add member variable :
      Code:
      bool m_timerRunning;              // true if timer has been started
    • initialize it in OnInitDialog()
      Code:
      m_timerRunning = false;
    • modify the OnHScroll() fucntion as follows:
      Code:
      void CDlgDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
      {	
          if (pScrollBar->GetSafeHwnd() == m_xTranslation_slider.GetSafeHwnd())
          {
              int minRange , maxRange , avgRange;
              m_xTranslation_slider.GetRange(minRange,maxRange);
              avgRange = (minRange + maxRange)/2;
      
              int xTranslation_new_position = m_xTranslation_slider.GetPos();
      
              if (xTranslation_new_position != avgRange)
              {
                  if (xTranslation_new_position == m_xTranslation_old_position)
                  {
                      if (m_timerRunning)
                      {
                          m_timerRunning = false;
                          KillTimer(1);
                      }
      
                      m_xTranslation_old_position = avgRange;
                      m_xTranslation_slider.SetPos(avgRange);
                  }
                  else
                  {
                      if (!m_timerRunning)
                      {
                          m_timerRunning = true;
                          SetTimer(1,250,NULL); // 250 = 0.25 seconds
                      }
      
                      m_xTranslation += (xTranslation_new_position - m_xTranslation_old_position);
                      m_xTranslation_old_position = xTranslation_new_position;
                      TRACE("new value for xTranslation = %d\n",m_xTranslation);
                  }
              }
          }
      
          CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
      }
    • code for the WM_TIMER message
      Code:
      void CDlgDlg::OnTimer(UINT nIDEvent) 
      {
      
          if (nIDEvent == 1) // 1 = first argument in the SetTimer() function
          {
              // do something based on m_xTranslation
          }
      	
          CDialog::OnTimer(nIDEvent);
      }

  9. #9
    Join Date
    Mar 2003
    Posts
    13
    I already have one timer running. Can i start another? I dont want what ive programmed to do on a timer event to happen every time the rewind is pressed.

    If it helps, when my rewind is pressed the other timer is always stopped (it pauses the animation).

  10. #10
    Join Date
    Mar 2003
    Posts
    13
    I setup my OnTimer function so if the id is 1 it does what it did origionally did but if it is 2, the 1st number i used when i SetTimer it does what your suggesting.

    And with a little fiddling of my code - it works!

    Thanks.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured