График прокрутки

Я пытаюсь нарисовать график с полосой прокрутки,
график использует время для оси 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и выяснение, на какую часть графика мы пытаемся взглянуть.

Я возился с этим в течение последних 2 дней, и у меня заканчиваются идеи. я уверен, что я близко, но я не могу понять это,

редактировать:
немного обновил код
кажется, я забыл сказать, в чем проблема.
скроллинг не работает должным образом, он автоматически прокручивается при поступлении новых данных,
но когда я перетаскиваю большой палец от конца полосы прокрутки, он просто привязывается к началу и не будет двигаться. при ближайшем рассмотрении стрелки работают, и "страница-вправо" "страница-влево" в меню, вызываемом правой кнопкой мыши, работает, но не отслеживание

любая помощь будет оценена.

заранее спасибо.

1 ответ

Решение

Мне удалось найти проблему, я в конечном итоге преобразовал все в секунды и работал с этим, что в итоге заработало, поэтому у меня, должно быть, были некоторые проблемы с масштабированием.
код закончился так:

case WM_HSCROLL:
    {
        SCROLLINFO sci = {sizeof(SCROLLINFO),SIF_RANGE|SIF_POS|SIF_PAGE|SIF_TRACKPOS,0,0,0,0,0};
        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 -= 2;
                break;
            case SB_PAGERIGHT:
                pos += sci.nPage;
                break;
            case SB_LINERIGHT:
                pos += 2;
                break;
            case SB_THUMBTRACK:
                tsTracking = true;
                pos = sci.nTrackPos;
                break;
            case SB_THUMBPOSITION:
                tsTracking = false;
                pos = sci.nTrackPos;
                break;
            case SB_LEFT:
                pos = sci.nMin;
                break;
            case SB_RIGHT:
                pos = sci.nMax;
                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))      //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;

для кода прокрутки и

 __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)
    GetScrollInfo(get_chwnd(IDCW_HARMONICSRESULTSTIMESHIFTSB),SB_CTL,&sci); //gets the scroll info for the scrollbar

if (elapsed_time >= MAX_TIME_WIDTH_MS)                                  //if elapsed time is longer then the max window length
{
    start = _SECSTOMS(sci.nPos);                                            //sets start to end - window length
    end = start+MAX_TIME_WIDTH_MS;                                          //set the end to current (scroll position / scroll max) * latest time -> this should put end relative to the scrollbar

}
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)max - (double)g_h_minY);   //set y-scale to height / (maxVal-minVal)
if(!(g_h_maxY-g_h_minY))
    yScale = 1;
if(!windowLengthMS)
    xScale = 1;
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.

для графа X-Scaling

Другие вопросы по тегам