Scrolling Graph <p>I am trying to draw a graph that has a scrollbar,<br> the graph uses time for the x-axis and i'd like to have a limited x-axis (1 minute)<br> so up until 1 minute, the scroll bar's page is the length of the scrollbar,<br> after that the page should be '60 seconds long' and the scrollbar max should be 'elapsed time' long<br> when you drag the scrollbar it tracks along, and pulls up the relevant bit of the graph.<br> the graph should auto-scroll until its dragged away (and auto-scroll once its dragged back to max)</p> <p>this is what i have so far</p> <p>is defined at the top of the wndproc<br> <code>static SCROLLINFO sci = {sizeof(SCROLLINFO),SIF_RANGE|SIF_POS|SIF_PAGE|SIF_TRACKPOS,0,0,0,0,0};</code> </p> <p>in the WM_HSCROLL event:</p> <pre><code>GetScrollInfo((HWND)lParam, SB_CTL, &amp;sci); int pos; pos = sci.nPos; switch(LOWORD(wParam)) { case SB_PAGELEFT: pos -= sci.nPage; break; case SB_LINELEFT: pos -= (sci.nMax/10); break; case SB_PAGERIGHT: pos += sci.nPage; break; case SB_LINERIGHT: pos += (sci.nMax/10); break; case SB_THUMBTRACK: tsTracking = true; pos = sci.nTrackPos; break; case SB_THUMBPOSITION: tsTracking = false; pos = sci.nTrackPos; break; } if (pos &lt; sci.nMin) pos = sci.nMin; if (pos &gt; sci.nMax) pos = sci.nMax; if (pos != sci.nPos) { sci.fMask = SIF_POS; sci.nPos = pos; if(sci.nPos &gt;= (sci.nMax-(sci.nPage*1.2)-1)) //this should detect when the thumb has reached the end of the scrollbar sci.nPos = sci.nMax; SetScrollInfo((HWND)lParam, SB_CTL, &amp;sci, TRUE); PostMessage(hWnd, WM_COMMAND, IDM_DISPLAYRESULTS, 0); } break; </code></pre> <p>in the drawing code called from WM_PAINT<br> (yes i realize i shouldn't be setting the scrollbar's info here, i intend to put it in its proper place once its working properly)</p> <p>at the top of the graph-drawing function:</p> <p><code>static SCROLLINFO sci = {sizeof(SCROLLINFO),SIF_RANGE|SIF_POS|SIF_PAGE|SIF_TRACKPOS,0,0,0,0,0};</code> </p> <p>in the graph-drawing function:</p> <pre><code>__int64 elapsed_time = g_h_maxX-g_h_minX, //the elapsed time windowLengthMS, //the current window length in ms (between 0 and MAX_TIME_WIDTH_MS) start, //the start of the current window end; //the end of the current window static UINT32 windowMaxS = 1; //how long the window max is (used for x sub-divisions) double xTickStep, //x division step yTickStep, //y division step xScale, //x-scale (used to get the time relative to the elapsed time and size of the graph) yScale; //y-scale (used to get the data being plotted relative to its max, and the size of the graph) if(!tsTracking) //a global bool, checking if the scrollbar's thumb is being dragged { GetScrollInfo(get_chwnd(IDCW_HARMONICSRESULTSTIMESHIFTSB),SB_CTL,&amp;sci); //gets the scroll info for the scrollbar int pos = sci.nPos*(double(elapsed_time)/double(sci.nMax - sci.nMin)); //gets the position relative to the new max sci.nMin = g_h_minX; //sets min (should always be the same, done for completeness) sci.nMax = (((g_h_maxX-MAX_TIME_WIDTH_MS)&gt;0)?(g_h_maxX):0); //sets max to either max, or 0 (if max isnt bigger then page length) sci.nPage = MAX_TIME_WIDTH_MS; //sets the page length to the window length sci.nPos = pos; //sets position to its new value if(sci.nPos &gt;= (sci.nMax-(sci.nPage*1.2)-1)) //if position is one "page" from the end sci.nPos = sci.nMax; //set it to max SetScrollInfo(get_chwnd(IDCW_HARMONICSRESULTSTIMESHIFTSB),SB_CTL,&amp;sci,true); } //set scroll info if (elapsed_time &gt; MAX_TIME_WIDTH_MS) //if elapsed time is longer then the max window length { end = ((double)sci.nPos / double(sci.nMax)) * g_h_maxX; //set the end to current (scroll position / scroll max) * latest time -&gt; this should put end relative to the scrollbar start = end-MAX_TIME_WIDTH_MS; //sets start to end - window length if (start &lt; 0) //if start is now less than zero { end = MAX_TIME_WIDTH_MS; //set end to window length start = 0; //set start to 0 } } else //if (elapsed_time &lt;= MAX_TIME_WIDTH_MS) { start = g_h_minX; //start is min end = g_h_maxX; //end is max } windowLengthMS = (end-start); //find the current window length if(_MSTOSECS(windowLengthMS) &gt; windowMaxS) //if the current window length beats one fo the markers windowMaxS = ((windowMaxS &lt; 10)?windowMaxS+1:(windowMaxS==40)?windowMaxS*1.5:windowMaxS*2); //change subdiv scaling xScale = double(graph_width)/double(windowLengthMS); //set x-scale to width / window length yScale = (double)(graph_height)/((double)g_h_maxY - (double)g_h_minY); //set y-scale to height / (maxVal-minVal) int ticks = _MSTOSECS(elapsed_time); //ticks = full seconds elapsed xTickStep = double(graph_width)/double(ticks+1); //tickstep = seconds+1 (accounts for 0) yTickStep = double(graph_height)/double(Y_TICKS); //6 y-ticks, constant. SelectObject(hDC,hThickPen); { //scope to clear variables! double x; //x to store subdiv x-location for(i = ticks; i &gt;= 0; i--) //for each subdiv { if(((windowMaxS&gt;40)?(!(i%3)):(windowMaxS &gt;20)?(!(i%2)):i)) //have if &lt;=20 secs, each second is shown on x, &gt;20 &lt;=40, every second second is shown, &gt;40 seconds, every 3rd second is shown { x = round((_SECSTOMS(i)*xScale)); //find x-pos sprintf(buf,"%d",(i+_MSTOSECS(start))); //print to buffer SetRect(&amp;rc, fr.left+x-5, fr.bottom+5, fr.left+x+xTickStep, fr.bottom+25); //get text rectangle DrawText(hDC, buf, -1, &amp;rc, DT_SINGLELINE | DT_VCENTER | DT_LEFT); //draw text } if (i!=ticks &amp;&amp; (windowMaxS&gt;40)?(!(i%6)):(windowMaxS &gt;20)?(!(i%4)):(windowMaxS&gt;10)?(!(i%2)):i)//every &lt;10, each sec gets a subdiv, &lt;20 each second tick gets a subdiv, &lt;40 each 6th tick gets a subdiv { MoveToEx(hDC, GRAPH_XL_OFFSET+x, graph_bottom, NULL); //draw the line LineTo(hDC, GRAPH_XL_OFFSET+x, graph_bottom-graph_height); //draw the line } } } </code></pre> <p>as for globals:<br> <code>g_h_minX</code> is the start time and<br> <code>g_h_maxX</code> is the last result time<br> <code>MAX_TIME_WIDTH_MS</code> is the "window length" in ms -> how long i want the scroll bar page (60 seconds)</p> <p>so the idea is to set <code>end</code> to where the scroll bar is, and get the <code>start</code> by taking the window length from <code>end</code>, and working out which part of the graph we're trying to look at.</p> <p>i've been fiddling with this for the last 2 days and i'm running out of ideas. im sure i'm close, but i cant quite figure it out,</p> <p>edit:<br> updated the code slightly<br> it also seems i forgot to say what the problem was.<br> the scolling code isnt working properly, it autoscrolls when new data comes in,<br> but when i drag the thumb away from the end of the scrollbar, it just snaps to the start, and wont move. on closer inspection, the arrows work, and the "page-right" "page-left" on the right-click menu work, just not the tracking </p> <p>any help would be appreciated.</p> <p>thanks in advance.</p>