Форум » GUI » Новая версия Расширенного релиза библиотеки MiniGUI (часть VI ) (продолжение) » Ответить

Новая версия Расширенного релиза библиотеки MiniGUI (часть VI ) (продолжение)

gfilatov: Начало темы находится здесь, а теперь АНОНС * АНОНС * АНОНС * АНОНС * АНОНС Готовится к опубликованию новая сборка №48, которая выйдет в конце недели. Если у Вас есть интересные наработки для включения в новый релиз, то сейчас самое удобное время для их отправки мне Кратко, что нового: - исправление обнаруженных ошибок и неточностей кода; - новый класс HEADERIMAGE для Grid и Browse; - свойство Address в Hyperlink может теперь открывать папку или файл на диске; - добавлен NOTABSTOP класс для Browse; - поддержка пользовательских компонентов (заимствована из оффициального релиза); - расширения и исправления в библиотеках TsBrowse и PropGrid; - обновлены сборки Харбор и HMGS-IDE; - новые и обновленные старые примеры (как обычно ).

Ответов - 300, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 All

kkg: Haz а если сломаем то починим. не нужно ломать, я по ходу нащупал проблему, откатите назад в оригинал и попробуйте [pre2] * ============================================================================ * METHOD TSBrowse:GoRight() Version 9.0 Nov/30/2009 * ============================================================================ METHOD GoRight() CLASS TSBrowse Local nTxtWid, nWidth, nCell, nSkip, lRefresh Local i,j ... lRefresh := ( ::lCanAppend /*.or. ::lIsArr*/ ) While ! ::IsColVisible( ::nCell ) .and. ::nColPos < ::nCell ::nColPos ++ lRefresh := .T. EndDo ::HiliteCell( ::nCell ) If ::aColumns[ ::nCell ]:bGotFocus != Nil .and. ::nOldCell != ::nCell Eval( ::aColumns[ ::nCell ]:bGotFocus, ::nOldCell, ::nCell, Self ) EndIf If ::aColumns[ ::nOldCell ]:bLostFocus != Nil .and. ::nOldCell != ::nCell Eval( ::aColumns[ ::nOldCell ]:bLostFocus, ::nCell, ::nOldCell, Self ) EndIf If lRefresh ::lNoPaint := .F. j :=::nAt i := -1 * ::nRowPos() - 1 if i !=0; ::skip(i) endif for i = 1 to ::nRowCount() ::skip(1) next ::GoPos( j, ::nCell ) // ::Refresh( .F. ) ElseIf ! ::lEditing ::DrawSelect() EndIf ... [/pre2] для GoLeft аналогично нужно проверить :lMoreFields := .T. может он и ненужен будет PS. наверно нужно прокомментировать. это место где при выходе за пределы экрана прорисовывается весь экран (что бы проверить достаточно заремить) меня как и Сержа не волнует скорость, раздражает мерцание текста (двойная прорисовка) чтоб убрать мерцание в зоне Freeze хотел DrawCell расширить до прорисовки таблицы и заодно рисовать не построчно, а по колонкам (по идее один раз открывая объект колонки и меняя только изменяемые значения для строк можно было бы ускорится) по факту все попытки получить массив строк и колонок вызывают DraweLine (что делает бессмысленным саму прорисовку) как и нет смысла рисовать строку курсора DrawSelect всё равно вызовется 2 раза до и после по GotLostFocus. если подскажете как в этом месте получить массив строк,колонок без прорисовки, попробую допилить DrawCell

kkg: Haz писал выше, нужно убрать всю строку целиком, не забыв проинициализировать переменную в . f. в начале метода. Просто не врубаюсь как связаны lCanAppend и goRight. С понедельника по не многу продолжу не нужно, при движении вправо по последней строке и достижения конца, должна произойти вставка строки и для её отображения нужен refresh для движения влево не нужно

SergKis: kkg пишет по факту все попытки получить массив строк и колонок вызывают DraweLine (что делает бессмысленным саму прорисовку) как и нет смысла рисовать строку курсора DrawSelect всё равно вызовется 2 раза до и после по GotLostFocus. Не все так грустно. Можно делать таким образом для начала, схема очень упрощенная - имеем hash с ключом <Recno\Element>+<имя колонки>+<тип вывода (line\select)> в значении {oCol, oCell} - в блоке кода :bOnDrawLine если ключ есть, то выводим :TSDrawCell( oCell, oCol ) из массива и возвращаем .T. - в блоке кода :bTSDrawCell если ключ есть, то вывод уже был, возвращаем .F. иначе на ключ запоминаем массив {oCol, oCell} и возврат .T. - для ключа <Recno\Element> значение берем из[pre2] If xrow > 0 .and. xrow <= Len(ob:aRowPosAtRec) ?? ob:aRowPosAtRec[ xrow ] EndIf[/pre2] - не очень ясно в какой момент очищать hash от ключей уже не используемых, т.е. за пределами данных массива ob:aRowPosAtRec По тексту[pre2] METHOD DrawLine( xRow, lDrawCell ) CLASS TSBrowse ... If ::bOnDrawLine != Nil // свой блок кода для рисования IF ! Empty( Eval( ::bOnDrawLine, Self, xRow ) ) ; RETURN Self ENDIF EndIf ... METHOD DrawSelect( xRow, lDrawCell ) CLASS TSBrowse ... If ::bOnDrawLine != Nil // свой блок кода для рисования IF ! Empty( Eval( ::bOnDrawLine, Self, xRow ) ) ; RETURN Self ENDIF EndIf If ! ::lDrawLine ... В программе ставим :lRowPosAtRec := .T. :bTSDrawCell := {|ob,ocel,ocol| If oc:nDrawType == 0 IF oc:lDrawLine // DrawLine // рисуем, если ключ есть ELSE // DrawSelect // рисуем, если ключ есть ENDIF EndIf Return Nil } :bOnDrawLine := {|ob,xrow| // свой вывод или стандартный Return Nil } [/pre2]


Haz: kkg пишет: при движении вправо по последней строке и достижения конца, должна произойти вставка строки в исходниках не нашел такой фичи , ткните пальцем

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

SergKis: Haz пишет все дело в скорости выборки данных Весь текст h_tbrowse.prg пропитан такими строками[pre2] nSkip := nNewRow - nOldRow If ( ::nRowPos + nSkip ) <= nTotRow .and. ( ::nRowPos + nSkip ) >= 1 ::Skip( nSkip ) ::nRowPos += nSkip ElseIf ! ::lIsDbf ::nAt := nNewRow ElseIf Empty( ::nLogicPos() ) While ::nAt != nNewRow If ::nAt < nNewRow ::Skip( 1 ) Else ::Skip( -1 ) EndIf EndDo ElseIf ! Empty( ::nLogicPos() ) ( cAlias )->( DbSkip( nSkip ) ) ::nAt := ::nLogicPos() Else ( cAlias )->( Eval( ::bGoToPos, nNewRow ) ) ::nAt := ::nLogicPos() EndIf If nNewRow != nOldRow .and. ::nLen > nTotRow .and. nNewRow > nTotRow If ::lIsDbf nRecNo := ( cAlias )->( RecNo() ) ( cAlias )->( DbSkip( nTotRow - ::nRowPos ) ) If ( cAlias )->( EoF() ) Eval( ::bGoBottom ) ::nRowPos := nTotRow While ::nRowPos > 1 .and. ( cAlias )->( RecNo() ) != nRecNo ::Skip( -1 ) ::nRowPos -- EndDo Else ( cAlias )->( DbGoTo( nRecNo ) ) EndIf [/pre2] т.е. постоянно переходим к первой потом от нее к текущей и еще это может происходить не 1 раз, откуда скорость возьмется ? Запоминать только первую строку (позицию) и переходить от нее к тек. не очень проходит, в промежутке может появиться новая строка и все развалится. Можно пробовать танцевать от массива :aRowPosAtRec по содержимому элементов, т.е. сразу переход на первый и потом до тек. xRow и до конца отображать, в принциме аналогичным массивом\hash можно организовать одинарную прорисовку строк, но как то хлопотно по мне

kkg: Haz в исходниках не нашел такой фичи , ткните пальцем в исходниках этого не найти, это жизнь. когда пользователь вводит данные и нажимает Enter уходит вправо, на последней строке и последней колонке рождается новая строка (в ней весь заложенный смысл) хотя согласен, для арабов должно работать и при движении влево, видать не юзают Harbour PS был не прав, то что для нас вправо вниз, а влево ввех, для арабов наоборот, лучше этот вариант вообще не рассматривать, а то запутаемся

kkg: SergKis Можно делать таким образом для начала, схема очень упрощенная в обед нарыл попроще [pre2] m := ::lFirstPaint ::lFirstPaint := nil n := ::lDrawLine ::lDrawLine := .F. j :=::nAt i := -1 * ::nRowPos() - 1 if i !=0; ::skip(i) endif for i = 1 to ::nRowCount() ::skip(1) next ::GoPos( j, ::nCell ) ::lDrawLine := n ::lFirstPaint := m [/pre2] , но к сожалению на несколько дней загрузили работой. если есть интерес могу скинуть промежеточный код DrawCell в DrawRect но он очень "сырой"

SergKis: kkg пишет если есть интерес могу скинуть Нет, не надо, в целом, меня устраивает и то как сейчас работает. Все решается выборкой на local pc или процедурой на сервере (массив recno) и тсб на этот файл с выборкой Скорости хватает, не спорткар, но и не трактор

kkg: SergKis не спорткар, но и не трактор абсолютно согласен, лично у меня ERP системы приучили пользователя, что нажав кнопку получить отчёт, а через 25 мин он получает TimeOut и при этом пользователя обвиняют что он был не прав взяв большой период, то мы пока всё таки спорткар :) (пока данные и отчёты берут от нас)

Haz: SergKis пишет: Весь текст h_tbrowse.prg пропитан такими строками От этих skip никуда не деться. Можно попробовать оптимизировать уменьшив число переходов. Но полностью от цикла не уйти. Сегодня попробовал вариант goLeft goRight делать скролом окна бровса и прорисовывать только появляющуюся колонку. В исходнике кстати есть намек на такой вариант, но автор его бросил ( или не доделал). Из рисков такой логики это наткнуться на ситуацию когда скроллируемое окно не соответствует по записям новой колонке ( удалил или добавил кто то в совместном доступе ). Как обойти не придумал. Получается нужно в объекте держать массив номеров recno текущего отображения бровса..... А если так то и до массива всех записей в окне бровса недалеко. Тогда придется работать страницами. В текущем окне все будет летать , но появятся задержки при формировании новой страницы значениями для показа. Плюс не ясно как ловить изменения по сети. В общем пока только одни мысли, до решения далеко

SergKis: Haz пишет Получается нужно в объекте держать массив номеров recno текущего отображения бровса..... А если так то и до массива всех записей в окне бровса недалеко. Мы с тобой об одном и том же, выше описал на базе ob:aRowPosAtRec именно такую схему, а все записи бровса (страница, можно, конечно и весь) храним по ключу в hash в виде практически готовых объектов oCl, oCell, при выводе только координаты поправляются, т.к. goleft и goright по разному список колонок, помещающихся показывают. От skipov сильно не избавишься, но данные блоков кода, выполненые раз хранятся в oCell

SergKis: Haz пишет Плюс не ясно как ловить изменения по сети. Как обычно pgUp, pgDn и явный Refresh по кнопке или F5, как в IE и т.д. Из рисков такой логики это наткнуться на ситуацию когда скроллируемое окно не соответствует по записям новой колонке ( удалил или добавил кто то в совместном доступе ). Не очень понял, в совместном доступе у нас dbf или результат выборки (структура определена), как то не с руки в такой ситуевине менять структуру - это уже, как бы др. запрос, др. результат\ файл\массив

Haz: Из рисков такой логики это наткнуться на ситуацию когда скроллируемое окно не соответствует по записям новой колонке ( удалил или добавил кто то в совместном доступе ). Сергей я о другом механизме ::GoLeft() и ::GoRight() в КРАЙНИХ позициях Сейчас реализовано через полную перерисовку и передачу фокуса на появившуюся колонку. В методах ::GoUp() и ::GoDown() по другому - там сразу скролл всего окна бровса и ::DrawLine() на "освободившейся" строке. Если ::GoLeft() и ::GoRight() в КРАЙНИХ позициях перевести на эту логику , то скролл окна вправо или влево и ::DrawCol() - которого пока нет )) Функция TSBrwHScroll() в С модуле есть, метод ::TSBrwHScroll прописать не сложно как METHOD TSBrwHScroll( nDir ) INLINE TSBrwHScroll( ::hWnd, nDir, 0, 0) - проверил работает Сложнее сделать новые ::GoLeft2() и ::GoRight2() на основе скрола и тут может возникнуть ситуация когда новый ::DrawCol() нарисует колонку с другим набором записей чем на скроллируемой картинке. Думаю этот вопрос и заставил автора библиотеки бросить эту тему и пойти по пути перерисовки всего бровса

SergKis: Haz пишет тут может возникнуть ситуация когда новый ::DrawCol() нарисует колонку с другим набором записей чем на скроллируемой картинке. Думаю этот вопрос и заставил автора библиотеки бросить эту тему и пойти по пути перерисовки всего бровса Согласен с тобой и автором. Ускорить прорисовку (не ясно насколько) можно попробовать сохраняя oCell в hash для каждой нарисованной записи и ячейки DrawLine, DrawSelect при первом проходе, потом использовать данные hash для повторных рисований. oCol можно исп. из :aColumns, но если активно исп. Cargo колонки, то и oCol желательно сохранять для каждой ячейки вместе с oCell

SergKis: PS новый ::DrawCol() нарисует колонку новый :DrawCol() может опираться на массив записей, заполненный в DrawLine, DrawSelect, т.е. к примеру :aRowPosAtRec тогда рассогласования по списку записей не будет

SergKis: gfilatov2002 Поправить немного надо, Игорь подсказал, где сбивалось содержимое ::aRowPosAtRec[pre2] METHOD GoDown() CLASS TSBrowse ... If lTranspar ::Paint() Else ::nRowPos := nLines ::TSBrwScroll( 1 ) ::Skip( -1 ) ::DrawLine( ::nRowPos - 1 ) // added 10.07.2015 ::Skip( 1 ) IF ::lRowPosAtRec .and. Len( ::aRowPosAtRec ) > 0 hb_ADel( ::aRowPosAtRec, 1, .T. ) AAdd( ::aRowPosAtRec, ::nAt ) ENDIF EndIf ... METHOD GoUp() CLASS TSBrowse ... If ! lTranspar ::lRePaint := .F. ::TSBrwScroll( -1 ) ::Skip( 1 ) ::DrawLine( 2 ) ::Skip( -1 ) IF ::lRowPosAtRec .and. Len( ::aRowPosAtRec ) > 0 ASize( ::aRowPosAtRec, Len( ::aRowPosAtRec ) - 1 ) hb_AIns( ::aRowPosAtRec, 1, ::nAt, .T. ) ENDIF Else ::Paint() EndIf ... [/pre2]

Haz: SergKis пишет: Ускорить прорисовку (не ясно насколько) можно попробовать сохраняя oCell в hash для каждой нарисованной записи и ячейки DrawLine, это хорошая мысль. В принципе логика получается простая, 2 хеша содержат 1 хеш содержит { номер записи => хеш значений записи } 2 хеш значений содержит { имя колонки => значение для показа ( или oCell целиком )} или как вариант хеши держать в каждой ::aColumns, тогда 1 хаш в каждой колонке { RecNo() => значение для показа ( или oCell целиком )} Прирост в скорости будет в разы по сети , год назад тестировал хеширование справочников используемых в ::bData в результате по сети получил прирост раза в 4 ( визуально ) ::Refresh() обнуляет хеш(и), а ::DrawLine() и ::DrawSelect() заполняют если ключа нет или берут из хеша если ключ есть

SergKis: Haz пишет 2 хеша содержат А почему не один ? { Ключ := <:nAt>+<oCol:cName> => <копия oCell> } Если смотреть на DrawLine и DrawSelect, то они отличаются раскраской и вопрос хранить ли DrawSelect или рисовать его всегда. Если хранить то в этом же hash { Ключ := <:nAt>+<oCol:cName>+<oCel:lDrawLine> => <копия oCell> }

Haz: SergKis пишет: А почему не один ? { Ключ := <:nAt>+<oCol:cName> => <копия oCell> } Согласен SergKis пишет: хранить ли DrawSelect или рисовать его всегда. на него можно забить и не хранить



полная версия страницы