Форум » 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: Выложил 3-й апдейт сборки 21.07 Добавлены новые интересные функции, выполнена оптимизация использования внутренних STATIC переменных в ядре библиотеки (их количество уменьшилось на треть). Обновил также Unicode архив. Желаю всем участникам форума мира и добра

SergKis: gfilatov2002 Если появилось облако переменных, может есть смысл, внести обработку в Events() сообщения WM_COPYDATA, т.е. примерно так [pre2] ... CASE nMsg == WM_COPYDATA .and. _SetGetGlobal("b_WM_COPYDATA") != Nil // to get data cData := GetMessageData( lParam, @nDataID ) EVal( _SetGetGlobal("b_WM_COPYDATA"), nDataID, cData ) [/pre2] PS. Почему массив, а не Hash, переменных ведь много можно организовать или для системных переменных завести отдельное пространство переменных

gfilatov2002: SergKis пишет: может есть смысл, внести обработку в Events() Благодарю за предложение, но это, по-моему, излишне. Хотя, есть над чем подумать... SergKis пишет: Почему массив, а не Hash Так привычнее, поскольку для хранения PUBLIC переменных используется единый массив также.


SergKis: gfilatov2002 пишет PUBLIC переменных используется единый массив также. Это скорее, исторический, минус для hmg, т.к. структура внутри получилась довольно костяная и индивидуальная (описания контролов, где внутренние массивы различаются). Подключение пользовательских обработчиков через SET EVENTS FUNCTION TO MYEVENTS решает многое, но требуют знаний. Так привычнее Использую оч. давно механизм oKeyData() для решения пространства переменных программы и в реале их бывает оч. много и это с учетом, что на окнах такие данные (глобальные) перекрываются локальными значениями В Hash ключ можно использовать не только строковые значения, что бывает очень удобно PS. Пропустил, а удаление переменной есть ?

gfilatov2002: SergKis пишет: а удаление переменной есть ? Нет Но Вы без труда напишите функцию _DelGlobal()

SergKis: gfilatov2002 пишет Но Вы без труда напишите функцию _DelGlobal() Я бы пошел по пути STATIC _HMG_STATIC := oKeyData() //{} и уже все было бы через hash, CLASS TKeyData вынес бы за скобку #ifdef _OBJECT_ Код дополнительный для обслуживания _HMG_STATIC написан PS. CLASS TThrData можно, наверно, удалить. Вряд ли его используют в потоках, а для др. он не нужен

SergKis: PS Ф-я может быть такой[pre2] STATIC _HMG_STATIC := oKeyData() *-----------------------------------------------------------------------------* FUNCTION _SetGetGlobal( cVarName, xNewValue ) *-----------------------------------------------------------------------------* LOCAL xOldValue IF pCount() == 0 RETURN _HMG_STATIC ELSEIF pCount() == 1 IF ISCHAR(cVarName) ; cVarName := upper(cVarName) ENDIF RETURN _HMG_STATIC:Get(cVarName, NIL) ELSEIF pCount() == 2 IF ISCHAR(cVarName) ; cVarName := upper(cVarName) ENDIF xOldValue := _HMG_STATIC:Get(cVarName, NIL) IF ISNIL(xNewValue) ; _HMG_STATIC:Del(cVarName) ELSE ; _HMG_STATIC:Set(cVarName, xNewValue) ENDIF ENDIF RETURN xOldValue [/pre2] Применять так дополнительно (кроме выше описанных) aKeys := _SetGetGlobal():Keys() // список всех переменных и ключей aValues := _SetGetGlobal():Values() // список всех значений aAll := _SetGetGlobal():GetAll() // массив всех переменных и значений, т.е. {{key, value},...} и дальше по списку методов класса TKeyData Для строковых переменных можно работать os := _SetGetGlobal() cPath := os:cPathData os:bMy := {|| ... } примеры с Cargo есть на эту тему

gfilatov2002: SergKis пишет: Ф-я может быть такой Выполнил предложенные изменения для использования хэша и класса TKeyData. Исправил присвоение SergKis пишет: STATIC _HMG_STATIC := oKeyData() поскольку нельзя присваивать статической переменной возврат функции ВСЕ РАБОТАЕТ (как описано выше)! БЛАГОДАРЮ ЗА ПОМОЩЬ

SergKis: gfilatov2002 Может сделать THmgData класс, почистив от лишнего и вернуть TKeyData за скобку ? [pre2] STATIC _HMG_STATIC *-----------------------------------------------------------------------------* FUNCTION _SetGetGlobal( cVarName, xNewValue ) *-----------------------------------------------------------------------------* LOCAL xOldValue IF _HMG_STATIC == NIL ; _HMG_STATIC := oHmgData() ENDIF IF pCount() == 0 RETURN _HMG_STATIC ELSEIF pCount() == 1 RETURN _HMG_STATIC:Get(cVarName, Nil) ELSEIF pCount() == 2 xOldValue := _HMG_STATIC:Get(cVarName, Nil) IF ISNIL( xNewValue ) ; _HMG_STATIC:Del(cVarName) ELSE ; _HMG_STATIC:Set(cVarName, xNewValue) ENDIF ENDIF RETURN xOldValue *-----------------------------------------------------------------------------* FUNCTION oHmgData( lUpper ) *-----------------------------------------------------------------------------* hb_default( @lUpper, .T. ) RETURN THmgData():New( lUpper ) /////////////////////////////////////////////////////////////////////////////// CLASS THmgData /////////////////////////////////////////////////////////////////////////////// PROTECTED: VAR lUpp AS LOGICAL VAR aKey INIT hb_Hash() EXPORTED: VAR Cargo METHOD New( lUpper ) INLINE ( ::lUpp := !Empty( lUpper ), Self ) CONSTRUCTOR METHOD Set( Key, Block ) INLINE iif( HB_ISHASH( Key ), ::aKey := Key, hb_HSet ( ::aKey, ::Upp( Key ), Block ) ) METHOD Get( Key, Def ) INLINE hb_HGetDef( ::aKey, ::Upp( Key ), Def ) METHOD Del( Key ) INLINE iif( ::Pos( Key ) > 0, hb_HDel( ::aKey, ::Upp( Key ) ), Nil ) METHOD Pos( Key ) INLINE hb_HPos( ::aKey, ::Upp( Key ) ) METHOD Upp( Key ) INLINE iif( HB_ISCHAR(Key) .and. ::lUpp, Upper( Key ), Key ) METHOD Len() INLINE Len( ::aKey ) METHOD Keys() INLINE hb_HKeys( ::aKey ) METHOD Values() INLINE hb_HValues( ::aKey ) METHOD CloneHash() INLINE hb_HClone( ::aKey ) _METHOD GetAll( lAll ) _METHOD Eval( Block ) _METHOD Destroy() ERROR HANDLER ControlAssign ENDCLASS /////////////////////////////////////////////////////////////////////////////// METHOD GetAll( lAll ) CLASS THmgData LOCAL aRet := {} IF HB_ISLOGICAL( lAll ) .AND. lAll ::Eval( {| val | AAdd( aRet, val ) } ) ELSE ::Eval( {| val, Key | AAdd( aRet, { Key, val } ) } ) ENDIF RETURN aRet METHOD Eval( Block ) CLASS THmgData LOCAL i, b := HB_ISBLOCK( Block ) LOCAL l := HB_ISLOGICAL( Block ) .AND. Block LOCAL a := iif( b, NIL, Array( 0 ) ) FOR i := 1 TO ::Len() IF b ; Eval( Block, hb_HValueAt( ::aKey, i ), hb_HKeyAt( ::aKey, i ), i ) ELSEIF l ; AAdd( a, hb_HValueAt( ::aKey, i ) ) ELSE ; AAdd( a, { hb_HValueAt( ::aKey, i ), hb_HKeyAt( ::aKey, i ), i } ) ENDIF NEXT RETURN a METHOD Destroy() CLASS THmgData LOCAL i, k, o IF HB_ISHASH( ::aKey ) FOR i := 1 TO Len( ::aKey ) k := hb_HKeyAt( ::aKey, i ) hb_HSet( ::aKey, k, Nil ) hb_HDel( ::aKey, k ) NEXT ENDIF IF HB_ISOBJECT( ::Cargo ) .AND. ::Cargo:ClassName == ::ClassName o := ::Cargo IF HB_ISHASH( o:aKey ) FOR i := 1 TO Len( o:aKey ) k := hb_HKeyAt( o:aKey, i ) hb_HSet( o:aKey, k, Nil ) hb_HDel( o:aKey, k ) NEXT ENDIF ENDIF RETURN NIL METHOD ControlAssign( xValue ) CLASS THmgData LOCAL cMessage, uRet, lError cMessage := __GetMessage() lError := .T. IF PCount() == 0 uRet := ::Get( cMessage ) lError := .F. ELSEIF PCount() == 1 ::Set( SubStr( cMessage, 2 ), xValue ) uRet := ::Get( cMessage ) lError := .F. ENDIF IF lError uRet := NIL ::MsgNotFound( cMessage ) ENDIF RETURN uRet [/pre2] PS. Можно и метод Destroy() убрать, hb сам справится с очисткой, при завершении работы

gfilatov2002: SergKis пишет: Может сделать THmgData класс Принято

SergKis: gfilatov2002 пишет Принято Допустил неточность в методе Eval(), поправил и выделил цветом PS. Можно сделать псевдофункции на замену __mvPublic, __mvGet, ... и перенаправить с PUBLIC переменных на hash в переменной, к примеру, _HMG_PUBLIC

gfilatov2002: SergKis пишет: Допустил неточность в методе Eval() Спасибо, исправил.

gfilatov2002: Опубликован 4-й апдейт сборки 21.07 Благодарю за помощь Сергея Киселева P.S. Обновил также Unicode архив.

SergKis: Григорий, сделав обще доступной с пользователем область переменных _SetGetGlobal(), не закладывается ли мина пересечения имен ? Может надо разделить, для пользователя _SetGetGlobal(), а для системных вещей, на пример, _SysGlobal()\_HmgGlobal(). По мне стремная ситуация получается с именами сейчас, к примеру IF _SetGetGlobal( 'lOnChangeEvent' ) == NIL Я так тоже люблю свои переменные называть. Или выкинуть из описания для пользователя использование _SetGetGlobal(), можно оставить ф-ю oHmgData() для использования в таком виде LOCAL oVar := oHmgData() oVar:cPathData := "\HBK\DATA" oVar:lShow := .T. oVar:cTitle := "Bla bla bla" ...

gfilatov2002: SergKis пишет: стремная ситуация получается с именами Согласен. Для безопасности добавлю префикс _HMG_ к этим системным переменным

SergKis: gfilatov2002 пишет Для безопасности добавлю префикс _HMG_ к этим системным переменным Для безопасности лучше разделить, наверное и списки раздельные, т.е. контроль у каждого за своими переменными нормальный, и по действиям проще, просканировал тексты сейчас, заменил на системное использование и все.

Haz: Всем привет. нашел у себя в старом проекте. Совсем забыл Может будет интересно [pre2] METHOD Show(lShow) CLASS TSBrowse hb_default(@lShow, .t.) if lShow ShowWindow(::hWnd) else HideWindow(::hWnd) end RETURN nil [/pre2] Используется для прорисовки в одних координатах разных бровсов в зависимости от условий, примерно так [pre2] ... oBrw_1:Show( lOk ) oBrw_2:Show( !lOk ) ... [/pre2] В итоге , в зависимости от значения lOk один бровс спрячется, а второй появится Правда делал через __objAddMethod() чтоб исходники не менять. Но суть та же

SergKis: Haz пишет Правда делал через __objAddMethod() чтоб исходники не менять. В TControl уже есть методы METHOD Hide() INLINE ShowWindow( ::hWnd, SW_HIDE ) METHOD Show() INLINE ShowWindow( ::hWnd, SW_SHOWNA ) они работают. Т.е. можно писать iif( lOk, oBrw:Show(), oBrw:Hide() ) Через __objAddMethod() ты просто замещал метод oBrw:Show, наследованный от TControl, своим кодом

Haz: SergKis пишет: TControl уже есть методы METHOD Hide() INLINE ShowWindow( ::hWnd, SW_HIDE ) Значит я изобрёл велосипед Нашёл разгребая архивы, не проверив исходники. Спасибо

SergKis: Haz пишет Значит я изобрёл велосипед Это часто бывает проще, чем разобрать, что где лежит и как работает. Сам страдаю таким, ну нет времени куда то залезть поглубже , делаешь быстро, что бы работало. Так что не бери в голову ... со временем все встает на свои места



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