Форум » 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

gfilatov2002: SergKis пишет: это надо учитывать Поправил этот код. Благодарю за помощь

SergKis: PS Для поля "M" получим valtype() -> "C" и не попадем на веточку [pre2] ElseIf cType == "M" nSize := iif( ::nMemoWV == Nil, 200, ::nMemoWV ) [/pre2], для "=@" получим "T", но это, наверно, нормально веточка сработает[pre2] ElseIf cType $ "=@T" nSize := GetTextWidth( 0, Replicate( "9", 24 ), hFont ) а ElseIf cType $ "^+" nSize := GetTextWidth( 0, Replicate( "9", 10 ), hFont ) не сработает [/pre2] т.е. в целом нужна большая переработка, но можно пойти др. путем Игорь, какой тип получаем в структуре aStru[ nE, 2 ] для поля "CICHARACTER" U или пусто ? Может Valtype делать для таких полей (с неопределенной структурой) и для них делать Valtype() и результат заносить в aStru[ nE, 2 ], тогда метод не меняется практически

SergKis: PS тогда, наверно, придется определять и aStru[ nE, 3 ] и aStru[ nE, 4 ], но в методе дальше ничего не меняется


SergKis: PS2 Как то так получится [pre2] cType := aStru[ nE, 2 ] IF Empty(cType) .or. cType == "U" cData := ( cAlias )->( FieldGet( nE ) ) aStru[ nE, 2 ] := Valtype( cData ) cType := aStru[ nE, 2 ] IF cType == "C" aStru[ nE, 3 ] := Len( cData ) aStru[ nE, 4 ] := 0 ELSE // тут смотреть твои (ADS) варианты и добавить ENDIF ENDIF [/pre2]

Haz: SergKis пишет: какой тип получаем в структуре aStru[ nE, 2 ] для поля "CICHARACTER" Dbstruct() возвратит именно CICHARACTER , valtype() вернет С. В ADS есть и другие символьные поля это просто CHAR и VARCHAR! но valtype() справедливо вернет С. Тоже касается поля с автоинкрементом в ADS это AUTUINC , valtype вернет N, есть поле дата время TIMESTAMP , valtype его вернет как T (тут надо проверить ) Могу прописать по аналогии с dbf кусок кода для ADS с особенностями его типов полей. Вроде это пока единственный rdd выбивающийся из структуры классического dbf. Но с другой стороны логичнее все же привязываться к типам данных которые знает харбур , а не дергать их из структуры. То есть, valtype будет универсальнее чем dbsruct()

SergKis: Haz пишет Могу прописать по аналогии с dbf кусок кода для ADS с особенностями его типов полей. Вроде это пока единственный rdd выбивающийся из структуры классического dbf. Но с другой стороны логичнее все же привязываться к типам данных которые знает харбур , а не дергать их из структуры. То есть, valtype будет универсальнее чем dbsruct() Думаю, надо прописать (или определять весь список полей dbf), будет правильнее, т.к. лучше понимать ситуацию. Можно даже завести переменную hash в классе для такого списка с "правильной" перекодировкой. Ведь надо еще правильно формировать aStru[ nE, 3\4 ]. От полученного значения (cAlias)->(FieldGet(nE)) может возникать вариантность этих значений. ADS все таки RDD и сделать такую штуку, включив в тсб - нормальное решение

SergKis: Haz пишет То есть, valtype будет универсальнее чем dbsruct() Так и будем прыгать сначала от valtype, но для определения cType и nLen, nDec для работы метода. Если dbStruct() дает правильные типы в aStru, то их можно оставлять для :cFieldTyp, :cFieldLen, :cFieldDec для правильной привязки к полю.

Haz: SergKis пишет: надо прописать (или определять весь список полей dbf), будет правильнее в понедельник с работы пропишу

Haz: SergKis пишет: смотрю версию 2.07 от 2012 года там в LoadFields aStru := ( cAlias )->( DbStruct() ) и Тогда не пойму в чем дело. Последний раз обновлял сборку примерно полгода-год назад. Все строковые данные отображались корректно по колонкам где пикчи не было. Пару дней назад перешёл на последнюю сборку, записал проект в работу и посыпались жалобы. По коду только на loadfilds похоже, что еще может быть не пойму. В проекте после примерно 50 правок явного указания пикчи устал и просто в функцию создающую tsb после определения бровса добавил код который указал выше для символьных полей. Все заработало. Но вот если это тянется с 2012 года, я реально не понимаю что случилось

gfilatov2002: SergKis пишет: Так и будем прыгать сначала от valtype, но для определения cType и nLen, nDec для работы метода. Для того, чтобы сделать этот код универсальным, записал в методе так: [pre2] cData := ( cAlias )->( FieldGet( nE ) ) cType := ValType( cData ) If cType == "C" cPicture := "@K " + Replicate( 'X', aStru[ nE, 3 ] ) ElseIf cType == "N" .and. aStru[ nE, 2 ] $ "^+" cPicture := Replicate( '9', 10 ) ElseIf cType == "N" cPicture := Replicate( '9', aStru[ nE, 3 ] ) If aStru[ nE, 4 ] > 0 cPicture := SubStr( cPicture, 1, aStru[ nE, 3 ]-aStru[ nE, 4 ] - 1 ) + '.' + Replicate( '9', aStru[ nE, 4 ] ) EndIf cPicture := "@K " + cPicture EndIf If nSize == Nil cType := aStru[ nE, 2 ] nSize := aStru[ nE, 3 ] nDec := aStru[ nE, 4 ] hFont := iif( ::hFont != Nil, ::hFont, 0 ) hFontH := iif( ::hFontHead != Nil, ::hFontHead, ::hFont ) If cType == "C" cData := PadR( Trim( cData ), nSize, "B" ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf cType == "N" cData := StrZero( cData, nSize, nDec ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf cType == "D" cData := cValToChar( iif( Empty( cData ), Date(), cData ) ) nSize := Int( GetTextWidth( 0, cData + "BB", hFont ) ) + iif( lEditable, 30, 0 ) ElseIf cType == "M" nSize := iif( ::nMemoWV == Nil, 200, ::nMemoWV ) ElseIf cType $ "=@T" nSize := GetTextWidth( 0, Replicate( "9", 24 ), hFont ) ElseIf cType $ "^+" nSize := GetTextWidth( 0, Replicate( "9", 10 ), hFont ) Else cData := cValToChar( cData ) nSize := GetTextWidth( 0, cData, hFont ) EndIf ... [/pre2]

Haz: Григорий, видимо для универсальности нужно будет явно прописать типы ads. Их там гораздо больше чем в dbf. http://devzone.advantagedatabase.com/dz/webhelp/advantage7.1/server1/adt_field_types_and_specifications.htm В понедельник пришлю правку подних (дома нет компа ). За основу возьму код последним выложенный здесь . Заодно попрошу обновить библиотеку ads, в поставке она устарела . последняя версия ads v12 . именно на ней sap похоронил этот продукт после покупки. Библиотеку под 12 для bcc тоже вышлю

SergKis: gfilatov2002 пишет [pre2] cData := ( cAlias )->( FieldGet( nE ) ) cType := ValType( cData ) If cType == "C" cPicture := "@K " + Replicate( 'X', aStru[ nE, 3 ] ) ElseIf cType == "N" .and. aStru[ nE, 2 ] $ "^+" cPicture := Replicate( '9', 10 ) ElseIf cType == "N" cPicture := Replicate( '9', aStru[ nE, 3 ] ) If aStru[ nE, 4 ] > 0 cPicture := SubStr( cPicture, 1, aStru[ nE, 3 ]-aStru[ nE, 4 ] - 1 ) + '.' + Replicate( '9', aStru[ nE, 4 ] ) EndIf cPicture := "@K " + cPicture EndIf If nSize == Nil cType := aStru[ nE, 2 ] nSize := aStru[ nE, 3 ] nDec := aStru[ nE, 4 ] hFont := iif( ::hFont != Nil, ::hFont, 0 ) hFontH := iif( ::hFontHead != Nil, ::hFontHead, ::hFont ) If cType == "C" cData := PadR( Trim( cData ), nSize, "B" ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf cType == "N" ... [/pre2] 1. Предлагаю убрать выделенное синим цветом, т.к. если задан массив размеров, то из него не правильно берется размер, для всех колонок и тогда всегда надо делать переустановку. Если убрать, то формируются данные из структуры dbf и это более точно получается, но поправить потом можно. У себя убрал это давно 2. Предложенное не подойдет, т.к. CICHARACTER в cType := aStru[ nE, 2 ] после If nSize == Nil не сработает If cType == "C" На мой взгляд надо, сто то такое[pre2] cType := aStru[ nE, 2 ] If Len(cType) > 1 If cType == ""AUTOINC cType := "^" Else cType := Valtype( (cAlias)->(FieldGet(nE)) ) EndIf // может еще варианты, Игорь должен подсказать EndIf [/pre2] Тогда в aStru[ nE, 2 ] будет реальный тип и попадет в :cFieldTyp, а логика отработает в методе нормально. Надо посмотреть на Len и Dec в aStru, если они нормальные, то они отработают ок

SergKis: Haz пишет За основу возьму код последним выложенный здесь Надо брать код из либы последней, выложенный на основе valtype будет работать неверно

Haz: SergKis пишет: Надо брать код из либы последней, Договорились.

Haz: SergKis пишет: Надо брать код из либы последней, выложенный на основе valtype будет работать неверно Примерно так получилось, можно было на хеш массиве сделать , но выигрыша в скорости на таком коротком не будет Далее по коду ищется в массиве aType значение из dbstruct, а возвращается соответствующее valtype [pre2] local aType := {} aType := {} aAdd( aType, {"CICHARACTER", "C"} ) // CiCharacter aAdd( aType, {"C", "C"} ) // Character aAdd( aType, {"C:U", "C"} ) // nChar aAdd( aType, {"C:B", "C"} ) // Raw aAdd( aType, {"Q", "C"} ) // VarCharFox aAdd( aType, {"Q:U", "C"} ) // nVarChar aAdd( aType, {"Q:B", "C"} ) // VarBinaryFox aAdd( aType, {"D", "D"} ) // Date aAdd( aType, {"T", "T"} ) // Time aAdd( aType, {"@", "T"} ) // TimeStamp aAdd( aType, {"=", "T"} ) // ModTime aAdd( aType, {"I", "N"} ) // Integer, ShortInt, LongInt aAdd( aType, {"B", "N"} ) // Double aAdd( aType, {"+", "N"} ) // Autoinc aAdd( aType, {"N", "N"} ) // Numeric aAdd( aType, {"Y", "N"} ) // Money aAdd( aType, {"Z", "N"} ) // Curdouble aAdd( aType, {"^", "N"} ) // RowVersion aAdd( aType, {"M", "M"} ) // Memo aAdd( aType, {"M:U", "M"} ) // nMemo aAdd( aType, {"W", "M"} ) // Binary aAdd( aType, {"P", "M"} ) // Image aAdd( aType, {"L", "L"} ) // If aType[Ascan( aType, {|e| e[1] == cType })][2] == "C" cPicture := "@K " + Replicate( 'X', aStru[ nE, 3 ] ) ElseIf aType[Ascan( aType, {|e| e[1] == cType })][2] == "N" cPicture := Replicate( '9', aStru[ nE, 3 ] ) If aStru[ nE, 4 ] > 0 cPicture := SubStr( cPicture, 1, aStru[ nE, 3 ]-aStru[ nE, 4 ] - 1 ) + '.' + Replicate( '9', aStru[ nE, 4 ] ) EndIf cPicture := "@K " + cPicture ElseIf cType $ "^+" cPicture := Replicate( '9', 10 ) EndIf If nSize == Nil cData := ( cAlias )->( FieldGet( nE ) ) cType := aStru[ nE, 2 ] nSize := aStru[ nE, 3 ] nDec := aStru[ nE, 4 ] hFont := iif( ::hFont != Nil, ::hFont, 0 ) hFontH := iif( ::hFontHead != Nil, ::hFontHead, ::hFont ) If aType[Ascan( aType, {|e| e[1] == cType })][2] == "C" cData := PadR( Trim( cData ), nSize, "B" ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf aType[Ascan( aType, {|e| e[1] == cType })][2] == "N" cData := StrZero( cData, nSize, nDec ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf aType[Ascan( aType, {|e| e[1] == cType })][2] == "D" cData := cValToChar( iif( Empty( cData ), Date(), cData ) ) nSize := Int( GetTextWidth( 0, cData + "BB", hFont ) ) + iif( lEditable, 30, 0 ) ElseIf aType[Ascan( aType, {|e| e[1] == cType })][2] == "M" nSize := iif( ::nMemoWV == Nil, 200, ::nMemoWV ) ElseIf aType[Ascan( aType, {|e| e[1] == cType })][2] == "T" nSize := GetTextWidth( 0, Replicate( "9", 24 ), hFont ) ElseIf cType $ "^+" nSize := GetTextWidth( 0, Replicate( "9", 10 ), hFont ) Else cData := cValToChar( cData ) nSize := GetTextWidth( 0, cData, hFont ) EndIf nSize := Max( GetTextWidth( 0, Replicate( "B", Len( cHeading ) + 1 ), hFontH ), nSize ) nSize += iif( ! Empty( cOrder ), 14, 0 ) ElseIf ValType( ::aColSizes ) == "A" .and. ! Empty( ::aColSizes ) .and. n <= Len( ::aColSizes ) nSize := ::aColSizes[ n ] EndIf [/pre2]

Haz: Haz пишет: aType[Ascan( aType, {|e| e[1] == cType })][2] Думаю этот код нужно выполнить до сравнения один раз с проверкой на возврат нуля, иначе будет вылет если dbstruct вернет не прописанный в массиве тип

gfilatov2002: Haz пишет: Примерно так получилось Вынес поиск в массиве в статическую функцию GetDbfFieldType() и записал этот фрагмент таким образом: [pre2] cType := aStru[ nE, 2 ] If GetDbfFieldType( cType ) == "C" cPicture := "@K " + Replicate( 'X', aStru[ nE, 3 ] ) ElseIf cType $ "^+" cPicture := Replicate( '9', 10 ) ElseIf GetDbfFieldType( cType ) == "N" cPicture := Replicate( '9', aStru[ nE, 3 ] ) If aStru[ nE, 4 ] > 0 cPicture := SubStr( cPicture, 1, aStru[ nE, 3 ]-aStru[ nE, 4 ] - 1 ) + '.' + Replicate( '9', aStru[ nE, 4 ] ) EndIf cPicture := "@K " + cPicture EndIf If nSize == Nil cData := ( cAlias )->( FieldGet( nE ) ) cType := GetDbfFieldType( aStru[ nE, 2 ] ) nSize := aStru[ nE, 3 ] nDec := aStru[ nE, 4 ] hFont := iif( ::hFont != Nil, ::hFont, 0 ) hFontH := iif( ::hFontHead != Nil, ::hFontHead, ::hFont ) If cType == "C" cData := PadR( Trim( cData ), nSize, "B" ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf aStru[ nE, 2 ] $ "^+" nSize := GetTextWidth( 0, Replicate( "9", 10 ), hFont ) ElseIf cType == "N" cData := StrZero( cData, nSize, nDec ) nSize := GetTextWidth( 0, cData, hFont ) ElseIf cType == "D" cData := cValToChar( iif( Empty( cData ), Date(), cData ) ) nSize := Int( GetTextWidth( 0, cData + "BB", hFont ) ) + iif( lEditable, 30, 0 ) ElseIf cType == "M" nSize := iif( ::nMemoWV == Nil, 200, ::nMemoWV ) ElseIf cType == "T" nSize := GetTextWidth( 0, Replicate( "9", 24 ), hFont ) Else cData := cValToChar( cData ) nSize := GetTextWidth( 0, cData, hFont ) EndIf nSize := Max( GetTextWidth( 0, Replicate( "B", Len( cHeading ) + 1 ), hFontH ), nSize ) nSize += iif( ! Empty( cOrder ), 14, 0 ) ElseIf ValType( ::aColSizes ) == "A" .and. ! Empty( ::aColSizes ) .and. n <= Len( ::aColSizes ) nSize := ::aColSizes[ n ] EndIf [/pre2]Благодарю за помощь

SergKis: Haz пишет код нужно выполнить до сравнения один раз с проверкой на возврат нуля, иначе будет вылет если dbstruct вернет не прописанный в массиве тип Предлагаю так (можно будет расширять список, если что)[pre2] DATA aFieldTypes AS ARRAY INIT { ; {"CICHARACTER", "C"}, ; // CiCharacter {"C", "C"}, ; // Character {"C:U", "C"}, ; // nChar {"C:B", "C"}, ; // Raw {"Q", "C"}, ; // VarCharFox {"Q:U", "C"}, ; // nVarChar {"Q:B", "C"}, ; // VarBinaryFox {"D", "D"}, ; // Date {"T", "T"}, ; // Time {"@", "T"}, ; // TimeStamp {"=", "T"}, ; // ModTime {"I", "N"}, ; // Integer, ShortInt, LongInt {"B", "N"}, ; // Double {"+", "N"}, ; // Autoinc {"N", "N"}, ; // Numeric {"Y", "N"}, ; // Money {"Z", "N"}, ; // Curdouble {"^", "N"}, ; // RowVersion {"M", "M"}, ; // Memo {"M:U", "M"}, ; // nMemo {"W", "M"}, ; // Binary {"P", "M"}, ; // Image {"L", "L"} ; // } Local aType := ::aFieldTypes, nType ... cType := aStru[ nE, 2 ] IF ( nType := Ascan( aType, {|e| e[1] == cType }) ) > 0 cType := aType[nType ][2] ENDIF ... Далее по тексту метода, как был [/pre2]

Haz: SergKis пишет: Предлагаю так (можно будет расширять список, если что) Согласен, погоняю еще позже отпишусь . Сейчас занят очень

gfilatov2002: SergKis пишет: Предлагаю так Принято, тестовый пример отработал нормально Благодарю за помощь



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