Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Rate Limited CNiSlider control

I have a need to limit the rate that the slider control can be moved.  What I have done so far is subclassed the CNiSlider control and created a CRateLimit template class to handle the slider moves.  This works pretty well, except that the slider pointer continually jumps between the mouse pointer position to the rate limited position as the mouse is moved.
The way I am doing this is trapping the OnPointerValueChanged message to my application, and then processing the requested pointer position value with the CRateLimit class.  The CRateLimit calss has a Sleep() delayed while loop which programmatically sets the pointer position in increments until it reaches the value requested by the OnPointerValueChanged message.  What I would like to do be able to process the message BEFORE the slider position is updated and painted so that I can get rid of the annoying flicker.  Is there any way to do this, or perhaps handle a rate limit better than this??
TIA
Eric

0 Kudos
Message 1 of 3
(3,445 Views)
Eric,

Would you mind posting your application?  You may be running into an issue of the Message Queue sending messages while your callback is still executing.  How long of a delay are you causing in between the slider movement.

A thought I had is that it may be possible to capture events for the entire form before the Messages are passed onto the controls that make up the form.  You could capture generic mouse events and over ride the event handling by the CSlider control.

If you wouldn't mind posting your application, then I may have a better idea of what you are attempting to accomplish.

Thanks,

Tyler Tigue
Applications Engineer
National Instruments
0 Kudos
Message 2 of 3
(3,433 Views)
I can't post the whole application, but here is a simplified version of it.  I capture the mouse down and mouse up events and set the m_bMouseIsDown flag appropriately.
I basically just creep the pointer along until I get to the proper point.  The problem is this callback happens after the pointer is painted at the new position.  m_lpControlKnob is a pointer to the slider.
Eric

#define CHECK_FOR_PARENT_MESSAGES(hwnd)   MSG msg;\
   while(::PeekMessage(&msg, hwnd,0,0,PM_REMOVE))\
{TranslateMessage(&msg);DispatchMessage(&msg);}

#define LOOP_DELAY_MS (20)

void CCMCSimulatorDlg::OnPointerValueChangedLF(long Pointer, VARIANT FAR* Value)
{
   static double lastVal = 0;
   double valueDiff = Value->dblVal - lastVal;
   double rateDirection = (fabs(valueDiff)/valueDiff);
 
   double maxRateChange = 10;
   maxRateChange = maxRateChange * LOOP_DELAY_MS/1000;
   DWORD dwStart = GetTickCount();
   DWORD dwDelayed = dwStart;
   if(rateDirection < 0)
   {
      while(m_bMouseIsDown && m_CurrentValue > Value->dblVal - maxRateChange)
      {
         m_CurrentValue-= maxRateChange;
         m_lpControlKnob->SetValue(m_CurrentValue);
         CHECK_FOR_PARENT_MESSAGES(m_ParentWnd);
         dwDelayed = GetTickCount() - dwStart;
         if(dwDelayed < LOOP_DELAY_MS)
         {
            Sleep(LOOP_DELAY_MS - dwDelayed);
         }
         dwStart = GetTickCount();
      }
   }
   else
   {
      while(m_bMouseIsDown && m_CurrentValue< Value->dblVal + maxRateChange)
      {
         m_CurrentValue+= maxRateChange;
         m_lpControlKnob->SetValue(m_CurrentValue);
         CHECK_FOR_PARENT_MESSAGES(m_ParentWnd);
         dwDelayed = GetTickCount() - dwStart;
         if(dwDelayed < LOOP_DELAY_MS)
         {
            Sleep(LOOP_DELAY_MS - dwDelayed);
         }
         dwStart = GetTickCount();
      }
   }
   if(m_bMouseIsDown)
   {
      m_CurrentValue= lastVal = Value->dblVal;
   }

   m_lpControlKnob->SetValue(m_CurrentValue);
  
}

0 Kudos
Message 3 of 3
(3,421 Views)