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

SergKis: PS Если принять вариант GetControlIndex, то можно, пройдя по функциям, сделать:[pre2] *-----------------------------------------------------------------------------* FUNCTION _SetFocus ( ControlName, ParentForm ) *-----------------------------------------------------------------------------* LOCAL MaskStart As Numeric // LOCAL H , T , x , i, ControlCount , ParentFormHandle LOCAL H , T , x , ControlCount , ParentFormHandle LOCAL i := GetControlIndex ( ControlName, ParentForm ) ParentForm := i H := GetControlHandle( ControlName, ParentForm ) T := GetControlType ( ControlName, ParentForm ) // i := GetControlIndex ( ControlName, ParentForm ) ... [/pre2] работа без лишних макросов

Andrey: SergKis пишет: gfilatov2002 Повторю предложение, А он вроде писал, что убегает в отпуск ....

SergKis: Andrey пишет А он вроде писал, что убегает в отпуск Я в курсе, прошлый раз, Григорий, отказал, отослав к инструкции\описанию\религии МиниГуи. Выкладываю сейчас, потому как, он придет из отпуска, я уйду.

SergKis: gfilatov2002 SergKis пишет сделать [pre2] *-----------------------------------------------------------------------------* Function _DoControlEventProcedure ( bBlock , i , cEventType , nParam, p2, p3 ) *-----------------------------------------------------------------------------* ... if valtype( bBlock ) == 'B' .and. i > 0 ... If _HMG_BeginWindowActive == .F. .or. !( cEventType == 'CONTROL_ONCHANGE' ) .or. _HMG_MainClientMDIHandle != 0 Eval( bBlock, nParam, p2, p3 ) EndIf ... *-----------------------------------------------------------------------------* Function _DoWindowEventProcedure ( bBlock , i , cEventType, nParam, p2, p3 ) *-----------------------------------------------------------------------------* ... if valtype( bBlock ) == 'B' .and. i > 0 ... _HMG_ThisControlName := "" lRetVal := Eval( bBlock, nParam, p2, p3 ) _PopEventInfo() ... [/pre2] А правильнее так [pre2] *-----------------------------------------------------------------------------* Function _DoControlEventProcedure ( bBlock , i , cEventType , nParam, p2, p3 ) *-----------------------------------------------------------------------------* ... If Pcount() > 4; Eval( bBlock, p2, nParam, p3 ) // new Else ; Eval( bBlock, nParam ) // old EndIf ... *-----------------------------------------------------------------------------* Function _DoWindowEventProcedure ( bBlock , i , cEventType, nParam, p2, p3 ) *-----------------------------------------------------------------------------* ... If Pcount() > 4; lRetVal := Eval( bBlock, p2, nParam, p3 ) // new Else ; lRetVal := Eval( bBlock, nParam ) // old EndIf ... [/pre2] Тогда в примере будет [pre2] // ---------------------------------------------------------------------------- Control events WITH OBJECT oWnd:GetObj( This.FRM_4.Handle ) :Event( 1, {|ow,ky| This_Msg('Control message ' + "nKey="+cValToChar(ky), ow:Name) } ) :Event( 2, {|ow,ky| This_Msg('Control message ' + "nKey="+cValToChar(ky), ow:Name) } ) // ... END WITH nY += This.FRM_4.Height + nHgt cNam := 'ID' @ nY, nX LABEL &cNam VALUE '' WIDTH nLen HEIGHT oBrw1:nHeightCell CENTERALIGN WITH OBJECT oWnd:GetObj(cNam) :Cargo := 0 // :Event( 1, {|ky,oc,kd,id| ky := ky, ; // Get :Event( 1, {|oc,kd,id | kd := Eval( oBrw1:GetColumn('KODS'):bData ), ; // Get id := Eval( oBrw1:GetColumn('ID'):bData ), ; oc:Value := alltrim(cValToChar(id))+"-<"+ ; alltrim(cValToChar(kd))+">" } ) // :Event( 2, {|ky,oc | ky := ky, ; // Put :Event( 2, {|oc | oc:Window:oCargo:Set(oc:Name, oc:Value) } ) // Put :Window:oCargo:Set(cNam, :Value ) // init value to oCargo END WITH nY += This.&(cNam).Height cNam := 'KOLV' @ nY, nX LABEL &cNam VALUE '' WIDTH nLen HEIGHT oBrw1:nHeightCell CENTERALIGN WITH OBJECT oWnd:GetObj(cNam) // :Event( 1, {|ky,oc,kl| ky := ky, ; // Get :Event( 1, {|oc,kl | kl := Eval( oBrw1:GetColumn('KOLV'):bData ), ; // Get oc:Value := alltrim(cValToChar(kl)) } ) // :Event( 2, {|ky,oc | ky := ky, ; // Put :Event( 2, {|oc | oc:Window:oCargo:Set(oc:Name, oc:Value) } ) // Put :Window:oCargo:Set(cNam, :Value ) // init value to oCargo END WITH nY += This.&(cNam).Height cNam := 'CENA' @ nY, nX LABEL &cNam VALUE '' WIDTH nLen HEIGHT oBrw1:nHeightCell CENTERALIGN WITH OBJECT oWnd:GetObj(cNam) // :Event( 1, {|ky,oc,cn| ky := ky, ; // Get :Event( 1, {|oc,cn | cn := Eval( oBrw1:GetColumn('CENA'):bData ), ; // Get oc:Value := alltrim(cValToChar(cn)) } ) // :Event( 2, {|ky,oc | ky := ky, ; // Put :Event( 2, {|oc | oc:Window:oCargo:Set(oc:Name, oc:Value) } ) // Put :Window:oCargo:Set(cNam, :Value ) // init value to oCargo END WITH nY += This.&(cNam).Height + 10 cNam := 'NAME' cPic := oBrw1:GetColumn('NAME'):cPicture cNam := 'NAME' @ nY, nX GETBOX &cNam WIDTH nLen HEIGHT oBrw1:nHeightCell VALUE space(len(cPic)) ; PICTURE cPic ; BACKCOLOR {{255,255,255},{255,255,200},{200,255,255}} ; FONTCOLOR {{0,0,0},{255,255,200},{0,0,255}} WITH OBJECT oWnd:GetObj(cNam) // :Event( 1, {|ky,oc | ky := ky, ; // Get :Event( 1, {|oc | oc:Value := Eval( oBrw1:GetColumn('NAME'):bData ) } ) // Get // :Event( 2, {|ky,oc | ky := ky, ; // Put :Event( 2, {|oc | oc:Window:oCargo:Set(oc:Name, oc:Value) } ) // Put :Window:oCargo:Set(cNam, :Value ) // init value to oCargo END WITH // ---------------------------------------------------------------------------- Control events DEFINE TIMER REFR INTERVAL 500 ACTION MyEvent( 'ID' ) This.REFR.Cargo := oWnd:GetObj4Type('LABEL,GETBOX') WITH OBJECT oWnd // ---- Window events :Event( 1, {|ow,ky| This_Msg('Window message ' + "nKey="+cValToChar(ky), ow:Name) } ) :Event( 2, {|ow,ky| This_Msg('Window message ' + "nKey="+cValToChar(ky), ow:Name) } ) :Event( 3, {| | AEval( This.REFR.Cargo , {|oc| oc:SendMsg(2) }) } ) // Put // ... END WITH // ---- Window events [/pre2] без лишних ky := ky, ;

SergKis: gfilatov2002 Добавил методы и подправил h_windows.prg [pre2] CLASS TWndData ... METHOD Destroy() INLINE ( ::oCargo:Destroy(), ::oCargo := Nil, ::cChr := Nil, ; ::oUserKeys:Destroy(), ::oUserKeys := Nil, ; ::oEvent:Destroy(), ::oEvent := Nil, ::cVar := Nil, ; ::oHand:Destroy(), ::oHand := Nil, ::uTmp := Nil, ; ::oName:Eval({|ky,oc,nn| ky := nn, oc:Destroy() }), ; ::oName := Nil, ::cName := Nil, ::cType := Nil, ; ::nIndex := Nil, ::nHandle := Nil, ::nParent := Nil, ; ::oStatusBar := Nil, oToolBar := Nil, ::oMenu := Nil ) ENDCLASS ... CLASS TCntData INHERIT TWndData ... METHOD Destroy() INLINE ( ::oCargo:Destroy(), ::oUserKeys:Destroy(), ; ::oEvent:Destroy(), ::cChr := Nil, ::uTmp := Nil, ; ::cVar := Nil, ::cName := Nil, ::cType := Nil, ; ::nIndex := Nil, ::nHandle := Nil, ::nParent := Nil ) ENDCLASS ... METHOD Sum( Key, nSum ) METHOD Destroy() INLINE ( ::oObj := Nil, ::bBlk := Nil, ::Cargo := Nil, ::aKey := Nil ) ENDCLASS ... METHOD Sum( Key, xSum ) CLASS TKeyData LOCAL sum := ::Get( Key, 0 ) If HB_ISNUMERIC( xSum ) If HB_ISNUMERIC( sum ); sum += xSum Else ; sum := xSum EndIf ::Put( Key, sum ) ElseIf HB_ISARRAY( xSum ) If HB_ISARRAY(sum) .and. Len(sum) == Len(xSum) AEval(xSum, {|s,i| sum[ i ]:= iif( HB_ISNUMERIC( s ), sum[ i ] + s, s ) } ) Else sum := xSum EndIf ::Put( Key, sum ) EndIf RETURN Nil h_windows.prg ... *-----------------------------------------------------------------------------* Function _ReleaseWindow ( FormName ) *-----------------------------------------------------------------------------* ... line 2278 i := GetFormIndex ( Formname ) FormHandle := _HMG_aFormHandles [ i ] * Release Window If HB_ISOBJECT( _HMG_aFormMiscData1 [ i ][1] ) _HMG_aFormMiscData1 [ i ][1]:Destroy() EndIf IF _HMG_aFormType [ i ] == 'M' .AND. _HMG_ActiveModalHandle <> FormHandle ... [/pre2]

Петр: SergKis пишет: Добавил методы и подправил h_windows.prg Я надеюсь, что вы высылаете исходники Григорию или хотя-бы diff файлы? А то боюсь, что он врядли вручную захочет все это реконструировать. прошлый раз, Григорий, отказал, отослав к инструкции\описанию\религии МиниГуи. Я бы тоже отказал. В примеры - пожалуйста, там и так черт ногу сломит, а для ядра библиотеки - это слишком специфично и классово чуждо Tsbrowse не в счет. Да еще - ваши упоминания о "религии MiniGUI" ни на йоту не приближают вас к успеху Но я хотя бы понял, чего вы о ней вспомнили

Andrey: Да не так уж и много правок для ядра. А почему не нужно это вставлять ? По синтаксису понятно и пользоваться можно будет в будущем. Удобней кстати для использования. А примеры для этого тоже бы желательно иметь более подробней написанные...

SergKis: Петр пишет Я надеюсь, что вы высылаете исходники Григорию Пока, нет, т.к. нет ясности, будет ли это востребовано (работа по сообщениям) в MiniGui. Выкладываю что бы услышать коменты (исправления) и может кому пригодиться. Сборка изменений у меня есть (моя версия), но на какую версию 17.05\17.06 накладывать изменения ясности нет. для ядра библиотеки - это слишком специфично и классово чуждо чуждость странная, на мой взгляд, в одном месте ядра используем _HMG_... переменные в др. говорим низяя , хотя это такие же внутренние переменные. Мое дело предложить ...

SergKis: PS Нет ясности, у примеру, как обозвать правильно функции: oWndData() или oTWndData() oCntData() или oTCntData() oKeyData() или oTKeyData()

SergKis: Andrey пишет А примеры для этого тоже бы желательно иметь более подробней написанные... В примере, мне кажется, довольно подробно написано применение практически всех вариантов.

Петр: Andrey пишет: Да не так уж и много правок для ядра. Правки сырые, видно, что человек не читал хотя бы то, что в xhb-diff написано и примеров ООП в папке tests не смотрел. И если собираетесь использовать в harbour классы, то нужно найти и почитать документацию по Class(y). Реализация методов Destroy показывает, что еще есть чему учиться. SergKis пишет: Нет ясности, у примеру, как обозвать правильно функции: oWndData() или oTWndData() Если это функции классов, то префикс o здесь явно чуждый. Что до T - это дань Делфи, "родные" функции классов в harbour начинаются c Hb

Петр: SergKis пишет: в одном месте ядра используем _HMG_ Дело в том, что вы положили в переменную, использование классов в процедурной библиотеке, выглядит достаточно странно. А если учесть, что нет никакой продуманной обьектной модели, что визуальные обьекты, смешаны с невизуальными, довольно таки специфическими (TCntData ).. Пока, нет, т.к. нет ясности, будет ли это востребовано (работа по сообщениям) Какое отношение имеет TCntData к "работе с сообщениями" ? Какую модель работы с сообщениями вы выбрали?

SergKis: Петр пишет А если учесть, что нет никакой продуманной обьектной модели, что визуальные обьекты, смешаны с невизуальными, довольно таки специфическими (TCntData ).. Если просматривали историю выкладываня, могли увидеть, что некоторые визуальные (после отладки) уходили в невизуальные. Набираю с колес, в первую очередь, для себя, чтобы с работающей сейчас сопли (своя версия) перейди на более разумную Какое отношение имеет TCntData к "работе с сообщениями" Самое прямое, на нем, в первую очередь, ставятся\выполняются events этого This контрола + насколько команд, для упр. контролом внутри блока events. На окно, соответсвенно, для самостоятельных (не связанных event с контролом) или для организации множественной рассылки сообщений контролам, с установкой соотв. среды This. Дело в том, что вы положили в переменную, использование классов в процедурной библиотеке, выглядит достаточно странно. Вполне можно убрать, добавил только для "эстетического" написания\использования. GetControlIndex(Self) или GetControlIndex( , Self:Index) Реализация методов Destroy показывает, что еще есть чему учиться. Так всю жизнь этим занимаюсь. Правки сырые, видно, что человек не читал хотя бы то, что в xhb-diff написано и примеров ООП в папке tests не смотрел с xhb дел не имел (кроме сборки letodb) никаких. Примеры ООП, в основном hb 2.0. Правки сырые", действительно так, с "колес", но мне лично надо ехать, а шашечки ..., правильное оформление ... Разве, кто подключится и поможет.

Петр: Какое отношение имеет TCntData к "работе с сообщениями" Самое прямое А, так это - TControl и что делает метод Sum(), а главное для чего он что-то делает? Позвольте дать вам совет. 1) Для публичных библиотек не используйте конспирологические имена (:UsK) 2) Возьмите принятную для вас обьектную модель (Delphi, FoxPro, xailer ) и внимательно ее изучите. SergKis пишет: с xhb дел не имел (кроме сборки letodb) никаких. Примеры ООП, в основном hb 2.0. Правки сырые", действительно так, с "колес", но мне лично надо ехать, а шашечки ... Не буду обьяснять почему, но вам в source еще рано.

SergKis: Петр пишет что делает метод Sum(), а главное для чего он что-то делает? TKeyData для работы с ключами hash, т.е. ключ - значение и Sum делает в рамках этих правил сумму (массив сумм) на ключ. Local o1 := oKeyData() Local o2 := oKeyData() DO WHILE ! Eof() o1:Sum("#", 1) o1:Sum("KolVo", (oBrw1:cAlias)->KOLVO) o1:Sum("Summa", (oBrw1:cAlias)->SUMMA) o2:Sum("Itogo", {1, (oBrw1:cAlias)->KOLVO, (oBrw1:cAlias)->SUMMA} SKIP ENDDO o1:Eval({|k,s,i| _LogFile(.T., i, k, s) }) o2:Eval({|k,s,i| _LogFile(.T., i, k, hb_valtoexp(s)) }) и все это можно использовать в event, к примеру, окна. Для публичных библиотек не используйте конспирологические имена (:UsK) Я приписал - на любителя, оставил, что бы текст выложенный и моей версиии, соответствовалВозьмите принятную для вас обьектную модель (Delphi, FoxPro, xailer ) и внимательно ее изучите. но вам в source еще рано Скорее поздно, да и совершенно не стремлюсь.

SergKis: PS Вылез с предложениями, только по причинам 1. Убрать лишнее макро выполнение в командах (у меня убрано). См. _SetFocus постах выше 2. Получить работу с сообщениями, если мой вариант, то дополнительно бонус - список всех типов на окно - список объектов контролов по запросу типов - список объектов контролов по запросу имен Цель, иметь возможность перехода на последние версии hmg. Если предложения будут включены "правильным" образом с "правильным" описанием, я включу их в свою версию правильно. В любом случае, я перешел с поделки на Label (аналог сообщений), используя повод :UserKeys, пусть и не "правильный" код

Петр: SergKis пишет: Если предложения будут включены "правильным" образом с "правильным" описанием, я включу их в свою версию правильно. Ваш код в существующем виде не может быть включен в MiniGUI по банальной причине - MiniGUI Ext. поддерживает как harbour, так и xhb. Для того, чтобы написать совместимый код нужно знать их отличия (xhb-diff) как на PRG уровне (элементарное различие в наименовании функций и к-ве параметров), так и C API. Вот, к примеру, в xhb реализация деструктора обьекта приводит к повреждению HVM памяти. Поэтому такие вещи сильно (иногда не сильно ) лимитируют использование нативных средств языка (harbour/xhb), вынуждая создавать соотв. функциональность с помощью WinAPI и совместимого C API.

SergKis: Петр Наверно по незнанию,не вижу связи использования WinApi для установки свойства объекта (в реале STATIC переменной) в Nil, если не ставить - это произойдет все равно (как не использованная) мусоросборщиком. А др. в destroy нет. В hb (в сравнении с vo, но это уже история ...) напрягает (чуть чуть) отсутствие автоматических AXIT и Destroy, делаем ручками. Ваш код в существующем виде не может быть включен в MiniGUI по банальной причине - MiniGUI Ext. поддерживает как harbour, так и xhb. Destroy это просто название метода, его можно было назвать ToNil, если на название реагирует xhb , нет проблем, сменим, если для xhb надо отдельно метод инициализации, тоже нет проблемы, сделаем метод Init или Define и будем писать TWndData():New():Init( <параметры> ) Покажите как надо, оформлю, но изучать xhd-diff ..., т.к по жизни нет необходимости в этом

Петр: SergKis пишет: В hb (в сравнении с vo, но это уже история ...) напрягает (чуть чуть) отсутствие автоматических AXIT и Destroy, Ага-ага. Да посмотрите вы примеры, пожалуйста.. harbour\tests\destruct.prg CREATE CLASS myClass VAR TYPE VAR var1 CLASS VAR var2 METHOD INIT DESTRUCTOR dtor END CLASS В harbour деструкторы как раз таки, есть и работают не плохо. В xhb из-за особенностей реализации HVM есть проблемы. Поэтому изучив xhb-diff, напичкав свой код #ifdef ваяете что-то не слишком замысловатое (оно же еще в multithread работать должно, а там опять грабли при переносе с одной системы на другую) или забиваете на классы и с помощью WinAPI/C API/PRG кода в старом добром процедурном стиле решаете нужную вам проблему и предлагаете ее Григорию для включения в MiniGUI.

SergKis: Петр Спасибо за подробное разъяснение "религии" hmg. "Забивать на классы" не получится (задачи тоже на них), теряюсь когда надо писать процедурным языком, отвык однако . Останется сложный переход на new версию hmg, если понадобится. Если заложить в hmg следующее: 1. Оставить введенные переменные _HMG_aFormMiskData1, _HMG_aFormMiskData2 b _HMG_aControlMiskData0 или зарезервировать места аналоги этих переменных и где сейчас заполнялись объектами эти переменные, сделать вызов блоков кода Eval(_HMG_bFormInit, k), Eval(_HMG_bControlInit, k). Где k index регистрации элемента. 2. В процедурах _DoWindowControlEventProcedure, _DoWindowEventProcedure, сделать как предлагал выше или хотя бы добавить параметры в вызов и Eval и ввести проверку i > 0 3. _EraseControl, _ReleaseWindow, там где вставлял свой код, добавить выполнение блоков кода Eval(_HMG_bControlErase, k) Eval(_HMG_bFormRelease, k) Названия переменных условное, так к примеру. Может что то еще упустил, но тогда WM_USER+..., действительно обрабатывать можно в своем MyEvent. Тогда классы можно вывести в пример и сгородить весь огород по сообщениям в примере.



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