Отправлено: 08.11.21 01:29. Заголовок: Andrey пишет Есть та..
Andrey пишет
цитата:
Есть такой метод ?
Берешь запускаешь hbedit.exe h_tbrowse.prg, делаешь Alt+L, в полученном списке набираешь что хочешь найти, к примеру, "draw" и смотришь содержимое найденных ф-й. Начни смотреть DrawHeaders() и другие. Потратишь несколько минут
Отправлено: 09.11.21 19:15. Заголовок: Andrey пишет: Хоть ..
Andrey пишет:
цитата:
Хоть напиши где этот модуль...
единственный с мидуль в исходниках tsb, функция вроде tsdrawcell . в ней штук 5 вызовов вставки картинки , используется константа SCRAND . Можно поставить SCRCOPY и прозрачность фона и картинки уйдет . Вставь этот модуль на си целиком в свой проект через #pragma и меняй как хочешь. Ps.что означают эти константы в справке микрософт есть.
Если не изменяет память, давно, в какой то версии,
Да , несколько лет назад была именно по причине непрозрачного вывода. На тот момент замена немного сгладила вывод, потом появилась поддержка PNG с прозрачным фоном, может еще что то менялось. На моей памяти этот модуль менялся всего 2 раза, это изменение в скролле с целью убрать лишние прорисовку и эта маска с целью хоть как то получить прозрачность. В большинстве случаев отображение корректное, но бывает маску вывода нужно менять. Это единственное место где идет вывод графики в ячейку и параметр маски туда не передается. Если это требуется, просто включаю этот си модуль в проект и подбираю локально нужное значение. По хорошему эту маску нужно передавать параметром с установкой нужного значения по умолчанию, но подгрузить си модуль проще
Тогда нужно два переключателя, для шапки/подвала/суперхидера/номератора и для ячеек. oBrw:lImgNoCellTransparency := .T. / .F. oBrw:lImgCellTransparency := .T. / .F.
Не нужны переключатели, нужно явное задание маски примерно так oCol:nCellBitmapMask := SCRAND и пр.
а для колонок надо маску для каждого элемента определять oCol:nCellBmpMask oCol:nHeadBmpMask oCol:nFootBmpMask oCol:nSpcHdBmpMask AAdd( ::aSuperHead, { nFromCol, nToCol, uHead, nClrText, nClrBack, l3dLook, hFont, uBitMap, lAdjust, nLineStyle, ; nClrLine, nHAlign, nVAlign, lTransp, nSupHdBmpMask } ) //Super Header Вместо Bmp слово Image использовать в имени (Bmp короче) PS Есть еще void DrawMasked( HDC hDC, HBITMAP hbm, int wRow, int wCol ) с масками, с ней как ? PS2 Значение маски может задаваться блоком кода ?
Отправлено: 10.11.21 21:30. Заголовок: Вот поэтому мне прощ..
цитата:
Вот поэтому мне проще было си модуль прицепить
Понимаю, но вроде и описанные элементы, 33-ий параметр и немного добавить в методах :Draw...() для опр. 33-го параметра. В целом немного. Скажи что в С модуле менял, я туда не лазил
Отправлено: 13.11.21 22:17. Заголовок: Сергей сделал задани..
Сергей сделал задание константы для маски показа картинки. Я прикрутил менюшку для проверки этих масок. Есть несколько интересных масок. Выглядит вот так:
Отправлено: 29.11.21 17:47. Заголовок: Не меняется Height заголовка
Понадобилось длинный заголовок колонки разделить на строки и показать меньшим шрифтом. Но высота заголовка получилась как для стандартного фонта oBrw. И в итоге половина высоты заголовка - пустая. Если поменять Height потом в OnInit - сдвигаются все строки. Нашел ошибку в h_tbrowse.prg: функция STATIC FUNCTION SetHeights( oBrw ) Строка 15787: hFont := iif( hFont == NIL, 0, oBrw:hFont ) -> высоту заголовка по любому расчитывает по стандартному фонту. Самому менять каждый раз - не выход, прошу поменять, хотя бы на такое: hFont := iif( hFont == NIL, 0, hFont )
Отправлено: 01.12.21 19:31. Заголовок: Смотрю код в термина..
Смотрю код в терминалке
hb_cdpSelect( "RU1251" ) use STREET new Browse() use
А можно так же сделать для ТСБ ? Определить параметры по умолчанию и открывать для просмотра базу. А то чтобы просто показать базу, кода приходиться просто немеренно писать. Колонку SELECTOR и ORDKEYNO и ENUMERATOR включать сразу
Отправлено: 01.12.21 23:33. Заголовок: Andrey пишет: use S..
Andrey пишет:
цитата:
use STREET new Browse() use
Все тоже самое
Use street new Sbrowse() Use
Andrey пишет:
цитата:
Колонку SELECTOR и ORDKEYNO и ENUMERATOR включать сразу
Тогда немеряно кода придется писать всем, кому селекторы и нумераторы нафиг не нужны. Не нравится sBrowse(), в чем проблема написать один раз смотровой тсб под себя, оформить в виде библиотеки чтоб не таскать исходник по проектам.
Отправлено: 01.12.21 23:50. Заголовок: Andrey пишет Колонку..
Andrey пишет
цитата:
Колонку SELECTOR и ORDKEYNO и ENUMERATOR включать сразу
Ты же сам всегда хочешь их иметь
DEFINE TBROWSE &cTabl OBJ oBrw CELL ; AT nYBrw, nXBrw ALIAS cAls WIDTH nWBrw HEIGHT nHBrw ; FONT aTsbFont ; // все фонты для таблицы BRUSH aBrush ; // цвет фона под таблицей COLORS aColors ; // все цвета таблицы BACKCOLOR aBackColor ; // фон таблицы - совпадает с фоном окна HEADERS aHeader ; // список шапки колонок таблицы JUSTIFY aAlign ; // список отбивки колонок таблицы COLUMNS aField ; // список наименований колонок таблицы NAMES aNames ; // список полей базы колонок таблицы EDITCOLS aEdit ; // массив данных для редактирования колонок .T.\.F.\Nil>\.T\.F.\NIL FOOTERS aFooter ; // список подвала колонок таблицы SIZES aFSize ; // ширина колонок таблицы LOADFIELDS ; // автоматическое создание столбцов по полям активной базы данных GOTFOCUSSELECT ; EMPTYVALUE ; FIXED ; // активирует функцию двойного курсора на закрепленных столбцах COLNUMBER aNumer ; // виртуальная колонка с нумерацией ENUMERATOR ; // нумерация колонок LOCK ; // автоматическая блокировка записи при вводе в базу данных SELECTOR xSelector ; // первая колонка - селектор записей ON INIT {|ob| myBrwInit( ob ) } // настройки таблицы - смотреть ниже
Поставь в nil все задаваемые параметры в DEFINE ... кроме ON INIT ... и начиная с FONT ... Должен сработать :LoadFields(), возможно надо задать цвет для правильной работы, что то такое
PS. Точно не помню, вроде были правки, но может путаю со своей версией (все NIL у меня работают), а в hmg нет, не стыковка по aHeader := NIL и aField := NIL, т.к. они идут внутри aHeader := {NIL} и aField := {NIL} - это ломало тсб. Надо заполнить их массивами от имен полей. Начни с NIL все, если свалится заполни aHeader := {...} и aField := {...} от полей
Отправлено: 04.12.21 13:36. Заголовок: Ситуация возникает очень редко, но...
Я сформировал динамически TSBrowse и шапка из-за большого к-ва строк заняла почти все место. В итоге - показывается только одна строка из нескольких. Когда я на первой строке нажимаю клавишу Up а потом Down -> то TSBrowse рисует эту первую строку в заголовке таблицы. Нашел место, где можно поправить. Прошу изменить в h_tbrowse.prg строку 7464 ::nRowPos := nLines на -> ::nRowPos := nLines + IIF(nLines==1,1,0)
Отправлено: 09.12.21 14:46. Заголовок: Haz Игорь, ты вроде,..
Haz Игорь, ты вроде, разбирался с VScrollBar, HScrollBar тсб, как их активировать в примере Tsb_2tsb ? На 1-м тсб место под них есть, а отображения нет, перемещение ячейки в фокусе мало что дает. Я не смотрел V\H Bar, т.к. в моей версии (тсб 7.0) два тсб на окне не фурычат. Может подскажешь что ?
Столкнулся со странной ситуацией, когда TSBrowse вылелает по ошибке в строке 9627 Error BASE/1132 Переполнение массива: Ошибочное количество аргументов Args: [1] = A { ... } length: 6 [2] = N 0 Ошибка плавающая и возникает не всегда. Прошу немного изменить код в этой строке, он практически ничего не меняет, но ошибка пропадает: old: ELSEIF nMsg == WM_DESTROY .AND. ! Empty( ::aColumns ) .AND. ::aColumns[ ::nCell ]:oEdit != NIL New: ELSEIF nMsg == WM_DESTROY .AND. ! Empty( ::aColumns ) .AND. ::nCell > 0 .AND. ::aColumns[ ::nCell ]:oEdit != NIL
Отправлено: 10.12.21 14:25. Заголовок: krutoff пишет .AND. ..
krutoff пишет
цитата:
.AND. ::nCell > 0
А как вы получаете :nCell := 0 ? У вас ! Empty( ::aColumns ), т.е. колонки заданы ... У меня не было таких случаев. Даже :nColumn(<имя отсутствует>) дает 1 По мне, правка, мало что дает, в др. местах конструкция, типа, :aColumns[ :nCell ] много где применяется.
Отправлено: 10.12.21 17:28. Заголовок: SergKis пишет: А ка..
SergKis пишет:
цитата:
А как вы получаете :nCell := 0
Сергей, сам не понимаю. CHILD форму создаю динамически, на ней 2 броуза ( два алиаса ) и куча контролов get, editbox и т.д. Причем обработка броузов делает одна и та же функция, но все переменные (алиасы, названия броузов и т.д. ) внутри броуза навесил на oKeyData(). Если в моей форме создается динамически один броуз - все отрабатывает нормально, а если 2 - вылетает. Сделал кучу отладки - и вышел на эту строку. ::nCell в отладке показывает ненулевое значение, oEdit = NiL Причем, если строку разделяю, откусываю подстроку .AND. ::aColumns[ ::nCell ]:oEdit != NIL и прописываю ниже, как отдельное условие IF ::aColumns[ ::nCell ]:oEdit != NIL - все тоже проходит Ок... Кроме этого места нигде не вылетает, может DESTROY цепляет?, но опять же вылет идет уже на 1-м броузе, а не на 2-м.
Отправлено: 10.12.21 17:50. Заголовок: krutoff пишет один ..
krutoff пишет
цитата:
один броуз - все отрабатывает нормально, а если 2 - вылетает.
Попробуйте добавить DO EVENS или DoEvents() в блоки кода, возможно, что то не успевает отработать, прорисовать, т.е. :nCell == 0 не должно быть. Посмотрите завершение Edit, т.к. идет WM_DESTROY при ::aColumns[ ::nCell ]:oEdit != NIL, созданном объекте для edit, т.е. работа в :Edit и его завершение. Может oBrw:IsEdit применить надо ? Например, если открыт TGetBox и даем oBrw:SetFocus(), он закрывается, но :nCell в :Edit и завершающих :Edit..., меняется только для перестановки от oCol:nEditMove - может там что то происходит. Правку, предложенную, сделать не трудно, но :nCell := 0 не должно быть, источник надо бы найти Вместо CHILD MODAL можете попробовать ?
Отправлено: 10.12.21 19:27. Заголовок: krutoff пишет: сам ..
krutoff пишет:
цитата:
сам не понимаю
Кажется мне, что это накладки локальной переменной в каком то из блоков кода. Оба бровса в одной функции создаются скорее всего и на переменных экономите ( к примеру oBrw используется в обоих бровсах и в блоках кода )
Спасибо, MODAL отрабатывает, я это уже проверил, но если модал, то внутренние окна у меня сделаны CHILD ( для seek ) - и тогда не откроются, и надо тоже только модальные, а не ice. DoEvents() и oBrw:IsEdit буду тестировать, спасибо за подсказку, я на основе oBrw строю форму для редактирования и поэтому oBrw:IsEdit думаю, всегда .F.
Кажется мне, что это накладки локальной переменной в каком то из блоков кода.
Спасибо!, мог конечно, и не заметить, но доп.переменные только в классе TBrowse (добавлял __objAddData() ) и oKeyData(). Проверял, проверю еще раз, спасибо. А oBrw -> имени у меня нет, вообще имя oBE - и то, только в параметрах функций. И везде перепроверил на соответствие oBE:cParentWnd и oBE:cControlName. показали два разных Brows'a.
MODAL отрабатывает, я это уже проверил, но если модал, то внутренние окна у меня сделаны CHILD ( для seek ) - и не открываются, а тогда надо тоже только модальные, а не ice
Желательно, перейти на MODAL (мной замечено, что они понадежнее\стабильнее CHILD) + по child можно "неожиданно" перереключаться не туда и завершать окна с вопросом .... Надо добавлять установку родителя перед и восстанавливать после, переменная _hmg_InplaceParentHandle (первое окно modal после MAIN, STANDARD, этого делать не надо).
цитата:
я на основе oBrw строю форму для редактирования
Это как в примере Tsb_DemoMdi - карточка-запись в тсб ( ф-я MdiChildCard() ) ?
цитата:
поэтому oBrw:IsEdit думаю, всегда .F.
Если в oCol:oEdit не NIL, то внешние попытки что то делать, требуют проверки oBrw:IsEdi, например
TAB и SHIFT+TAB при включенной ячейки на :Edit() отработают нормально, а ESCAPE надо проверять и при вкл. :Edit() сначала закрывать, что бы не потерять данные, введенные в др. контролы
Отправлено: 10.12.21 22:37. Заголовок: Опять старая проблем..
Опять старая проблема вылезла, несколько лет назад такое было и не решили как исправить. Глюк показа в левом нижнем углу колонки SELECTOR - при условии что цвет фона ПОДВАЛА последней колонки отличается от основного цвета. Вот так на картинке:
Т.е. цвет фона последней колонки ОРАНЖЕВЫЙ и он перескакивает на SELECTOR - кружок (2). Вот код как это происходит:
// цвета изменить nClrNoDbf := GetSysColor( COLOR_BTNFACE ) oCol := oBrw:GetColumn("ORDKEYNO") oCol:nClrBack := nClrNoDbf
// цвет фона шапки таблицы + подвала списка колонок - (1) FOR nI := oBrw:nColumn("ORDKEYNO") TO Len( oBrw:aColumns ) oCol := oBrw:aColumns[ nI ] cCol := oCol:cName cTyp := oCol:cFieldTyp IF cTyp $ "+=^" // Type: [+] [=] [^] oCol:nClrHeadBack := CLR_ORANGE oCol:nClrFootBack := CLR_ORANGE ENDIF NEXT
Сергей, спасибо за такой детальный совет, буду копать у себя. PS: Помогло DO EVENTS. Нет, не помогло.
SergKis пишет:
цитата:
А как вы получаете :nCell := 0 ?
Нашел ошибку! Да, у меня перед Activate формы с броузом, стоял блок восстанова параметров из INI-файла - там был ноль и тупо присвоило ::nCell := 0 У себя я, конечно, исправил, но, может для присвоения ::nCel сделать метод класса с проверкой?
берешь oBrw:hWnd и по его координатам (getwindowrect() ) рисуешь свое
Спасибо БОЛЬШОЕ !
Вот пример. Когда окно по ценру, то окно wZero по таблице закрывается пиксель в пиксель !!! А если окно сдвинуть, то наступает фигня... Может команда нужна типа SET DIALOGBOX CENTER OF PARENT ? Как исправить ? Вот исходник - Скрытый текст
Никто не копировал объект OBRW TSBrowse? Я сформировал TSBrowse на одной форме со всеми картинками, блоками кода и т.д. и хотел бы скопировать(клонировать) этот объект на другую форму, это возможно?
Отправлено: 14.01.22 14:40. Заголовок: krutoff пишет Я сфор..
krutoff пишет
цитата:
Я сформировал TSBrowse на одной форме со всеми картинками, блоками кода и т.д. и хотел бы скопировать(клонировать) этот объект на другую форму, это возможно?
Чисто технически копировать можно, но колонки это объекты и в скопированном варианте будут ссылки на одни и те же колонки, при lEdit := .T. каждый тсб будет создавать каждый свои :oEdit, хорошо это или плохо, хз. Делал копирование колонок
aColOld := {} FOR EACH oCol IN oBrw:aColumns AADD( aColOld, oCol:Clone() ) NEXT
менял колонки в oBrw:aColumns (добавлял переменные в oCol) и потом восстанавливал обратно из aColOld. Можно создать новый DEFINE TBROWSE ... и методом oBrw:AddColumn( oCol ) перегнать туда массив aColOld, но надо помнить, что в колонках в :bData, через FieldWBlock("FieldName", select(oBrw:cAlias)), заложена область dbf файла. Можно создать базу колонок и потом исп. ее для создания разных тсб (алиас для тсб задается). Примеры: app_oopcolumns и app_ooptsbbox Если исп. _TBrowse(...) с oTsb := oHmgData() ... параметрами, то для др. разных тсб можно использовать параметры настройки одного объекта oTsb, возможно, это неплохой вариант.
Имеется код: DEFINE TBROWSE Br_sch AT h_tlbar,0 ALIAS 'sch' WIDTH w_br HEIGHT h_br BOLD CELLED ... ADD COLUMN TO Br_sch HEADER 'Ввод в'+CRLF+'работу' SIZE w_dtv ; DATA FieldWBlock('dtuse', Select('sch')) ; ALIGN DT_CENTER, DT_CENTER ; PREEDIT {|uVar| oldVal := uVar, IF(Status = 1, .T., .F.)} ; POSTEDIT {|uVar| postMod(uVar,'введен'), Br_sch:DrawSelect()} ; EDITABLE ... Пользователи недовольны тем, как приходится набирать дату, процесс получается довольно протяженный пока выберешь год, потом месяц и наконец дату. В примере d:\MiniGUI\SAMPLES\Advanced\Tsb_Basic дата вводится простыми цифрами, но как это сделать в моём случае я так и не сообразил. Помогите люди добрые.
Отправлено: 08.06.22 18:08. Заголовок: Редактирование логического поля
Наткнулся на непонятную ситуацию
DEFINE TBROWSE ... ... ADD COLUMN TO Br_sch HEADER '' SIZE w_lod ; DATA FieldWBlock('lm1', Select('sch')) ; CHECKBOX ; PREEDIT {|| preMod('lm1')} ; EDITABLE ... У меня редактирование логического поля происходит по уcловию из preMod. Всё работает, когда используется клавиатура, но когда используется мышь то двойной клик по полю хоть и вызывает выполнение функции preMod, её возврат не анализируется и поле lm1 всегда меняет своё значение на противоположное. Такое впечатление, что двойной клик мышью вызывает сначала безусловное редактирование логического поля, а потом обработку из PREEDIT.
Отправлено: 08.06.22 20:47. Заголовок: alex_II пишет PREEDI..
alex_II пишет
цитата:
PREEDIT {|| preMod('lm1')}
Что возвращает эта конструкция и какие значения имеют oCol:lCheckBoxNoReturn .OR. ::lCheckBoxAllReturn ? То о чем спрашиваете тут (метод :Edit(...))Скрытый текст
Отправлено: 09.06.22 10:24. Заголовок: alex_II Если объект..
alex_II Если объект oBrw Public\Private\Static, то PREEDIT {|| oBrw:lCheckBoxAllReturn := preMod('lm1')} ; POSTEDIT {|| oBrw:lCheckBoxAllReturn := .T. } Если oBrw Local, то надо исп. внутренние переменные параметры блоков кода :bPrevEdit и :bPostEdit
Отправлено: 09.06.22 13:01. Заголовок: Редактирование логического поля
SergKis Большое спасибо за помощь, всё заработало корректно Только маленькая поправка: PREEDIT {|| oBrw:lCheckBoxAllReturn := preMod('lm1')} но это уже детали.
Отправлено: 12.07.22 15:04. Заголовок: После того, как я в..
После того, как я включил блок кода ::bFilter, метод GotoRec( nRec, nRowPos ) Игоря Назарова стал работать некорректно. Сам крутил - не получилось. Игорь, если будет возможность - гляньте, плз.
SergKis Сергей, спасибо за ответ. Но в моей ситуации я хотел уйти от DbSetFilter, чтобы Seek работало по всей базе без фильтра (тут мне важны все записи), а через TSBrowse показывать фильтрованые записи.
Отправлено: 12.07.22 17:53. Заголовок: krutoff пишет Но в м..
krutoff пишет
цитата:
Но в моей ситуации я хотел уйти от DbSetFilter, чтобы Seek работало по всей базе без фильтра (тут мне важны все записи),а через TSBrowse показывать фильтрованые записи.
Используя :bFilter вам надо исп. все установки окружения тсб в ручном режиме (:nLen входящих строк в просмотр ...), если глянуть метод DbSkipper( nToSkip ) видно - все делается руками, т.е.
по мне, :GotoRec(...) не имеет к :bFilter никакого отношения. Почему бы после Seek не накапливать RecNo() в объекте контейнере (oRec := oHmgData() ; iif( dbSeek(...), oRec:Set(RecNo(), RecNo()), ) ) или в строке (cRec := "," ; cRec += iif(dbSeek(...), hb_ntos(RecNo())+',', "")) (oRec или cRec private\public). потом ставить :FilterData("oRec:Get(RecNo(), 0) > 0",...) или на строку :FilterData("','+hb_ntos(RecNo())+',' $ cRec", ...) PS Если из RecNo() или ID записей сделать в mem:file.dbf , то тсб простым способом, с SET RELATION ... на осн. базу можно показывать нужные поля, т.е. ваш просмотр
Отправлено: 17.07.22 22:53. Заголовок: krutoff пишет Поправ..
krutoff пишет
цитата:
Поправил метод GotoRec( nRec, nRowPos ) -> включил ::DbSkipper Протестировал. Все работает!
Попробуйте пример Tsb_addrecord cо старым\родным вариантом :Gotorec(...) и вариант с вашими поправками. Родной метод работает после кнопки "AddRecord" (курсор, например, на 3-й строке) правильно, ваш вариант - нет
Отправлено: 04.02.23 09:15. Заголовок: Заметил у себя две б..
Заметил у себя две бяки в ТСБ. 1) Если делаем так в ON INIT окна
oBrw:Enabled( .F. ) // блокировка таблицы ...удаляем столбцы, ставим свои размеры колонок oBrw:Enabled( .T. ) // разблокировка таблицы
То в ТСБ размер колонок и сами колонки восстанавливаются ДО ПЕРВОНАЧАЛЬНЫХ значений. Это так должно быть ? Тогда это не есть хорошо, т.к. построение окна с таблицей занимает время и нужна блокировка всего окна от шаловливых ручек юзера.
2) Использую у себя условную индексацию. Очень удобно. Но на больших базах 1 тыс.записей и выше при смене текущего индекса курсор ТСБ впадает в ступорт, вешает ТСБ. До сих пор лечу это таким кодом после создания условного индекса:
// ------------- добавка обязательна ---------- nTags := ( oBrw_2:cAlias )->( ordCount() ) oBrw_2:aTags := {} FOR nI := 1 TO nTags AAdd( oBrw_2:aTags, { ( ALIAS() )->( ordName( nI ) ), ( ALIAS() )->( ordKey( nI ) ) } ) NEXT oBrw_2:uLastTag := ( ALIAS() )->( ordName( nTags ) ) // без этого индекс слетает
А можно этот код добавить сразу в ТСБ ? Раньше, года 2-3 назад такого не было, ТСБ работал без этого.
Отправлено: 04.02.23 10:22. Заголовок: Andrey пишет Если де..
Andrey пишет
цитата:
Если делаем так в ON INIT окна ...удаляем столбцы, ставим свои размеры колонок
На мой взгляд это неправильно, надо формировать список рабочих колонок на уровне DEFINE TBROWSE ... ...удаляем столбцы, ставим свои размеры колонок END TBROWSE или делать не обрамляя методом :Enabled, т.к., если смотреть метод :Enabled, то увидишь сохранение\восстановление данных колонок
... IF ::lEnabled ::aOldEnabled := { ::hBrush, {}, ::nClrPane, {}, ::nClrLine } FOR nI := 1 TO Len( ::aColumns ) AAdd( ::aOldEnabled[ 2 ], ::aColumns[ nI ]:Clone() ) ::aColumns[ nI ]:SaveColor() NEXT ... IF ! ::lEnabled FOR nI := 1 TO Len( ::aColumns ) ::aColumns[ nI ]:RestColor() SetColor( , ::aColumns[ nI ]:aColors, nI ) NEXT IF ! Empty( ::oPhant ) ::oPhant:RestColor() ENDIF IF HB_ISARRAY( ::aOldEnabled ) .AND. ! Empty( ::aOldEnabled[ 1 ] ) AEval( ::aOldEnabled[ 2 ], {| oc, nc | ::aColumns[ nc ] := oc:Clone() } ) ...
Отправлено: 21.02.23 18:58. Заголовок: Танцы с бубном показ..
Танцы с бубном показали, что использование виртуальной колонки в ТСБ с массивом - ПРОТИВОПОКАЗАНО !!! Т.е. в ТСБ НЕ НАДО использовать COLNUMBER { 1, 20 } - если нужна сортировка по колонке. Не помогают всякие ухищрения типа:
IF oBrw:nColumn("ARRAYNO") > 0 nCol -= 1 ENDIF IF oBrw:lSelector nCol -= 1 ENDIF
Придётся делать как и в 2015 году - свою собственную виртуальную колонку и отслеживать самому нумерацию этой колонки.
Отправлено: 13.03.23 09:25. Заголовок: Всем привет ! Что по..
Всем привет ! Что посоветуете делать для хранения и показа картинки в ТСБ ? Нужно показывать в одной колонке ТСБ картинки из базы. Картинки небольшие BMP или PNG размером 48х48 или 64х64. Есть 2 варианта: загонять все картинки в массив и показывать в ТСБ, или записывать эти картинки в поле базы, а потом уже показывать. Количество записей в базе может быть и 100 записей, а может и 10-20 тыс. Как показывать картинки из массива - знаю:
Отправлено: 13.03.23 13:08. Заголовок: Есть ещё такой приме..
Есть ещё такой пример - MiniGUI\SAMPLES\Advanced\Tsb_BitMaps Но там не совсем понятно, грузятся картинки из файла. А как сделать показ из мемо-поля уже записанную туда картинку ?
Можно попробовать использовать BLOB мемо-поля для хранения картинок
Спасибо ! Сделал пример и загрузил в базу картинки (bmp). Как показать эти картинки в ТСБ - не знаю ? Пример тут - https://cloud.mail.ru/public/FvKA/sFktSMppQ и сделан на базе примера MiniGUI\SAMPLES\Advanced\Tsb_BitMaps Народ, отзовитесь ... Как это можно реализовать ?
Посмотрел примеры, ну там и наворочено... Не знаю как и прикрутить это к ТСБ
Ты притворяешься? Один из самых мелких примеров. Получить картинку из базы, грузнуть в память и получив хендл указать в uBmpCell. В примере картинку берут из базы sql запросом , с этой строки чуть ниже всего одна строчка кода для получения хендла. Удачи.
Отправлено: 14.03.23 10:22. Заголовок: Haz пишет: Ты притв..
Haz пишет:
цитата:
Ты притворяешься?
Да нет. Не совсем ясен будет механизм показа.
Haz пишет:
цитата:
Получить картинку из базы, грузнуть в память и получив хендл указать в uBmpCell
И как это сделать - грузнуть в память ? Если в базе будет 10 тыс. записей, то все картинки нужно будет грузить в память ? А она выдержит столько ? Пример давал выше - там все картинки уже в базе. Если не сложно, покажи пожалуйста на примере, как это сделать. Думаю, что и другим будет интересно.
Отправлено: 14.03.23 10:41. Заголовок: Andrey пишет: Если ..
Andrey пишет:
цитата:
Если в базе будет 10 тыс. записей, то все картинки нужно будет грузить в память
Хендл картинки нужен в момент прорисовки строки.Нет надобности весь миллиард держать в памяти. При желании можно динамичную подкачку сделать и загрузку хендлов в хеш по номеру записи на пару страниц бровса вверх и вниз и отслеживать диапазон по событиям бровса.
Отправлено: 14.03.23 11:16. Заголовок: Andrey пишет: Не со..
Andrey пишет:
цитата:
Не совсем ясен будет механизм показа.
LoadImage() в блоке ubmpCell вопросов же не вызовет с механизмом. И тут тоже самое, вместо LoadImage() функция freeimage которая выдаёт хендл по строке.
Андрей! Плохие новости , через FI не получится в ТСБ скормить хендл картинки, ТСБ не понимает хендл возвращаемый FI_LoadImage...() Не трать время, ищи другой способ
Плохие новости , через FI не получится в ТСБ скормить хендл картинки, ТСБ не понимает хендл возвращаемый FI_LoadImage...() Не трать время, ищи другой способ
Огромное СПАСИБО за то что проверил это. А то я бы ... и нифига бы не понял.
Отправлено: 14.03.23 17:26. Заголовок: В FW есть функция за..
В FW есть функция загрузки битмапа из строки, в MG нет такой. Здесь только LoadImage() из файла или ресурсов. Поэтому решение будет кривым : Из блоба писать в файл , а из Файла LoadImage() Более того, сам код TsBrowse использует именно такой подход. Функция StockBmp() из ТСБ для графических иконок пользует последовательность кода
Отправлено: 15.03.23 11:17. Заголовок: Ещё один вопрос по Т..
Ещё один вопрос по ТСБ. При первом показе ТСБ делаю показ ПУСТОЙ таблицы (ну юзер так привык), как а Экселе. Мешают/раздражают значки логического поля. Как их можно убрать на время ?
For nI := 1 To oBrw:nColCount() oCol := oBrw:aColumns[ nI ] nW := oCol:nWidth oSheet:Columns(nI):ColumnWidth := nW // строка 246 Next
Вылет вот такой:
Error BASE/1004 Метод не экспортирован: COLUMNS Args: [1] = U [2] = N 1 --------------------------------- Stack Trace --------------------------------- Called from COLUMNS(0) Called from TOEXCEL2(246) in module: Form_7Btn.prg Called from (b)MYCONTEXMENUEXPORT(48) in module: Form_7Btn.prg Called from _DOCONTROLEVENTPROCEDURE(0)
Эксель не закрыт, на экране висит. Перезапускать эксель не хочется. Что ещё забыл ?
Там в исходнике METHOD ExcelOle() вот это стоит:
IF bExtern != NIL Eval( bExtern, oSheet, Self ) ENDIF
Отправлено: 18.03.23 16:52. Заголовок: Andrey пишет Эксель ..
Andrey пишет
цитата:
Эксель не закрыт, на экране висит.
Может и висит, но сообщение говорит, что в переменной oSheet нет объекта или он, метод, написан неверно, т.е. метод Columns не найден. Почему сразу не задаешь размеры, при описании колонок Header ? В конце формирования Sheet обычно делают AutoFit для выравнивания размеров колонок к размеру текстов в них
Отправлено: 18.03.23 17:22. Заголовок: Andrey пишет Наверно..
Andrey пишет
цитата:
Наверное моя ширина колонок замениться ?
Не знаю, т.к. никогда не использую Excel Ole. Возможно, получишь все нормально или вставив в длинный текст заменитель CRLF (сколько надо для ширины) получишь нужное. Или Wrap отключи, то же что то получишь
Отправлено: 23.03.23 18:57. Заголовок: Всем привет, терзает..
Всем привет, терзает меня давно один вопрос . При редактировании поля в ТСБ курсор скачет на первую позицию и обратно. На сам процесс не влияет , но не эстетично. Порыл по исходникам и нашел причину : в методе UpStable()
14778: ::GoTop() - вызывает видимый прыжок на начало таблицы с прорисовкой курсора. По коду нет необходимости здесь использовать метод , достаточно будет (::cAlias)->(dbGoTop()) -и быстрее , и без дерганья курсора. Вроде когда то не было такого, или просто не обращал внимания
чуть ниже два вызова ::Skip() - их тоже можно заменить на (::cAlias)->(dbSkip()), но они хоть на экране не мелькают
Меняем все. Просто в твоем сообщении уже увидел замену, подумал что у меня не самая последняя версия. ::GoTop() точно под замену ::Skip() 99% что да. Посмотрел код погонял, у меня все норм на рабочем проекте. Еще на всякий случай завтра с фильтрами проверю и отпишусь. Себе все поменял
Отправлено: 27.03.23 16:40. Заголовок: Haz пишет Вобщем пот..
Haz пишет
цитата:
Вобщем потестировал и с фильтрами и со сменой индекса, все работает при всех заменах
Игорь, а как будет при применении :DbSkipper(n), разве не будет конфликта с (:cAlias)->( dbSkip(n) ) ? Наверно, :Skip(n) метод надо оставить, в нем нет отображений и он не мешает.
Замена ( ::cAlias )->( dbGoTop() ) //!!! 23.03.23 ::GoTop() тоже не совсем корректна, т.к. :GoTop() выполняет свои алгоритмы, например Eval( ::bGotop } ... Ты не пробовал перед "При редактировании поля в ТСБ" сделать ::lPainted := .F., потом вернуть, если надо. Все прорисовки идут при ::lPainted := .T. Может тогда курсор скакать не будет ?
Замена ( ::cAlias )->( dbGoTop() ) //!!! 23.03.23 ::GoTop() тоже не совсем корректна, т.
В этом месте не важно, тут простой подсчет строк с начала и все остальные вычисления только тормозят процесс. :Skip() можно и оставить, , но при обычном использовании тоже не критично, в коде полно и функций dbSkip() и методов :Skip() Завтра посмотрю на :dbSkipper() уверен не повлияет.
Есть где нибудь в инете актуальные исходники MG ? А то не всегда комп под рукой и по телефону не посмотреть
Отправлено: 27.03.23 21:45. Заголовок: SergKis пишет: тут ..
SergKis пишет:
цитата:
тут "Download"
Про тут я знаю, мне не скачивать , и просматривать исходник хотелось бы с браузера ( без скачивания и установки) . в последнее время часто езжу на общественном транспорте и есть время полистать в телефоне. Можно конечно и с компа папку MG в телефон кинуть и не забывать обновлять.
Игорь, а как будет при применении :DbSkipper(n), разве не будет конфликта с (:cAlias)->( dbSkip(n) ) ? Наверно, :Skip(n) метод надо оставить, в нем нет отображений и он не мешает.
Сергей , ты прав для корректной отработки ::bFilter (если он есть ) ::Skip() тогда лучше оставить
цитата:
Замена ( ::cAlias )->( dbGoTop() ) //!!! 23.03.23 ::GoTop() тоже не совсем корректна, т.к. :GoTop() выполняет свои алгоритмы, например Eval( ::bGotop } ...
в этом месте Eval( ::bGotop } ... и пр. точно не нужны , тут по коду просто подсчет строк, но есть но ... при ( ::cAlias )->( dbGoTop() ) опять таки не учитывается ::bFilter , значит тоже нельзя просто замкнутый круг получается.
цитата:
Ты не пробовал перед "При редактировании поля в ТСБ" сделать ::lPainted := .F., потом вернуть, если надо. Все прорисовки идут при ::lPainted := .T. Может тогда курсор скакать не будет ?
Да , это скорее всего решит проблему , но это нагружает код разработчика для исправления косяка в MG может в самом ::Upstable() перед ::GoTop() поставить ::lPainted := .F. , а после ::lPainted := .T. Попробовал, решает вопрос с прыганьем и позволяет корректно выполнить функционал ::bFilter
Отправлено: 27.03.23 22:55. Заголовок: Haz пишет Попробовал..
Haz пишет
цитата:
Попробовал, решает вопрос с прыганьем и позволяет корректно выполнить функционал
Осталось решить эти строки нужны ?
METHOD UpStable() CLASS TSBrowse ... IF ::lPainted ::Refresh( iif( ::nLen < nRows, .T., .F. ) ) ENDIF
Посмотрел код на :UpStable() и :Refresh() после него. Во многих местах этот метод есть, но небольшой процент вероятности, что где то его не хватает есть. Думаю "поставить ::lPainted := .F. , а после ::lPainted := .T." хорошая мысль, т.к. выкинется, возможно, лишний :Refresh(), будет меньше мелькания
Просто так не выкинуть. В самом методе upstable , можно GoTop() обрамить выключением и включёнием lPainted и это уберёт видимость прыжка. Дальше по логике метода вызывается перерисовка если есть несоответствие строк . Это в принципе правильно. Метод проверяет строки сверху и снизу окна бровса. Без перерисовки тут не обойтись. Вызываемые далее в исходнике рефрешы после upstable не всегда учитывают что нужна полная перерисовка. Тут скорее путь такой, upstable всегда перерисовывает, а код исходников чистить от лишних рефрешей после upstable. Это уберёт и дерганье и повысит скорость
Отправлено: 28.03.23 13:00. Заголовок: Haz пишет Тут скорее..
Haz пишет
цитата:
Тут скорее путь такой, upstable всегда перерисовывает, а код исходников чистить от лишних рефрешей после upstable.
Это повторение ситуации, :Upstable() должен давать сообщение, что нужна прорисовка, но сам делать не должен. Прорисовка нужна вне :UpStable(), а почистить код и оптимизировать :Refresh() идея хорошая, но трудно выполнимая, слишком много условий и вариантов, которые и тестировать надо. Вынести на какой нибудь счетчик потребности :Refresh() (заменив вызовы текущие) и если он > 0 и new переменная .T. - делать :Refresh() и счетчик в 0. Вынести бы :Refresh() на событие, но слишком разбросан он по текстам PS Я стараюсь делать так, например, после (Edit) изменений в нескольких строках Row
oCol:bPostEdit := {|xv,ob| ... IF xv != oc:xOldEditValue DO EVENTS ; _wPost(55, ob:cParentWnd, ob) ENDIF Return Nil }
(This.Object):Event(55, {|ow,ky,ob| DoEvents(), ky := ow, ob:Refresh(), DoEvents() })
Использую событие всегда по потребности, используя _wPost(55...), _wSend(55...) и для др. окна с тсб тоже (работая на тек. окне). Такая метода с постановкой :lPainted := .T.\.F., думаю будет работать
Отправлено: 28.03.23 13:17. Заголовок: SergKis пишет: Это ..
SergKis пишет:
цитата:
Это повторение ситуации, :Upstable() должен давать сообщение,
Да , согласен , поэтому и написал что просто так не выкинуть. Просто процитирую твои слова, т.к. полностью согласен :Upstable() должен выполнять все внутренние установки и выставлять флаг для :Refresh(), сам вызывать :Refresh() не должен при этом флаг для рефреш имеет признаки 1) с очисткой , 2) без очистки Именно так работает метод :Refresh() 1. с очисткой - сначала очищается текущее окно , а потом по чистенькому прорисовка. Это вызывает моргание но без него не обойтись если после фильтра строк стало меньше чем было. 2. без очистки - рисует поверх моргания нет
Может имеет смысл пересмотреть метод и сделать третий вариант 3. перерисовка полностью без очистки. Суть в том , что если :nLen < :nRowCount то до :nLen рисуем поверх, а дальше просто рисуем пустые строки ( с сеткой или без ). Это визуально добавит плавности.
Отправлено: 28.03.23 15:10. Заголовок: Haz пишет Может имее..
Haz пишет
цитата:
Может имеет смысл пересмотреть метод и сделать третий вариант
Игорь, я за "любой кипишь", если он на пользу. Не уверен, что получится реализовать, т.к. разбросано сильно по текстам и режимам, которые не применял никогда. Тут бы получить вариант простенький, счетчик :Refresh() (знать сколько раз подряд вызывался в том или ином режиме), отключить\включить :Refresh() (кроме, может быть, перемещения, PgUp, PgDn, Up, Dn, ...), что бы самому управлять :Refresh() в др. случаях, с очисткой или нет это уже техника, параметры есть. А "третий вариант" это событие 55 (выше), оно может быть простым или более сложным, но оно работает когда мне надо, а не тсб за меня, что то пытается изобразить. Такое событие не сунешь в тсб, т.к. оно внешнее по отношению к тсб и может работать как с кнопок, мышек, ..., других окон и даже др. процесса. Такие мысли
Отправлено: 28.03.23 17:51. Заголовок: Haz пишет Ну как мет..
Haz пишет
цитата:
Ну как метод сделать можно, черновик попробовал , мелькает меньше ( только на DrawSelect )
На DrawSelect не должна моргать, там же ничего нет, после всех DrawLine одна строка поверх с др. атрибутами цвета ... и все "Дойдешь до кондиции" выложи на посмотреть
Отправлено: 28.03.23 19:01. Заголовок: SergKis пишет: На D..
SergKis пишет:
цитата:
На DrawSelect не должна моргать
Должна, сначала рисуются все строки drawline а потом drawselect и эта прорисовка со стандарта на селект видна на плохой сети. Но это решаемо алгоритмом
Сделал контрольный, чуть косметики и выложу. Это не совсем событие 55, там у тебя Refresh без очистки. Это значит , что при установке фильтра и не полном заполнении окна бровса, строки из фильтра перерисуются, а остальные остаются мусором на экране. В данном случае нужна очистка, но ее видно мельканием, т.к. сначала полностью очищается окно, а потом все рисуем заново Чисто теоретически , при неполном заполнении окна бровса с очисткой работает быстрее ( меньше строк рисовать ) а с дорисовкой плавнее и плюс бонусом опционально сетка на незанятой область бровса ( любым цветом ). Я сделал пример не с очисткой , а с дорисовкой всего окна бровса
Отправлено: 29.03.23 12:42. Заголовок: Haz пишет Это значит..
Haz пишет
цитата:
Это значит , что при установке фильтра и не полном заполнении окна бровса, строки из фильтра перерисуются, а остальные остаются мусором на экране.
Ты не понял, событие 55 может быть разным, простым, более сложным, Например такое :Event(55, {|ow,ky,ob| DoEvents(), ky := ow, ob:Refresh(ob:nLen < ob:nRowCount(), .T.), DoEvents() }) то, что было ранее это из примера, где фиксированное кол-во строк в тсб, который служит для установки\снятия галочек как в RedioGroup и вызывается в :bPostEdit, т.е. давая завершить работе методов :Edit... и прорисовкой тек. строки и только потом сработает 55 событие, которое перерисует все строки, для показа состояния галочек др. строк. PS И если откл. внутреннее исп. :Refresh() (в :UpStable или др. варанты), то 55 событие позволяет мне управлять когда перепоказывать окно тсб
Отправлено: 29.03.23 12:52. Заголовок: SergKis пишет: Ты н..
SergKis пишет:
цитата:
Ты не понял, событие 55 может быть разным, простым, более сложным,
Да понял я, вопрос в том что есть два варианта рефреш. Первый не чистит мусор, второй моргает. А так да , согласен на 55 можно понаписать свой h_tbrowse целиком
Отправлено: 29.03.23 13:05. Заголовок: Haz пишет вопрос в т..
Haz пишет
цитата:
вопрос в том что есть два варианта рефреш. Первый не чистит мусор, второй моргает
Написанный выше дает только один вариант, на все случаи и :nLen ставит и чистит когда надо, по мне вопроса тут нет. То что моргает, так это уровень C, туда не лезем, т.к. DoubleBuffer не будет реализован. Т.е. что есть, то и используем
Отправлено: 04.04.23 18:20. Заголовок: А иконку в контекстн..
А иконку в контекстное меню можно сразу выводить ? Без всякой замены на лету ? А то приходилось делать в два этапа, вывести пустой ресурс, а потом менять его на иконку. Сложно это, давно перестал делать.
Отправлено: 05.04.23 12:16. Заголовок: aColors, есть вопрсы
Столкнулся с несоответствием в описании структуры массива aColors. Использовал superheader и захотел поменять цвета через SetColor, в описании это 16 и 17 элементы массива, а на деле оказалось надо указывать 15 и 16 элемент. Глянул в TSBROWSE.CH. там тоже 16 и 17, непонятно Использую HMG Extended Edition version 22.12 (Update 2).
Отправлено: 13.04.23 15:04. Заголовок: Если я ставлю фильтр..
Если я ставлю фильтр на базу oBrw:FilterData( cFilter ), то у меня при перемещении по базе на линии ВЕРТИКАЛЬНОГО скролинга бегунок неправильно отображается. Как починить его ?
Отправлено: 14.04.23 08:31. Заголовок: Andrey пишет: Как п..
Andrey пишет:
цитата:
Как починить его ?
разбираться со значением :bLogicLen после вызова фильтра. Там устанавливается конкретное значение , отличное от изначального в :setdbf()
Ошибка. bLogicLen. не учтена работа в шаред режиме при которой коллеги могут внести правки в базу , влияющие на фильтр , а так же удаление и добавление новых записей и то что фильтр можно поставить вне бровса. И при значении :bLogicLen == {|| 1000} после последнего вызова метода получим ерунду. А так же, не применимо для логики ads в целом , с его AOF фильтрами.
Собираю коллекцию показа ресурсов в ТСБ ! Не могу понять как можно загрузить bmp, png, jpg из внешней dll + с изменением размеров ? Т.е. картинки в dll могут быть любых размеров, а мне в ТСБ нужно выводить нужный размер, допустим 90х90. С иконками разобрался, их можно загружать в ТСБ любых размеров.
Странно и непонятно. Такое впечатление что берется старая TsbViewer.lib Так как в новой TsbViewer.lib MAIN окно включено по умолчанию. Пересобрал заново TsbViewer.lib - поправил пути в tsbviewer.hbp, т.к. я делаю свой путь для каждой версии МиниГуи
Отправлено: 16.11.23 08:57. Заголовок: Вот ещё пример ТСБ в..
Вот ещё пример ТСБ в папке \MiniGUI-23.10\SAMPLES\Advanced\APP_OOPTEMPLATE Окно и таблица строится из ини-файла Demo_timer.cfg Смотреть секцию - [ТАБЛИЦЯ_БД_АБОНЕНТИ]
Правая кнопка мышки на ячейке вызывает меню для работы с буфером: Копировать в буфер/Вставить из буфера/Удалить в зависимости от языка.
Предусмотрен вызов меню по клику мышки на суперхидере. Повторное открытие базы в другой кодировке на "лету", без закрытия таблицы.
Отправлено: 01.01.24 15:05. Заголовок: Редактирование Memo поля как 'C'
Всех с Новым Годом! Прошу в h_tbrowse.prg сделать изменения в строке 5266 IF ::lIsArr .AND. oCol:cDataType # ValType( uValue ) // GF 15/07/2009 cType := ValType( uValue ) oCol:cDataType := cType ENDIF В моем случае, если cDataType = 'M', то этот блок переводит cDataType в 'C' и дальше не отрабатывает строка 5451 ELSEIF ( cType == "C" .AND. Chr( 13 ) $ uValue ) .OR. cType == "M" .OR. oCol:lEditBox и редактирование переводит на GetBox. Я, конечно, вручную поставил oCol:lEditBox := .T., но хотелось бы автоматически.
dbAppend() REPLACE CODE WITH 'LTU', NAME WITH 'Lithuania', RESIDENTS WITH 3369600 dbAppend() REPLACE CODE WITH 'USA', NAME WITH 'United States of America', RESIDENTS WITH 305397000 dbAppend() REPLACE CODE WITH 'POR', NAME WITH 'Portugal', RESIDENTS WITH 10617600 dbAppend() REPLACE CODE WITH 'POL', NAME WITH 'Poland', RESIDENTS WITH 38115967 dbAppend() REPLACE CODE WITH 'AUS', NAME WITH 'Australia', RESIDENTS WITH 21446187 dbAppend() REPLACE CODE WITH 'FRA', NAME WITH 'France', RESIDENTS WITH 64473140 dbAppend() REPLACE CODE WITH 'RUS', NAME WITH 'Russia', RESIDENTS WITH 141900000 USE
RETURN .T. // editable browse (return .F. is readonly)
// ----------------------------------- FUNCTION CountChildWindows // ----------------------------------- LOCAL i, nFormCount := Len ( _HMG_aFormHandles ), nCnt := 0
FOR i := 1 TO nFormCount IF _HMG_aFormType[ i ] <> "A" IF _IsWindowDefined ( _HMG_aFormNames[ i ] ) nCnt++ ENDIF ENDIF NEXT
Отправлено: 03.01.24 12:37. Заголовок: Динамическая высота строк TSBrowse
Я так понимаю, что динамическая высота строк TSBrowse не предусмотрена? Бывает очень длинная строка и ячейка ее не показывает, обрезает, даже если показывать через CRLF.
Отправлено: 03.01.24 14:20. Заголовок: krutoff пишет Я так ..
krutoff пишет
цитата:
Я так понимаю, что динамическая высота строк TSBrowse не предусмотрена?
есть немного с memo полями, переменные смотрите в коде
DATA nMemoHE // memo sizes on edit and view mode DATA nMemoWE // Height in lines and Width in pixels DATA nMemoHV // default: 3 lines height and 200 pixels width DATA nMemoWV и STATIC FUNCTION SetHeights( oBrw ) ... // Now for cells ... IF Empty( oBrw:nMemoHV ) IF At( Chr( 13 ), cHeading ) > 0 oBrw:nMemoHV := Len( hb_ATokens( cHeading, Chr( 13 ) ) ) ENDIF ENDIF DEFAULT oBrw:nMemoHV := 2
Предусмотреть динамическую высоту автоматом, по мне, трудно (тип С), т.к. каждому надо по разному от ширины колонки. Например, я часто использую схему ширина не > 45 символов и на tooltip ячейки вешаю полное содержимое, что бы получить больше колонок в просмотре и не исп. для поля С вставки CRLF для вертикального разбиения показа ячейки, т.к. это съедает строки в просмотре и в др. строках будут пустоты в ячейки, текст короче. PS Проще выделить место на окне показа или отдельное окно, в котором организовать показ длинных полей, при перемешении по тсб в Label-ах, GetBox-ах ReadOnly или EditBox ReadOnly или тсб с вертикальной раскладеой, как по полям одной записи в SBrowse. Ситуация с отдельным окном может оказаться предпочтительней, т.к. вызывать просмотр можно по кнопке или R\L клику
Отправлено: 09.04.24 19:03. Заголовок: Есть длинная строка ..
Есть длинная строка адреса. В ТСБ естественно будет показываться только то кол-во символов, которые заданы в picture. Допустим 30 символов. А можно сделать чтобы показывало последние 30 символов из строки в колонке ?
Отправлено: 12.04.24 13:52. Заголовок: Не пойму почему
ТСБ работает с массивом ... s1 := 0 aKv - массив [4,11] ... Br:SetArrayTo(aKv,,aZg,aWi,aFoot,aPict,aAlgn)
Хочу при старте заполнить подвал второй колонки, в этой колонке цифры и надо подсчитать сумму Делаю так: Br:aColumns[2]:cFooting := {|| aEval(Br:aArray, {|aVal,nElm| s1 += aVal[2]}), str(s1,10,2)} но aEval почему-то проходит по массиву 4 раза, т.е сумма получается в четыре заза больше.
Отправлено: 12.04.24 14:33. Заголовок: alex_II Тсб - это п..
alex_II Тсб - это просто рисование данных в таблице по настройке, ничего не считает. В данном случае прошло 4-е прохода прорисовки. Надо посчитать и записать в нужные колонки :cFooting := cValToChar(...) или в переменные, поля dbf, ... и в :cFooting := блок кода для получения строки из них (для каждой колонки), тогда по каким то действиям меняете значения данных для этих блоков кода и делаете переотображение тсб всех строк oBrw:Refresh(...), курсора oBrw:DrawSelect(), oBrw:DrawFooters()
Отправлено: 12.04.24 17:30. Заголовок: Я извиняюсь, но ниче..
Я извиняюсь, но ничего не понял. Я описал ситуацию, которая происходит при старте программы, когда еще никаких действий не производилось. ТСБ прорисовывает таблицу по данным из массива и я пытаюсь заполнить подвал до всех действий. Тут вопрос думаю не к ТСБ, а а к блоку кода, тем более он у меня вложенный.
alex_II 1. Тсб - это просто рисование данных в таблице по настройке, ничего не считает. 2. Выносите свой блок кода, подсчета итоговых сумм, из тсб отдельно 3. Создаете массив для показа в тсб 4. Запускаете подсчет сумм по колонкам массива, т.е. исполняете свой блок кода, итоги запомнили 5. DEFINE TBROWSE ... => в колонки переносите итоги oCol:cFooting := <итоги из массива, как строка> END TBROWSE 6. Тсб нарисуется вместе с итогами (за 4-ре раза, потому в вашей ситуации учетверение сумм, так не надо делать) Если делаем правку строк с суммами в строках массива тсб :lEdit := .T., то итоги надо пересчитать, т.е. запускаем блок кода подсчета сумм п.2, получив новые итоги, заносим их результаты в нужные oCol:cFooting и делаем oBrw:DrawFooters() - перерисовать подвал. Если, например, у вас есть массив итогов aItig, то можно исп. блок кода в oCol:cFooting := {|| hb_ntos(aItog[3]) } и так во все колонки. Блок кода будет обеспечивать данные дли Footers по выполнению oBrw:DrawFooters() PS Примеры APP_OOPREPORT смотрите, там есть итоги в массивах, создаваемых по кнопкам
Отправлено: 18.04.24 20:21. Заголовок: После редактирования линия выше ячейки затирается!
Пример: ...\MiniGUI\SAMPLES\Advanced\Tsb_array_2\demo5.prg Сперва думал, что сам как-то повлиял своими настройками, убил на это день. У меня белый фон и вид получается удручающий
Нужен именно такой вид, максимально приближенный к распечатке. Там. где была корректировка, сетка нарушается. В 21 году вроде эта тема обсуждалась, но с ходу не нашел когда.
В методе Edit() координаты окна редактирования рассчитываются не пойми как и для каждого контрола отдельно. Погрешность выравнивается подгонкой через массив из 4 значений. Выхода из положения два 1 править edit() 2 перед редактированием задавать сдвиги в массиве корректировки координат окна редактирования. Высота строки бровса тут не при чем т ее изменение не поможет
Отправлено: 19.04.24 13:00. Заголовок: alex_II пишет Там. г..
alex_II пишет
цитата:
Там. где была корректировка, сетка нарушается
oBrw:DrawSelect(), oBrw:Refresh() перерисовывают строку курсора и все окно, не понимаю проблему совсем Не нравится oBrw:aEditCellAdjust, положите на ячейку[и] modal окно в размеры или больше со своим вводом
цитата:
Править метод Edit() нет ни желания ни возможности, много работы
Метод Edit править нет нужды, даже мыслей на это нет, а сделать свой ввод (можно даже красивый) один раз и использовать везде ЭТО и есть работа над проектом (hmg это продукт как есть и использование его вами это ваш риск ...)
Править метод Edit() нет ни желания ни возможности, много работы. Печалька.
Там править ничего не надо, нужно просто подменить. У себя , когда лень менять исходники делаю замену Скрытый текст
После определения бровса ( DEFINE BROWSE .. OBJ oBrw ...) подменяю методы на свои и нет нужды каждый раз править oBrw := __objModMethod( oBrw, 'edit', @edit() ) oBrw := __objModMethod( oBrw, 'GetCellinfo', @Cell() )
Отправлено: 19.04.24 15:48. Заголовок: Haz пишет У себя , ..
Haz пишет
цитата:
У себя , когда лень менять исходники делаю замену
А мне всегда лень это делать, обхожусь вариантом modal окон как в примере Tsb_addrecord_3 ф-я STATIC FUNCTION Add_Rec( oBrw ) только для всех вариантов ведения (Add, Add+Copy, Del, Edit) и окно может быть как для одной Cell так и нескольких, а GETBOX-ы иметь встроенные кнопки для ACTION и ACTION2
Отправлено: 19.04.24 15:56. Заголовок: SergKis пишет: А мн..
SergKis пишет:
цитата:
А мне всегда лень это делать, обхожусь вариантом modal окон как в примере Tsb_addrecord_3 ф-я STATIC FUNCTION Add_Rec( oBrw ) только для всех вариантов ведения (Add, Add+Copy, Del, Edit) и окно может быть как для одной Cell так и нескольких, а GETBOX-ы иметь встроенные кнопки для ACTION и ACTION2
Сергей , привет. Согласен, с твоей подачи тоже использую MODAL, подмены метода использую для быстрого моделирования. ну чтоб не совсем стыдно было черновик показывать Потом можно бесконечно наводить красоту.
Схема расчёта итогов на лету, после установки фильтра на базу. Может кому будет интересно. Т.е. набираем буквы в поиске, и получаем итого в подвале таблицы. Спасибо ОГРОМНОЕ Сергею. Скрытый текст
* Построение таблицы справочника/поиск по буквам и подсчёт итогов "на лету" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1) LOCAL aFldSum := {"F3", "F4"} // поля базы числовые !!! ... DbSelectArea(cAls) aItogo := Itogo_Dbf(aFldSum, Alias(), .T.) // расчёт итого по базе
DEFINE WINDOW Report AT .... ; ON INIT _wPost( 0) ; ON RELEASE _wSend(90) ... This.Cargo := oHmgData() ; owc := This.Cargo // для окна создаем объект без переменных (условно пустой) owc:aFldSum := aFldSum // для подвала таблицы - итого owc:nCount := aItogo[1] owc:aItogo := aItogo[2] owc:aReturn := {} // для возврата выбранных значений ... DEFINE TBROWSE oRpt OBJ oRpt AT nY, nX ALIAS cAls .... ; ... ; ON INIT {|ob| myTsbInit( ob ) } // настройки таблицы - смотреть ниже
myTsbTune(oRpt) // настроить myTsbColor(oRpt,oBrw) // цвета изменить myTsbKeys(oRpt) // обработка клавиш // не должно быть нигде, кроме события ! myTsbItogo() // показ подвала
END TBROWSE ON END {|ob| ob:SetNoHoles(), ob:SetFocus() }
This.Cargo:oRpt := oRpt // положить объект oRpt (таблицу) на окно
// GetBox в подвале таблицы - можно сделать и через меню @ nY-nG, nX+nG GETBOX GB_Find OBJ oGet WIDTH nW-nG HEIGHT nH VALUE space(30) ; PICTURE "@K" NOTABSTOP INVISIBLE ; ON LOSTFOCUS {|| This.Cargo := .F., This.Value := space(30), This.Hide } ; ON CHANGE {|| iif( Empty( This.Cargo ), NIL, Search_TSB( ThisWindow.Object, .T. ) ) } ; ON INIT {|| This.Cargo := .T. }
This.Cargo:oGet := oGet This.Cargo:cGet := "GB_Find" // запомнить для дальнейшего использования
/////////////////////////////////// o := This.Object o:Event( 0, {|ow| _wPost(22, ow) } ) // инициализация после построения окна
DO EVENTS GO TOP DO WHILE ! EOF() nCnt++ DO EVENTS FOR EACH nPos IN aPos IF nPos > 0 .and. HB_ISNUMERIC( nSum := FieldGet( nPos ) ) aItg[ hb_EnumIndex(nPos) ] += nSum ENDIF NEXT SKIP ENDDO
DbGoTo( nRec ) ; DO EVENTS
IF !Empty(aWait) ; WaitWindow() ENDIF
dbSelectArea( nOld ) ; DO EVENTS
RETURN { nCnt, aItg }
4) STATIC FUNCTION myTsbItogo( oWnd ) // подвал - ТОЛЬКО показ LOCAL aItg := oWnd:Cargo:aItogo Local oRpt := oWnd:Cargo:oRpt
Открываю базу, устанавливаю индекс, делаю SCOPE на базу. После правки (ENTER) ячейки - теряется SCOPE... Почему ? Что там хитрого сделано после правки ячейки ?
Это я помню и делал с этим. В новом примере, который сбоил - использовал ТОЛЬКО один индекс со SCOPE Из-за этого и не тащил oBrw:uLastTag := (oBrw:cAlias)->( OrdName(nIndx) )
Отправлено: 07.05.24 13:33. Заголовок: Когда делаю oBrw:Ena..
Когда делаю oBrw:Enabled(.F.) остаётся не закрашенная колонка. Это можно исправить в исходниках ? Или дайте как это можно сделать ручками, пробовал сам, у меня не получилось.
Отправлено: 07.05.24 16:23. Заголовок: Andrey пишет В новом..
Andrey пишет
цитата:
В новом примере, который сбоил - использовал ТОЛЬКО один индекс со SCOPE Из-за этого и не тащил oBrw:uLastTag := (oBrw:cAlias)->( OrdName(nIndx) )
Его не надо тащить в такой ситуации, надо ставить сразу нужный тэг индекса, т.е. dbSelectArea(cAls) OrdSetFocus("MY_TAG") ... DEFINE TBROWSE ... или oBrw := _TBrowse(...) Далее можно, если надо, этот и другие тэги закреплять за колонками для DublClick-а по Header колонки и переключения тэгов показа тсб. oBrw:uLastTag самому надо вести при самостоятельном переключении тэгов, не используя механизм тсб и метод oBrw:SetOrder( nColumn )
Отправлено: 02.06.24 14:19. Заголовок: Как для старой верси..
Как для старой версии МиниГуи 23.09.2 сделать удаление BRUSH для ТСБ ? На новую версию МиниГуи не могу перейти. У себя в большой системе везде при закрытии окна с ТСБ делаю так:
// ручное удаление объекта oBrw := ow:Cargo:oBrw IF hb_IsObject(oBrw) DeleteObject( oBrw:hBrush ) // не работает oBrw:hBrush := NIL DoEvents() oBrw:Destroy() ENDIF
В новой сборке МиниГуи 24.05 есть папка \SAMPLES\Advanced\Tsb_oHmgData\
Три примера работы с объектом Tsbrowse (ТСБ): 1) demo.prg - на базе функции _TBrowse(...) с использованием oHmgData() 2) demo1.prg - на базе функции _TBrowse(...) сокращённый вариант и другой вариант правки колонок 3) demo2.prg - с помощью обычных функций и oHmgData() -------------------------------------------------------------------------------------------------------------------- * Тестирование колонок в Tsbrowse для dbf файла * Ввод в таблицу. Проверка до и после ввода. * Итоги по числовым полям, автоматический пересчёт при изменении данных в колонке * Своё окно редактирования мемо-поля и текстовых колонок с CRLF * Отработка клика мышки (правая/левая) на суперхидере/шапке/подвале/ячейки таблицы * Работа со SCOPE. * Сохранение/восстановление размеров окна в ини-файл. * Работа с буфером обмена: копирование/вставка ячеек таблицы разного формата * Построение справочника ввода документов по месяцам года - demo2_menu_Fxx.prg * Построение отчёта справочника ввода документов/поиск по буквам и подсчёт итогов "на лету"
аким образом, условие IIF( oBrw:oHScroll != NIL, ... ) отвечает на поставленный вопрос.
Не работает, это просто пробовал. В том примере HScroll есть, из-за этого и работает. В другом примере пробовал - где есть и нет HScroll - там всегда ? oBrw:oHScroll - выдаёт всегда 'o'
Все даты в формате GMT
3 час. Хитов сегодня: 16
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет