我正在尝试绘制一个带有滚动条的图形,
该图形使用 x 轴的时间,我希望有一个有限的 x 轴(1 分钟)
,所以直到 1 分钟,滚动条的页面是长度滚动条,
之后页面应该是“60 秒长”,并且
当您拖动它跟踪的滚动条并拉起图形的相关位时,滚动条最大值应该是“经过时间”长。
图表应该自动滚动直到它被拖走(并且一旦它被拖回最大值就自动滚动)
这就是我到目前为止所拥有的
在 wndproc 的顶部定义
static SCROLLINFO sci = {sizeof(SCROLLINFO),SIF_RANGE|SIF_POS|SIF_PAGE|SIF_TRACKPOS,0,0,0,0,0};
在 WM_HSCROLL 事件中:
GetScrollInfo((HWND)lParam, SB_CTL, &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 < sci.nMin) pos = sci.nMin;
if (pos > sci.nMax) pos = sci.nMax;
if (pos != sci.nPos)
{
sci.fMask = SIF_POS;
sci.nPos = pos;
if(sci.nPos >= (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, &sci, TRUE);
PostMessage(hWnd, WM_COMMAND, IDM_DISPLAYRESULTS, 0);
}
break;
在从 WM_PAINT 调用的绘图代码中
(是的,我意识到我不应该在此处设置滚动条的信息,我打算在其正常工作后将其放在适当的位置)
在绘图功能的顶部:
static SCROLLINFO sci = {sizeof(SCROLLINFO),SIF_RANGE|SIF_POS|SIF_PAGE|SIF_TRACKPOS,0,0,0,0,0};
在绘图功能中:
__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,&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)>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 >= (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,&sci,true);
} //set scroll info
if (elapsed_time > 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 -> this should put end relative to the scrollbar
start = end-MAX_TIME_WIDTH_MS; //sets start to end - window length
if (start < 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 <= 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) > windowMaxS) //if the current window length beats one fo the markers
windowMaxS = ((windowMaxS < 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 >= 0; i--) //for each subdiv
{
if(((windowMaxS>40)?(!(i%3)):(windowMaxS >20)?(!(i%2)):i)) //have if <=20 secs, each second is shown on x, >20 <=40, every second second is shown, >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(&rc, fr.left+x-5, fr.bottom+5, fr.left+x+xTickStep, fr.bottom+25); //get text rectangle
DrawText(hDC, buf, -1, &rc, DT_SINGLELINE | DT_VCENTER | DT_LEFT); //draw text
}
if (i!=ticks && (windowMaxS>40)?(!(i%6)):(windowMaxS >20)?(!(i%4)):(windowMaxS>10)?(!(i%2)):i)//every <10, each sec gets a subdiv, <20 each second tick gets a subdiv, <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
}
}
}
至于全局变量:
g_h_minX
是开始时间,
g_h_maxX
是最后一个结果时间
MAX_TIME_WIDTH_MS
是毫秒的“窗口长度”->我想要滚动条页面多长时间(60秒)
所以我们的想法是设置end
滚动条所在的位置,并start
通过从中获取窗口长度end
,并计算出我们要查看的图形的哪一部分。
在过去的两天里,我一直在摆弄这个,我的想法已经不多了。我确定我很接近,但我无法弄清楚,
编辑:
稍微更新了代码
似乎我也忘了说问题是什么。
scolling 代码不能正常工作,当有新数据进入时它会自动滚动,
但是当我将拇指拖离滚动条的末端时,它只是捕捉到开始,并且不会移动。仔细观察,箭头有效,右键菜单上的“page-right”“page-left”有效,只是没有跟踪
任何帮助,将不胜感激。
提前致谢。