Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: CScrollView  (Прочитано 24053 раз)
0 Пользователей и 8 Гостей смотрят эту тему.
Kuzmich
Гость
« : 25-09-2003 07:48 » 

У меня есть SDI приложение, классом клиентской области служит CScrollView. Когда в CScrollView'е строк мало, то скролируется все нормально, когда же количество строк большое 200000 при перемещении движка вид периодически сбрасывается на первую строку, причем если движок дотащить до самой нижней строки, будет показана строка с номером ~8000 движок отпускаю, он прыгает почти в самое начало, т.е. как раз на строку с номером где-то около 8000. Если скролить PgDown и PgUp то все нормально, но это слишком медленно. Как вылечить ?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 25-09-2003 08:27 » 

Проблемма скорее всего не в скроллинге, а в скорости отображения данных. Какие у тебя данные? Текст? Подобная проблемма была с ListView - в итоге пришлость написать свой контролл, так что готовься. Ну а попробовать можно следущее:

каждое передвижение движка - одно сообщение, при 200000 - 200000 сообщений!
можно поставить заглушку и не передавать все сообщения, а самому отлавливать их
и устанавливать текущий в соответствии с инфой из ScrollBar, например с какого-то определённого момента, типа после 200 сообщений (или кратных ему) сразу прыгаем на 200ую строчку и тп
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #2 : 25-09-2003 10:21 » 

CScrollView может не успевать перерисовывать все твои 200000 строк.
Для нормальной шустрой работы надо отрисовывать только видимые стороки плюс пару строк сверху и снизу.
Записан

Megabyte be with you!
Kuzmich
Гость
« Ответ #3 : 25-09-2003 12:07 » 

Цитата

CScrollView может не успевать перерисовывать все твои 200000 строк.
Для нормальной шустрой работы надо отрисовывать только видимые стороки плюс пару строк сверху и снизу.

В данный момент я так и сделал, вывожу только видимые строки.
Только вот самым акуратным решением будет, наверно проецирование файла в память (строки я из него беру). Думаю проблемма с большими файлами должна разрешится, только вот мапировать файлы я неумею. Прежде чем копать хотелось бы узнать: например у меня блок из файла зачитан в память, мне там необходимо что-то поредактировать, при этом размер информации изменится. Теперь вопрос: обратно этот спрецированный блок как запишется в файл и вообще возможно ли это ?
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #4 : 25-09-2003 12:34 » 

Kuzmich, проецирование файлов проблему не решит.
Правильное решение как раз рисовать только то, что видно, а не все 200000 строк.
Записан

Megabyte be with you!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 25-09-2003 12:54 » 

Kuzmich, ты не там копаешь, проблемма с ОТОБРАЖЕНИЕМ инфы, прорисовкой её в графике. Файлы пишутся-читаются ну очень быстро.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #6 : 25-09-2003 12:58 » 

Джон, данные из памяти читаются намного быстрее, чем с винта. Но тут действительно узкое место в отрисовке и его надо оптимизировать.
Записан

Megabyte be with you!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 25-09-2003 13:18 » 

Цитата: Lex
Джон, данные из памяти читаются намного быстрее, чем с винта.


А я обратного и не утверждал
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Kuzmich
Гость
« Ответ #8 : 26-09-2003 09:41 » 

Я же уже написал что у меня отображается ровно столько строк сколько вмещается в экран + 100. Можно ответ по последней части моего вопроса, просто существует необходимость редактировать файл 3Гб.
Записан
Lex
Специалист

ru
Offline Offline

WWW
« Ответ #9 : 26-09-2003 10:12 » 

Kuzmich, +100 это многовато. я обычно запас только на пару строк с каждой стороны делаю. А вот буфер для редактирования +100 строк может и ничего. Как его обратно в файл вставить, это думать надо, сходу ничего умного посоветовать не могу.
Записан

Megabyte be with you!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 26-09-2003 11:15 » 

А в каком виде данные в файле?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Kuzmich
Гость
« Ответ #11 : 29-09-2003 04:09 » 

Цитата: Джон
А в каком виде данные в файле?

Данные в файле - числа от 0 до 255 Отлично
PS. Мануалы нашел, читать седня неохота, если интересно когда разберусь все расскажу.
Записан
Kuzmich
Гость
« Ответ #12 : 02-12-2003 05:20 » 

Вот наткнулся на это "The only limitation here is the logical size of the scrolling window. In Microsoft Windows 95, the limits are ±32,767, and that restricts the number of rows we can display. If the distance between rows is 14 units, we can display only up to 2340 rows." справедливо и для Win2K, это относится к самому первому посту. Как обойти данное ограничение ?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 02-12-2003 08:14 » 

Kuzmich,  мне ща надо систему переустанавливать. Так что несколько часов меня не будет. Если не очень горит, попозже вылезу. А так - почему бы своё окошко не сварганить со скроллом?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Kuzmich
Гость
« Ответ #14 : 02-12-2003 11:27 » 

Цитата: Джон
Kuzmich,  мне ща надо систему переустанавливать. Так что несколько часов меня не будет. Если не очень горит, попозже вылезу. А так - почему бы своё окошко не сварганить со скроллом?

Да время терпит, дата создания топика 25 сентября Улыбаюсь
Я вот туго себе представляю как сварганить свое окошко, видимо придется юзать API   Вот такой я вот
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 02-12-2003 13:17 » 

Вернулся, те устанавливать продолжаю, но браузер уже поставил. Ага

А весь проект у тебя MFC?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Kuzmich
Гость
« Ответ #16 : 03-12-2003 04:33 » 

Цитата: Джон
А весь проект у тебя MFC?

уху
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 03-12-2003 09:46 » 

Тогда без API можно. Ага Хотя MFС только врапер для API, но почему-то (всеобщее заблуждение) народ всегда говорит о них как о разных вещах.

Но ближе к телу, как говорил Мопассан (с) О.Бендер

Создадим класс (пока без непосредственного скроллинга) для показа данных за 5 минут.
Те делаем конечно в API, но воспользуемся прелестями MFC. Ага

1. вставляешь свой класс типа class CMyDataWnd : public CWnd (лучше воспользоваться мастером - wizard)

2. В конструкторе регистрируем класс:

Код:
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetResourceHandle();

    if (!(::GetClassInfo(hInst, _T("CMyDataWnd "), &wndcls)))
    {
        // otherwise we need to register a new class
        wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
        wndcls.lpfnWndProc      = ::DefWindowProc;
        wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
        wndcls.hInstance        = hInst;
        wndcls.hIcon            = NULL;
        wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        wndcls.hbrBackground    = (HBRUSH) (COLOR_WINDOW + 1);
        wndcls.lpszMenuName     = NULL;
        wndcls.lpszClassName    = _T("CMyDataWnd ");

        if (!AfxRegisterClass(&wndcls))
{
            AfxThrowResourceException();
        }
    }

3. Вставляем функции

Код:
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_HSCROLL()
ON_WM_VSCROLL()

4. переписываем Create:
Код:
BOOL CMyDataWnd ::Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )
{
return CWnd::Create(_T("CMyDataWnd "), _T(""), dwStyle, rect, pParentWnd, nID);
}

В принципе всё. Теперь начинается часть с учётом специфики данных. Поэтому приведу общую схему (к сожалению нет времени написать полный туториал, по данному вопросу Жаль , но в принципе это всё "табличные" данные поэтому напишу ключевые функции и пошлю ... к MSDN Ага ):

В OnPaint() "рисуются" данные с учётом инфы из скролбаров, получаем с помощью:
   SCROLLINFO si;
   si.cbSize = sizeof(si);
   GetScrollInfo(SB_HORZ, &si); и GetScrollInfo(SB_VERT, &si);

В OnSize() не забываем переустанавливать (reset) скролбарную инфу - проверка на необходимость скроллинга - опять GetScrollInfo, SetScrollInfo. Делается как для горизонтального так и для вертикального.

Остались последние две функции:
OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
OnНScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

в них надо выкинуть вызов родительской функции, который вставил мастер:
// CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
UINT nSBCode - даёт инфу, что произошло: SB_LINEUP, SB_PAGEDOWN и тд.
Сценарий такой: опрашиваем текущую инфу GetScrollInfo, в зависимости от nSBCode проверяем позицию и граничные условия. Если позиция изменилась, то делаем InvalidateRect().

И всё! "Измеряются удавы (читай - создаются свои контролы) 5х5 любого роста".

Собсно, самая сложная чась - отображение данных в OnPaint, поэтому имеет смысл вставить в класс так-же и отображаемые данные. Во всяком случае считывание данных  - если речь опять идёт о гигабайтных файлах  Ага .

Ну вроде всё для начала. Ошибки и опечатки возможны, бо как тороплюсь шибко...
« Последнее редактирование: 19-11-2007 22:19 от Алексей1153++ » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Kuzmich
Гость
« Ответ #18 : 04-12-2003 04:24 » 

Я тут вот что подумал: MFC - обертка для API. В MFC функции
OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
OnНScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
обращаем внимание на UINT nPos (используется только для SB_THUMBPOSITION и SB_THUMBTRACK, т.е. когда таскают ползунок), размерности в MFC полюбому хватит на туеву хучу строк, тут видимо ограничение в API, хотя надо проверить...
Записан
Kuzmich
Гость
« Ответ #19 : 04-12-2003 06:20 » 

Да вот еще вопрос: SDI приложение на MFC в качестве клиентской области используется CFormView. Как на часть формвиева натянуть CScrollView ?
Я делал так: объявил переменную m_pScroll, в OnInitialUpdate такой код
Код:
	if (!m_pScroll) {
m_pScroll = new CScrollView();
}
компилятор ругается (m_pScroll инициализированна как NULL в конструкторе)
« Последнее редактирование: 19-11-2007 22:22 от Алексей1153++ » Записан
Anonymous
Гость
« Ответ #20 : 04-12-2003 12:07 » 

Kuzmich, я тут галопом по еропам. Подождёшь до завтра? А пока коротко: подобные проблемы всплыают при использовании стандартных МFC контроллов CEdit например ограничено число байт, комбо бокс не может вернуть большое число сторк и тд. Поэтому нада сделать свой контрол. Что ты использовал до сих пор?

Джон
Записан
Kuzmich
Гость
« Ответ #21 : 05-12-2003 04:36 » 

Цитата: Джон
Что ты использовал до сих пор?
На данный момент я использую стандартный CScrollView, в котором вывожу не более 2047 строк, т.к. это шестнадцатиричный редактор, то зачитываю первые 32767 байт, сейчас пытаюсь придумать как сделать что-то типа масштабирования, чтобы при тягании ползунка проматывалось больше строк (клавишами то все работает нормально).
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #22 : 05-12-2003 12:17 » 

Как я понял, очень тебе не хочется своё окошко ваять Ага . Ну ладно давай так разбираться. Ты уже попробовал с :

OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
OnНScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  ?

Потому как там всё и происходит.

У меня подходящего кода под рукой нету чтоб поиграться. Жаль
Так что придётся тебе засучить рукова. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Kuzmich
Гость
« Ответ #23 : 05-12-2003 13:11 » new

эти функции я уже расковырял вдоль и поперек:
pScrollBar = NULL, nSBCode - идентификатор события, а вот nPos как раз и используется при таскании ползунка, когда идентификатор события SB_THUMBPOSITION или SB_THUMBTRACK, пробовал залесть в API этих функций, а там вот что:
int x = GetScrollPos(SB_HORZ); (обратите внимание на тип Я шокирован! )
ну и потом соотвественно
x=nPos; но это мне всеравно ниче не говорит  :oops:
сделал так
Код:
void CHexViewView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{

CString str;
str.Format("%u", nPos);
AfxGetApp()->m_pMainWnd->SetWindowText(str);

CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}
в заголовке скачет до FFFFFFFF, потом видимо переполнение и падает на ноль, время позно башка уже не варит, больше ниче придумать немогу (да и пятница сегодня Отлично )
 :arrow: Всем удачных выходных!
« Последнее редактирование: 19-11-2007 22:24 от Алексей1153++ » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #24 : 05-12-2003 13:59 » 

В понедельник по-любому раньше меня придёшь, так что ща отвечу. Тут как раз и нужно пересчитывать всё.

Попробуй такой код адоптировать к своему проекту:

   SCROLLINFO si;
   si.cbSize = sizeof(si);
   GetScrollInfo(SB_VERT, &si);
   int nNewPos = si.nPos;
   int nOldPos = nNewPos;
   
   switch(nSBCode)
   {
   case SB_BOTTOM:
      nNewPos = si.nMax;   
      break;
   case SB_LINEDOWN:
      nNewPos++;
      if (nNewPos > si.nMax)
         nNewPos = si.nMax;
      break;
   case SB_LINEUP:
      nNewPos--;
      if (nNewPos < si.nMin)
         nNewPos = si.nMin;
      break;
   case SB_PAGEDOWN:
      nNewPos += si.nPage;
      if (nNewPos > si.nMax)
         nNewPos = si.nMax;
      break;
   case SB_PAGEUP:
      nNewPos -= si.nPage;
      if (nNewPos < si.nMin)
         nNewPos = si.nMin;
      break;
   case SB_THUMBPOSITION:
      nNewPos = si.nTrackPos;
      break;
   case SB_THUMBTRACK:
      nNewPos = si.nTrackPos;
      break;
   case SB_TOP:
      nNewPos = si.nMin;
      break;
   }

Тут самое главное

   if (nNewPos != nOldPos)
   {
      if (nSBCode != SB_THUMBPOSITION)
         SetScrollPos(SB_VERT, nNewPos);
      CRect rc;
      GetClientRect(rc);
      InvalidateRect(rc);
   }
   
Это вообще не вызываем!!!!
//   CWnd::OnVScroll(nSBCode, nPos, pScrollBar);

Те вещи из моего "туториала"  Ага  можно применять и не для "своего" окна.
Просто ты сам управляешь параметрами СкролБара
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines