Kuzmich
Гость
|
|
« : 25-09-2003 07:48 » |
|
У меня есть SDI приложение, классом клиентской области служит CScrollView. Когда в CScrollView'е строк мало, то скролируется все нормально, когда же количество строк большое 200000 при перемещении движка вид периодически сбрасывается на первую строку, причем если движок дотащить до самой нижней строки, будет показана строка с номером ~8000 движок отпускаю, он прыгает почти в самое начало, т.е. как раз на строку с номером где-то около 8000. Если скролить PgDown и PgUp то все нормально, но это слишком медленно. Как вылечить ?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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
|
|
« Ответ #2 : 25-09-2003 10:21 » |
|
CScrollView может не успевать перерисовывать все твои 200000 строк. Для нормальной шустрой работы надо отрисовывать только видимые стороки плюс пару строк сверху и снизу.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Kuzmich
Гость
|
|
« Ответ #3 : 25-09-2003 12:07 » |
|
CScrollView может не успевать перерисовывать все твои 200000 строк. Для нормальной шустрой работы надо отрисовывать только видимые стороки плюс пару строк сверху и снизу.
В данный момент я так и сделал, вывожу только видимые строки. Только вот самым акуратным решением будет, наверно проецирование файла в память (строки я из него беру). Думаю проблемма с большими файлами должна разрешится, только вот мапировать файлы я неумею. Прежде чем копать хотелось бы узнать: например у меня блок из файла зачитан в память, мне там необходимо что-то поредактировать, при этом размер информации изменится. Теперь вопрос: обратно этот спрецированный блок как запишется в файл и вообще возможно ли это ?
|
|
|
Записан
|
|
|
|
Lex
|
|
« Ответ #4 : 25-09-2003 12:34 » |
|
Kuzmich, проецирование файлов проблему не решит. Правильное решение как раз рисовать только то, что видно, а не все 200000 строк.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Джон
просто
Администратор
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
|
|
« Ответ #6 : 25-09-2003 12:58 » |
|
Джон, данные из памяти читаются намного быстрее, чем с винта. Но тут действительно узкое место в отрисовке и его надо оптимизировать.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #7 : 25-09-2003 13:18 » |
|
Джон, данные из памяти читаются намного быстрее, чем с винта. А я обратного и не утверждал
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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
|
|
« Ответ #9 : 26-09-2003 10:12 » |
|
Kuzmich, +100 это многовато. я обычно запас только на пару строк с каждой стороны делаю. А вот буфер для редактирования +100 строк может и ничего. Как его обратно в файл вставить, это думать надо, сходу ничего умного посоветовать не могу.
|
|
|
Записан
|
Megabyte be with you!
|
|
|
Джон
просто
Администратор
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, это относится к самому первому посту. Как обойти данное ограничение ?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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? уху
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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 байт, сейчас пытаюсь придумать как сделать что-то типа масштабирования, чтобы при тягании ползунка проматывалось больше строк (клавишами то все работает нормально).
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
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 » |
|
эти функции я уже расковырял вдоль и поперек: 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++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
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."
|
|
|
|