Автор | Сообщение |
gfilatov
|
| модератор
|
Пост N: 699
Зарегистрирован: 25.05.05
|
|
Отправлено: 29.01.08 13:59. Заголовок: Новая версия Расширенного релиза библиотеки MiniGUI (часть VI ) (продолжение)
Начало темы находится здесь, а теперь АНОНС * АНОНС * АНОНС * АНОНС * АНОНС Готовится к опубликованию новая сборка №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
|
| постоянный участник
|
Пост N: 1542
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.06.17 09:19. Заголовок: gfilatov2002 Класс ..
gfilatov2002 Класс TKeyData в целом готов, выложу, для анализа и предложений сейчас Скрытый текст
/* * Создание объекта класса TKeyData, если задан параметр Obj, то в блоки кода * метода Do(...) передается значение Obj, иначе Self. */ *-----------------------------------------------------------------------------* FUNCTION oKeyData( Obj ) *-----------------------------------------------------------------------------* RETURN TKeyData():New(Obj) ////////////////////////////////////////////////////////////////////////////////////////////// CLASS TKeyData ////////////////////////////////////////////////////////////////////////////////////////////// PROTECTED: VAR oObj VAR aKey INIT hb_Hash() EXPORTED: VAR Cargo METHOD New( o ) INLINE ( ::oObj := iif( HB_ISOBJECT(o), o, Self ), Self ) CONSTRUCTOR METHOD Set( Key, Block ) INLINE hb_HSet( ::aKey, Key, Block ) METHOD Get( Key, Def ) INLINE hb_HGetDef( ::aKey, Key, Def ) METHOD Del( Key ) INLINE iif( hb_hHasKey( ::aKey, Key ), hb_HDel( ::aKey, Key ), ) METHOD Do ( Key, p1, p2, p3 ) BLOCK {|Self,Key,p1,p2,p3,b| b := ::Get(Key), ; iif( HB_ISBLOCK(b), EVal(b, ::oObj, Key, p1, p2, p3), Nil ) } ACCESS Obj INLINE ::oObj ASSIGN Obj( o ) INLINE ::oObj := iif( HB_ISOBJECT(o), o, Self ) ACCESS Len INLINE Len( ::aKey ) METHOD IsBLock( Key ) INLINE HB_ISBLOCK( ::Get(Key) ) _METHOD Eval( Block ) _METHOD Sum( Key, xSum ) _METHOD Destroy() #ifndef __XHARBOUR__ DESTRUCTOR Destroy() #endif ENDCLASS ////////////////////////////////////////////////////////////////////////////////////////////// /* * Выполнение блока кода Block над всеми элементами контейнера данных ::aKey. * Кодоблоку передаются ключ, значение и индекс. * Если параметр Block, не блок кода, возвращается массив значений, где * каждый элемент массив { ключ, значение, индекс } * Примеры использования в классе TWndData: * METHOD GetListType() * METHOD GetObj4Type( cType, lEque ) * METHOD GetObj4Name( cName ) */ METHOD Eval( Block ) CLASS TKeyData LOCAL i, b := HB_ISBLOCK(Block) LOCAL a := iif( b, Nil, array(0) ) For i := 1 To ::Len If b; Eval( Block, hb_HKeyAt( ::aKey, i ), hb_HValueAt( ::aKey, i ), i ) Else; aAdd( a, { hb_HKeyAt( ::aKey, i ), hb_HValueAt( ::aKey, i ), i } ) EndIf Next RETURN a /* * Выполнение операции суммирования над элементом контейнера данных с ключем Key. * xSum может быть числом или массивом, тогда суммируются только числовые элементы. * В качестве ключа можно использовать имена контролов, тогда возникает связка, при * событийном программировании, с событием заполнения Value контрола из контейнера. * Пример: Local o := oKeyData() * Local Als := oBrw1:cAlias * o:Sum("PRIHOD", { 0, 0, 0 }) * o:Sum("RASHOD", { 0, 0, 0 }) * DO WHILE ! Eof() * o:Sum("COUNT" , 1) * o:Sum("KOLVO" , (Als)->KOLVO) * o:Sum("SUMMA" , (Als)->SUMMA) * If (Als)->OPER == "PRI" * o:Sum("PRIHOD", { 1, (Als)->KOL_PRI, (Als)->SUM_PRI }) * ElseIf (Als)->OPER == "RAS" * o:Sum("RASHOD", { 1, (Als)->KOL_RAS, (Als)->SUM_RAS }) * EndIf * SKIP * ENDDO * ? o:Get("COUNT"), o:Get("KOLVO"), o:Get("SUMMA") * ? hb_valtoexp(o:Get("PRIHOD")) * ? hb_valtoexp(o:Get("RASHOD")) */ 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 /* * Освобождение собственных переменных объекта, устанавливаем в Nil. */ METHOD Destroy() CLASS TKeyData 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 ::oObj := ::aKey := ::Cargo := Nil RETURN Nil
|
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1543
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.06.17 09:22. Заголовок: PS _METHOD ... это у..
PS _METHOD ... это у меня #define _METHOD METHOD что бы не дублировались объявления с реальными методами при работе с проектом - список Entyti на экране
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1544
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.06.17 09:28. Заголовок: Петр Спасибо за DEST..
Петр Спасибо за DESTRUCTORв hb, работает.
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1545
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.06.17 13:01. Заголовок: SergKis пишет * П..
SergKis пишет цитата: | * Пример: Local o := oKeyData() * Local Als := oBrw1:cAlias * o:Sum("PRIHOD", { 0, 0, 0 }) * o:Sum("RASHOD", { 0, 0, 0 }) * DO WHILE ! Eof() * o:Sum("COUNT" , 1) * o:Sum("KOLVO" , (Als)->KOLVO) * o:Sum("SUMMA" , (Als)->SUMMA) * If (Als)->OPER == "PRI" * o:Sum("PRIHOD", { 1, (Als)->KOL_PRI, (Als)->SUM_PRI }) * ElseIf (Als)->OPER == "RAS" * o:Sum("RASHOD", { 1, (Als)->KOL_RAS, (Als)->SUM_RAS }) * EndIf * SKIP * ENDDO * ? o:Get("COUNT"), o:Get("KOLVO"), o:Get("SUMMA") * ? hb_valtoexp(o:Get("PRIHOD")) * ? hb_valtoexp(o:Get("RASHOD")) |
| Если дополнить * Пример: Local o := oKeyData() * o:Set('bItog', {|o,p1,p2,p3| ToItog(o,p1,p2,p3) } ) ... * ? hb_valtoexp(o:Get("RASHOD")) * o:Do('bItog', 'Harbour', 'MiniGui', 'OK!') то повесив в new версии эту ф-ю на APPEVENT от Петра, можно в блоке кода скинуть, полученные итоги на контролы, которым были даны имена ключей (в блоке можем сделать): FUNC ToItog( o, cH, cM, cO ) ? o:ClassName, cH, cM, cO ? o:Get("COUNT"), o:Get("KOLVO"), o:Get("SUMMA") ? hb_valtoexp(o:Get("PRIHOD")) ? hb_valtoexp(o:Get("RASHOD")) _SetValue('COUNT', 'win_1', cValToChar(o:Get("COUNT"))) ...
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1546
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.06.17 13:32. Заголовок: PS в ToItog можно и ..
PS в ToItog можно и так вывести данные на контролы цитата: | AEval(o:Eval(), {|ky,uv,ni| win_1.&(ky).Value := cValToChar(uv), ni := ky }) |
|
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1547
Зарегистрирован: 17.02.12
|
|
Отправлено: 17.06.17 14:40. Заголовок: Кому интересно. Выкл..
Кому интересно. Выкладываю классы для vm и vmmt режимов hb. Скрытый текст
*-----------------------------------------------------------------------------* FUNCTION oWndData( nIndex, cName, nHandle, nParent, cType, cVar, oWin, lVmMt ) *-----------------------------------------------------------------------------* LOCAL o Default nIndex := 0, ; cName := '', ; nHandle := 0, ; nParent := 0, ; cType := '', ; cVar := '', ; lVmMt := hb_mtvm() If ! HB_ISOBJECT( oWin ) // window o := TWndData():New():Def( nIndex, cName, nHandle, nParent, cType, cVar, lVmMt ) Else // control o := TCnlData():New():Def( nIndex, cName, nHandle, nParent, cType, cVar, oWin, lVmMt ) If ! Empty(o:Name) .and. ! Empty(o:Handle) If o:Type == 'TBROWSE' o:TBrowse := _HMG_aControlIds [ o:Index ] EndIf o:Set() EndIf EndIf RETURN o /////////////////////////////////////////////////////////////////////////////// CLASS TWndData /////////////////////////////////////////////////////////////////////////////// PROTECTED: VAR cVar VAR cName VAR cType VAR nIndex VAR nHandle VAR nParent VAR cChr INIT ',' VAR lMT INIT .F. CLASSDATA oName INIT oKeyData() CLASSDATA oHand INIT oKeyData() EXPORTED: VAR oCargo VAR oUserKeys VAR oEvent METHOD New() INLINE Self CONSTRUCTOR METHOD Def( nIndex, cName, nHandle, nParent, cType, cVar, lVmMt ) INLINE ( ; ::nIndex := nIndex , ::cName := cName, ::nHandle := nHandle, ; ::nParent := nParent, ::cType := cType, ::cVar := cVar, ; ::oCargo := oKeyData(), ::oUserKeys := oKeyData(), ; ::oEvent := oKeyData( Self ), ::MT := lVmMt, ; Self ) ACCESS MT INLINE ::lMT ASSIGN MT( lVmMt ) INLINE ( ::lMT := iif( HB_ISLOGICAL(lVmMt), lVmMt, .F. ), ; ::oName:MT := ::lMT, ::oHand:MT := ::lMT, ; ::oCargo:MT := ::lMT, ::oEvent:MT := ::lMT, ; ::oUserKeys:MT := ::lMT ) ACCESS Index INLINE ::nIndex ACCESS Name INLINE ::cName ACCESS Handle INLINE ::nHandle ACCESS Parent INLINE ::nParent ACCESS Type INLINE ::cType ACCESS VarName INLINE ::cVar ACCESS Row INLINE GetWindowRow ( ::nHandle ) ACCESS Col INLINE GetWindowCol ( ::nHandle ) ACCESS Width INLINE GetWindowWidth ( ::nHandle ) ACCESS Height INLINE GetWindowHeight( ::nHandle ) ACCESS ClientWidth INLINE _GetClientRect ( ::nHandle )[ 3 ] ACCESS ClientHeight INLINE _GetClientRect ( ::nHandle )[ 4 ] ACCESS Title INLINE GetWindowText ( ::nHandle ) ACCESS Cargo INLINE _WindowCargo( Self ) ASSIGN Cargo( xVal ) INLINE _WindowCargo( Self, xVal ) ACCESS IsWindow INLINE .T. ACCESS IsControl INLINE .F. ACCESS Chr INLINE ::cChr ASSIGN Chr( cChr ) INLINE ::cChr := iif( HB_ISCHAR(cChr), cChr, ::cChr ) ACCESS WM_nMsgW INLINE WM_HMG_USER_MSG_W ACCESS WM_nMsgC INLINE WM_HMG_USER_MSG_C METHOD UserKeys( Key, Block, p2, p3 ) INLINE iif( HB_ISBLOCK( Block ), ; ::oUserKeys:Set( Key, Block ), ; ::oUserKeys:Do ( Key, Block, p2, p3 ) ) METHOD Event ( Key, Block, p2, p3 ) INLINE iif( HB_ISBLOCK( Block ), ; ::oEvent:Set( Key, Block ), ; ::oEvent:Do ( Key, Block, p2, p3 ) ) METHOD PostMsg( nKey, nHandle, lMsgW ) INLINE ( lMsgW := lMsgW == Nil .or. !Empty(lMsgW), ; lMsgW := empty(nHandle) .or. lMsgW, ; PostMessage( ::nHandle, iif( lMsgW, ::WM_nMsgW, ::WM_nMsgC ), nKey, ; hb_defaultValue(nHandle, 0) ) ) METHOD SendMsg( nKey, nHandle, lMsgW ) INLINE ( lMsgW := lMsgW == Nil .or. !Empty(lMsgW), ; lMsgW := empty(nHandle) .or. lMsgW, ; SendMessage( ::nHandle, iif( lMsgW, ::WM_nMsgW, ::WM_nMsgC ), nKey, ; hb_defaultValue(nHandle, 0) ) ) _METHOD DoEvent( Key, nHandle, nParam, cEvent ) _METHOD GetListType() _METHOD GetObj4Type( cType ) _METHOD GetObj4Name( cName ) METHOD GetObj( xName ) INLINE iif( HB_ISCHAR(xName), ::oName:Get(xName), ; ::oHand:Get(xName) ) _METHOD DelProperty( cName ) _METHOD AddProperty( cName, xVal ) _METHOD DelMethod( cMethod ) _METHOD AddMethod( cMethod, pFunct ) METHOD Destroy() INLINE ( ::oCargo:Destroy(), ::oUserKeys:Destroy(), ; ::oHand:Destroy(), ::oName:Destroy(), ::oEvent:Destroy(), ; ::cChr := ::cName := ::oName := ::oHand := ::cVar := Nil, ; ::oUserKeys := ::oEvent := ::cType := ::oCargo := Nil, ; ::nIndex := Nil, ::nHandle := Nil, ::nParent := Nil ) ENDCLASS /////////////////////////////////////////////////////////////////////////////// METHOD AddMethod( cMethod, pFunct ) CLASS TWndData LOCAL o := Self If HB_ISCHAR( cMethod ) .and. ! __ObjHasMsg( o, cMethod ) RETURN ! Empty( __objAddMethod( o, cMethod, pFunct ) ) ENDIF RETURN .F. METHOD DelMethod( cMethod ) CLASS TWndData LOCAL o := Self If HB_ISCHAR( cMethod ) .and. __ObjHasMsg( o, cMethod ) RETURN Empty( __objDelMethod( o, cMethod ) ) ENDIF RETURN .F. METHOD AddProperty( cName, xVal ) CLASS TWndData LOCAL o := Self If HB_ISCHAR( cName ) .and. ! __objHasData( o, cName ) If ! Empty( __objAddData( o, cName ) ) RETURN ! Empty( __ObjSetValueList( o, { cName, xVal } ) ) EndIf EndIf RETURN .F. METHOD DelProperty( cName ) CLASS TWndData LOCAL o := Self If HB_ISCHAR( cName ) .and. __objHasData( o, cName ) RETURN Empty( __objDelData( o, cName ) ) EndIf RETURN .F. METHOD GetListType() CLASS TWndData LOCAL oType := oKeyData() LOCAL aType := {} ::oName:Eval({|k,o,i| k := i, oType:Set(o:cType, o:cType) }) oType:Eval({|k,v,i| k := i, aAdd(aType, v) }) oType:Destroy() oType := Nil RETURN aType METHOD GetObj4Type( cType, lEque ) CLASS TWndData LOCAL aObj := {} If ! empty(cType) lEque := hb_defaultValue(lEque, .T.) If ::cChr $ cType; lEque := .F. EndIf FOR EACH cType IN hb_ATokens(upper(cType), ::cChr) ::oName:Eval({|ky,oc,ni| ky := ni, iif( lEque, iif( cType == oc:cType, aAdd(aObj, oc), ), ; iif( cType $ oc:cType, aAdd(aObj, oc), ) ) }) NEXT EndIf RETURN aObj METHOD GetObj4Name( cName ) CLASS TWndData LOCAL aObj := {} If ! empty(cName) FOR EACH cName IN hb_ATokens(cName, ::cChr) ::oName:Eval({|ky,oc,ni| ky := ni, iif( cName $ oc:cName, aAdd(aObj, oc), Nil ) }) NEXT EndIF RETURN aObj METHOD DoEvent ( Key, nHandle, nParam, cEvent ) CLASS TWndData LOCAL o, lW := .T. nParam := iif( HB_ISNUMERIC(nParam), nParam, 0 ) cEvent := hb_defaultValue(cEvent, '') If ! empty(nHandle) o := _ControlObj(nHandle) If HB_ISOBJECT(o); lW := .F. EndIf EndIf If ! HB_ISOBJECT(o); o := Self EndIf If lW; _DoWindowEventProcedure ( ::oEvent:Get(Key), o:Index, cEvent, nParam, o ) Else ; _DoControlEventProcedure( ::oEvent:Get(Key), o:Index, cEvent, nParam, o ) EndIf RETURN Nil /////////////////////////////////////////////////////////////////////////////// CLASS TCnlData INHERIT TWndData /////////////////////////////////////////////////////////////////////////////// PROTECTED: VAR oWin VAR oTBrowse EXPORTED: METHOD New() INLINE Self CONSTRUCTOR METHOD Def( nIndex, cName, nHandle, nParent, cType, cVar, oWin, lVmMt ) INLINE ( ; ::Super:Def(nIndex, cName, nHandle, nParent, cType, cVar, lVmMt), ; ::oWin := oWin, ; Self ) CONSTRUCTOR ACCESS Title INLINE ::oWin:cTitle ACCESS Caption INLINE iif( ::cType == 'TBROWSE', ; ::oWin:cName + "." + ::cName, ; _GetCaption( ::cName, ::oWin:cName ) ) ACCESS Cargo INLINE _ControlCargo( , ::nIndex ) ASSIGN Cargo( xVal ) INLINE _ControlCargo( , ::nIndex, xVal ) ACCESS Window INLINE ::oWin ACCESS IsWindow INLINE .F. ACCESS IsControl INLINE .T. METHOD PostMsg( nKey ) INLINE PostMessage( ::oWin:nHandle, ::WM_nMsgC, nKey, ::nHandle ) METHOD SendMsg( nKey ) INLINE SendMessage( ::oWin:nHandle, ::WM_nMsgC, nKey, ::nHandle ) METHOD Set() INLINE ( ::oName:Set( ::cName , Self ), ; ::oHand:Set( ::nHandle, Self ) ) METHOD Del() INLINE ( ::oName:Del( ::cName ), ; ::oHand:Del( ::nHandle ) ) ACCESS TBrowse INLINE ::oTBrowse ASSIGN TBrowse( oBrw ) INLINE ::oTBrowse := oBrw ACCESS Value INLINE _GetValue( , , ::nIndex ) ASSIGN Value( xVal ) INLINE _SetValue( , , xVal, ::nIndex, .T. ) ACCESS SetFocus INLINE _SetFocus ( ::cName, ::oWin:cName ) METHOD SetFocus() INLINE _SetFocus ( ::cName, ::oWin:cName ) METHOD Disable( nPos ) INLINE _DisableControl( ::cName, ::oWin:cName, nPos ) METHOD Enable ( nPos ) INLINE _EnableControl ( ::cName, ::oWin:cName, nPos ) ACCESS Show INLINE _ShowControl ( ::cName, ::oWin:cName ) METHOD Show() INLINE _ShowControl ( ::cName, ::oWin:cName ) ACCESS Hide INLINE _HideControl ( ::cName, ::oWin:cName ) METHOD Hide() INLINE _HideControl ( ::cName, ::oWin:cName ) METHOD Destroy() INLINE ( ::oCargo:Destroy() , ::oEvent:Destroy(), ; ::oUserKeys:Destroy(), ::oUserKeys := Nil, ; ::oCargo := ::oEvent := ::cChr := Nil, ; ::nIndex := ::cName := ::cType := Nil, ; ::nHandle := ::nParent := ::cVar := Nil ) ENDCLASS /* * Создание объекта класса TKeyData, если задан параметр Obj, то в блоки кода * метода Do(...) передается значение Obj, иначе Self. * Для использования в потоках, задаем значение параметра lVmMt := hb_mtvm(). */ *-----------------------------------------------------------------------------* FUNCTION oKeyData( Obj, lVmMt ) *-----------------------------------------------------------------------------* RETURN TKeyData():New():Def(Obj, lVmMt) ////////////////////////////////////////////////////////////////////////////////////////////// CLASS TKeyData ////////////////////////////////////////////////////////////////////////////////////////////// PROTECTED: VAR oObj VAR aKey INIT hb_Hash() VAR lMT INIT .F. SYNC METHOD SGD( n, k, v ) EXPORTED: VAR Cargo METHOD New() INLINE ( Self ) CONSTRUCTOR METHOD Def( o, lVmMt ) INLINE ( ::Obj := o, ::MT := lVmMt, Self ) METHOD Set( Key, Block ) INLINE iif( ::lMT, ::SGD( 1, Key, Block ), hb_HSet ( ::aKey, Key, Block ) ) METHOD Get( Key, Def ) INLINE iif( ::lMT, ::SGD( 2, Key, Def ), hb_HGetDef( ::aKey, Key, Def ) ) METHOD Del( Key ) INLINE iif( ::lMT, ::SGD( 3, Key ), ; iif( hb_hHasKey( ::aKey, Key ), hb_HDel ( ::aKey, Key ), Nil ) ) METHOD Do ( Key, p1, p2, p3 ) BLOCK {|Self,Key,p1,p2,p3,b| b := ::Get(Key), ; iif( HB_ISBLOCK(b), EVal(b, ::oObj, Key, p1, p2, p3), Nil ) } ACCESS MT INLINE ::lMT ASSIGN MT( lVmMt ) INLINE ::lMT := iif( HB_ISLOGICAL(lVmMt), lVmMt, .F. ) ACCESS Obj INLINE ::oObj ASSIGN Obj( o ) INLINE ::oObj := iif( HB_ISOBJECT(o), o, Self ) ACCESS Len INLINE Len( ::aKey ) METHOD IsBLock( Key ) INLINE HB_ISBLOCK( ::Get(Key) ) _METHOD Eval( Block ) _METHOD Sum( Key, xSum ) _METHOD Destroy() #ifndef __XHARBOUR__ DESTRUCTOR Destroy() #endif ENDCLASS ////////////////////////////////////////////////////////////////////////////////////////////// /* * Для работы в потоках, синхронизируется доступ к контейнеру ::aKey */ METHOD SGD( n, k, v ) CLASS TKeyData SWITCH n CASE 1 hb_HSet( ::aKey, k, v ) EXIT CASE 2 RETURN hb_HGetDef( ::aKey, k, v ) EXIT CASE 3 If hb_hHasKey( ::aKey, k ) hb_HDel ( ::aKey, k ) EndIf EXIT CASE 4 RETURN { hb_HKeyAt( ::aKey, k ), hb_HValueAt( ::aKey, k ) } EXIT END RETURN Nil /* * Выполнение блока кода Block над всеми элементами контейнера данных ::aKey. * Кодоблоку передаются ключ, значение и индекс. * Если параметр Block, не блок кода, возвращается массив значений, где * каждый элемент массив { ключ, значение, индекс } * Примеры использования в классе TWndData: * METHOD GetListType() * METHOD GetObj4Type( cType, lEque ) * METHOD GetObj4Name( cName ) */ METHOD Eval( Block ) CLASS TKeyData LOCAL m, i, b := HB_ISBLOCK(Block) LOCAL a := iif( b, Nil, array(0) ) For i := 1 To ::Len If ::lMT m := ::SGD( 4, i ) If b; Eval( Block, m[ 1 ], m[ 2 ], i ) Else; aAdd( a, { m[ 1 ], m[ 2 ], i } ) EndIf Else If b; Eval( Block, hb_HKeyAt( ::aKey, i ), hb_HValueAt( ::aKey, i ), i ) Else; aAdd( a, { hb_HKeyAt( ::aKey, i ), hb_HValueAt( ::aKey, i ), i } ) EndIf EndIf Next RETURN a /* * Выполнение операции суммирования над элементом контейнера данных с ключем Key. * xSum может быть числом или массивом, тогда суммируются только числовые элементы. * В качестве ключа можно использовать имена контролов, тогда возникает связка, при * событийном программировании, с событием заполнения Value контрола из контейнера. * Пример: Local o := oKeyData() * Local Als := oBrw1:cAlias * o:Sum("PRIHOD", { 0, 0, 0 }) * o:Sum("RASHOD", { 0, 0, 0 }) * DO WHILE ! Eof() * o:Sum("COUNT" , 1) * o:Sum("KOLVO" , (Als)->KOLVO) * o:Sum("SUMMA" , (Als)->SUMMA) * If (Als)->OPER == "PRI" * o:Sum("PRIHOD", { 1, (Als)->KOL_PRI, (Als)->SUM_PRI }) * ElseIf (Als)->OPER == "RAS" * o:Sum("RASHOD", { 1, (Als)->KOL_RAS, (Als)->SUM_RAS }) * EndIf * SKIP * ENDDO * ? o:Get("COUNT"), o:Get("KOLVO"), o:Get("SUMMA") * ? hb_valtoexp(o:Get("PRIHOD")) * ? hb_valtoexp(o:Get("RASHOD")) */ 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 /* * Освобождение собственных переменных объекта, устанавливаем в Nil. */ METHOD Destroy() CLASS TKeyData 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 ::oObj := ::aKey := ::Cargo := Nil RETURN Nil
| Пример, который выкладывал ранее, работает и там и там.
| |
|
Andrey
|
| постоянный участник
|
Пост N: 5417
Зарегистрирован: 12.09.06
|
|
Отправлено: 17.06.17 14:57. Заголовок: SergKis пишет: Кому..
SergKis пишет: цитата: | Кому интересно. Выкладываю классы для vm и vmmt режимов hb. |
| Да всем будет интересно. Не сейчас, так позже понадобиться. gfilatov пишет: цитата: | Если у Вас есть интересные наработки для включения в новый релиз, то сейчас самое удобное время для их отправки мне |
| Григорий включи пожалуйста в библиотеку. А то проработанные и хорошие идеи пропадают !
| |
|
Петр
|
| постоянный участник
|
Пост N: 1525
Зарегистрирован: 09.10.06
|
|
Отправлено: 17.06.17 23:26. Заголовок: Andrey пишет: А то ..
Andrey пишет: цитата: | А то проработанные и хорошие идеи пропадают ! |
| На счет хорошие или нет - не скажу, не знаю, а вот чтобы проработанные - это еще вопрос. SergKiss скажите, вот у вас обьекты создаются по такой схеме *-----------------------------------------------------------------------------* FUNCTION oKeyData( Obj, lVmMt ) *-----------------------------------------------------------------------------* RETURN TKeyData():New():Def(Obj, lVmMt) Т.е. у вас метод Def фактически является конструктором Скажите почему вы игнорируете подсказку разработчика "and please remember that :NEW() will be class method so it should not be redefined as constructor in user class. Instead :INIT() method should be used as constructor. It's executed automatically when object is created from the :NEW() method." Какой смысл вы вкладываете в существование такого кода ACCESS MT INLINE ::lMT ASSIGN MT( lVmMt ) INLINE ::lMT := iif( HB_ISLOGICAL(lVmMt), lVmMt, .F. ) а такого ACCESS Obj INLINE ::oObj ASSIGN Obj( o ) INLINE ::oObj := iif( HB_ISOBJECT(o), o, Self ) такого ACCESS Show INLINE _ShowControl ( ::cName, ::oWin:cName ) METHOD Show() INLINE _ShowControl ( ::cName, ::oWin:cName ) PS. Если ответ будет типа: и так работает; боюсь, что вы не поймете; некогда думать, надо по клаве стучать или "вам шашечки или ехать" - оставьте, пожалуйста, вопросы без внимания.
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1548
Зарегистрирован: 17.02.12
|
|
Отправлено: 18.06.17 14:36. Заголовок: Петр Спасибо за кон..
Петр Спасибо за конкретные вопросы. цитата: | такого ACCESS Show INLINE _ShowControl ( ::cName, ::oWin:cName ) METHOD Show() INLINE _ShowControl ( ::cName, ::oWin:cName ) |
| Это аналог (как в псевдо ООП на препроцессоре) исп. o:Show и o:Show() цитата: | а такого ACCESS Obj INLINE ::oObj ASSIGN Obj( o ) INLINE ::oObj := iif( HB_ISOBJECT(o), o, Self ) |
| 1. Я скрыл, что вн. переменная имеет префикс oObj - хранение объектов 2. access\assign предполагает, что в дальнейшем, я должен использовать везде, в том числе и внутри класса только эти определения. Что бы в дальнейшем, подправив\изменив assign мне не требовалось править весь текст класса, а еще хуже программы. Я, кстати, нарушил это правило (что не есть хорошо), но только по причине, что классы небольшие. цитата: | Какой смысл вы вкладываете в существование такого кода ACCESS MT INLINE ::lMT ASSIGN MT( lVmMt ) INLINE ::lMT := iif( HB_ISLOGICAL(lVmMt), lVmMt, .F. ) |
| Не очень понимаю вопрос. Делал так, по причине, не привязываться к ф-ии hb_mtvm() внутри класса, не знаю как она называется в xhb, но главное, считаю (во многих случаях), что в среде vmmt, вполне можно работать без совместного доступа к классам - это в руках делающего программу. К примеру, если в потоке создаем окно с сопутствующими классами, то не х... лезть в него из др. потоков. Если очень надо, для этого есть сообщения, т.е. послали по handle и пусть идет ... А делать всегда совместный доступ - это удорожание продукта, трата времени и ... цитата: | вот у вас обьекты создаются по такой схеме *-----------------------------------------------------------------------------* FUNCTION oKeyData( Obj, lVmMt ) *-----------------------------------------------------------------------------* RETURN TKeyData():New():Def(Obj, lVmMt) Т.е. у вас метод Def фактически является конструктором |
| Мы в процедурной среде. oKeyData(...) это аналог функций _Difine...(...). Кстати, забыл, а надо бы добавить и можно это сделать не залезая в класс FUNCTION oKeyData( Obj, lVmMt ) *-----------------------------------------------------------------------------* Default lVmMt := hb_mtvm() RETURN TKeyData():New():Def(Obj, lVmMt) Нет, конструктором является :New(), то что он пустышка - это частный случай Если бы сделал METHOD New( nIndex, cName, nHandle, nParent, cType, cVar, lVmMt ) INLINE ( ; ::nIndex := nIndex , ::cName := cName, ::nHandle := nHandle, ; ::nParent := nParent, ::cType := cType, ::cVar := cVar, ; ::oCargo := oKeyData(), ::oUserKeys := oKeyData(), ; ::oEvent := oKeyData( Self ), ::MT := lVmMt, ; Self ) то исп. в нем ::MT := lVmMt было бы не очень правильно, т.к. конструктор не закончился, а мы суем ему уже разные внутренние конструкции. А написав (фактически продублировав свойство assign) мы в будущем могли попасть на неприятности, модификации дубляжа. Потому применение Def вполне оправдано, а честнее, только так и надо поступать. Утрированный пример. Делаем (не в среде hmg) o := oWndData(....) для окна A, поработали, надо также поработать с окном Б, можем создавать новыу переменную окна, а можем вызвать :Def(...) существующего и по тому же тексту, что работал с А отработать Б. Еще про access\assign. Имеем ACCESS AAAA INLINE .... ASSIGN AAAA( p ) INLINE .... используем по полной и через время понадобилось немного изменить, но не влазит по потребностям в assign, то подправить ситуевину можно добавив METHOD AAAA( p, p1 ) INLINE ... и старое работает и новое есть. При исп. (хорошая команда) SETGET мы имеем чуть другое
| |
|
Петр
|
| постоянный участник
|
Пост N: 1526
Зарегистрирован: 09.10.06
|
|
Отправлено: 18.06.17 16:22. Заголовок: SergKis пишет: Это ..
SergKis пишет: цитата: | Это аналог (как в псевдо ООП на препроцессоре) исп. o:Show и o:Show() |
| Т.е. ради сомнительного синтаксического сиропа вы просто так добавили еще один метод, который и не нужен честно говоря. SergKis пишет: цитата: | 1. Я скрыл, что вн. переменная имеет префикс oObj - хранение объектов 2. access\assign предполагает, что в дальнейшем, я должен использовать везде, в том числе и внутри класса |
| От кого вы скрыли, oObj находится в PROTECTED и не может использоваться вне класса. Но я, вообще-то, не о том. Вот как только вы открыли свой код для других можете быть уверенны, что кто-то воспользуется не так как надо. Почему в ASSIGN нет никаких проверок и в чем прикол хранить в переменной обьекта ссылку на сам обьект? SergKis пишет: цитата: | Не очень понимаю вопрос. Делал так, по причине, не привязываться к ф-ии hb_mtvm() внутри класса, не знаю как она называется в xhb, но главное, считаю (во многих случаях), что в среде vmmt, вполне можно работать без совместного доступа к классам - это в руках делающего программу. К примеру, если в потоке создаем окно с сопутствующими классами, то не х... лезть в него из др. потоков. Если очень надо, для этого есть сообщения, т.е. послали по handle и пусть идет ... А делать всегда совместный доступ - это удорожание продукта, трата времени и ... |
| Это все ИМХО. Вы, я и др. не можем управлять многопоточностью в своей программе. Вот прилинковали соотв. библиотеку и от этого пляшем. Ну если вам так нужна эта lVmMt (мое мнение - не нужна ) то можно просто добавить, не раздувая класса CLASSVAR lVmMt INIT hb_mtvm() READONLY
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1549
Зарегистрирован: 17.02.12
|
|
Отправлено: 18.06.17 17:41. Заголовок: Петр пишет Т.е. ради..
Петр пишет цитата: | Т.е. ради сомнительного синтаксического сиропа вы просто так добавили еще один метод, который и не нужен честно говоря. |
| Если вы считаете, что привыкнув писать с псевдо ООП .Show или .Show(), дадим только:Show(), нет вопросов убирайте. А "добавили еще один метод, который и не нужен честно говоря" - это из серии "сколько бухгалтеров столько и бухгалтерий". цитата: | От кого вы скрыли, oObj находится в PROTECTED и не может использоваться вне класса. |
| Вообще то, есть правила хорошего тона при программировании, сообщать, что хранится в веденной переменной. Введя o я сказал, что там объект и не надо делать операций проверок и не важно в какой области класса эта переменная. Что бы не было как TsColumn :nAlign - вроде для числа, а там и блоки и ...., про TsBrowse вообще молчу. цитата: | Почему в ASSIGN нет никаких проверок и в чем прикол хранить в переменной обьекта ссылку на сам обьект? |
| Про какое место разговор. если про TKeyData, то я написал "то в блоки кода метода Do(...) передается значение Obj, иначе Self. " и применил METHOD Def( nIndex, cName, nHandle, nParent, cType, cVar, lVmMt ) INLINE ( ; ::nIndex := nIndex , ::cName := cName, ::nHandle := nHandle, ; ::nParent := nParent, ::cType := cType, ::cVar := cVar, ; ::oCargo := oKeyData(), ::oUserKeys := oKeyData(), ; ::oEvent := oKeyData( Self ), ::MT := lVmMt, ; Self ) т.е. в блоки кода будет передан объект окна или контрола, а не только свой Self. Вы можете иметь свой объект, иметь набор блоков для исполнения с каким то др. объектом, вы можете выполнить те же блоки со своим, сделав o:Obj := <ваш объект> цитата: | CLASSVAR lVmMt INIT hb_mtvm() READONLY |
| Я сказал ранее, повторю, не хочу связывать объект с функцией hb_mtvm(), т.к. это связывает руки при использовании класса. Я, к примеру, в потоках не буду использовать совместно данные объектов, т.е. даже в vmmt у меня будет всегда .F. Я предлагал _HMG_MainCargo := oKeyData() _HMG_MainCargo:Set('bFormInit', Nil) _HMG_MainCargo:Set('bFormDestroy', Nil) _HMG_MainCargo:Set('bControlInit', Nil) _HMG_MainCargo:Set('bControlDestroy', Nil) можно подправить и добавить _HMG_MainCargo := oKeyData( , hb_mtvm()) _HMG_MainCargo:Set('lModeVmMt', .F.) или hb_mtvm() и в функциях oWndData, oKeyData заменить Default lVmMt := _HMG_MainCargo:Get('lModeVmMt') ...
| |
|
|
Петр
|
| постоянный участник
|
Пост N: 1527
Зарегистрирован: 09.10.06
|
|
Отправлено: 18.06.17 23:23. Заголовок: SergKis пишет: Если..
SergKis пишет: цитата: | Если вы считаете, что привыкнув писать с псевдо ООП .Show или .Show(), дадим только:Show(), нет вопросов убирайте. |
| Кто вам сказал, что все убегут с псевдо на ООП? Вы используйте рационально ресурсы компьютера и все, всех остальных компилятор быстро научит "родину любить". SergKis пишет: цитата: | Вообще то, есть правила хорошего тона при программировании, сообщать, что хранится в веденной переменной. Введя o я сказал, что там объект и не надо делать операций проверок и не важно в какой области класса эта переменная. Что бы не было как TsColumn :nAlign - вроде для числа, а там и блоки и ...., про TsBrowse вообще молчу. |
| Венгерская нотация еще никому ничего не гарантировала, тем более в нетипизированных языках. В METHOD Destroy() CLASS TKeyData тогда зачем проверок напихали? Может опять какой то префикс замутить и хватит. Типа VAR aKey INIT hb_Hash() Так, что за необходимость хранить в переменной обьекта ссылку на сам обьект? цитата: | ASSIGN Obj( o ) INLINE ::oObj := iif( HB_ISOBJECT(o), o, Self ) |
| SergKis пишет: цитата: | если про TKeyData, то я написал "то в блоки кода метода Do(...) передается значение Obj, иначе Self. " и применил METHOD Def |
| Ну написали, я прочитал и что? Почему так "кучеряво" написали? цитата: | Я сказал ранее, повторю, не хочу связывать объект с функцией hb_mtvm(), т.к. это связывает руки при использовании класса. Я, к примеру, в потоках не буду использовать совместно данные объектов, т.е. даже в vmmt у меня будет всегда .F. |
| Какие руки (oHand?), каким образом? Эта функция линкуется в любой harbour бинарник при использовании ключа -mt. Прямой ее вызов в нужном месте "дешевле" хранения стандартных переменных и тем более переменных обьекта, не говоря про методы ACCESS MT INLINE ::lMT ASSIGN MT( lVmMt ) INLINE ::lMT := iif( HB_ISLOGICAL(lVmMt), lVmMt, .F. ) Вот вы не собираетесь использовать, я тоже, если Андрею придется использовать TKeyData в mt режиме и у него будет .T., может он рассчитывать на безопасность этого класса? И если да, то чем вы ее обеспечили?
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1550
Зарегистрирован: 17.02.12
|
|
Отправлено: 19.06.17 15:25. Заголовок: Петр пишет Венгерс..
Петр пишет цитата: | Венгерская нотация еще никому ничего не гарантировала, тем более в нетипизированных языках Так, что за необходимость хранить в переменной обьекта ссылку на сам обьект? Ну написали, я прочитал и что? Почему так "кучеряво" написали? |
| ASSIGN Obj( o ) INLINE ::oObj := iif( HB_ISOBJECT(o), o, Self ) как раз и гарантирует "венгерскую нотацию", обеспечивая в переменной объект. o := oKeyData({||...}) или o:Obj := {||...} кроме объекта иное не пройдет. потому везде смело работайте с o:Obj как с объектом, без проверок типов. Объсню "кучерявость". Смысл :Obj в том, что он передается в блок кода, который зарегистририван в :aKey (их, блоков, может быть много). Если менять в :Obj ссылку с Self на ссылку др. объекта, то блоки, при выполнении, будут получать уже этот объект по ссылке. Т.е. когда создается объект TWndData\TCnlData, работает метод :Def(...), создаются объекты контейнеры CLASSDATA oName INIT oKeyData() CLASSDATA oHand INIT oKeyData() ::oCargo := oKeyData() ::oUserKeys := oKeyData() для этих в :Obj будет собственный адрес объекта Self ::oEvent := oKeyData( Self ) этот занесет в :Obj значения адреса объекта, в зависимости от того, какой объект создается TWndData или TCnlData. Таким образом решается вопрос передачи в события нужного объекта, т.е. блоки коды событий, зарегистрированные на окно, получат объект своего окна. К примеру события окна win_1 получат, в блоке кода, ссылку на объект win_1, для win_2 и т.д. будет тоже самое, т.е. доступны o:Index, o:Handle, o:Name, ... окна. Точно так же работают зарегестрированные события (блоки кода) и на контролах, т.е в блоке кода будет объект собственного контрола, т.е. доступны o:Index, o:Handle, o:Name, ... контрола. Это основное предназначение :Obj. Но можно делать и так: Пример. Имеем oBrw1 на окне 1, он решает задачи (в блоках кода), зарегистированные в o := oKeyData(oBrw1) o:Set("Ras4et1", {|ob,ky| ... }) o:Set("Ras4et2", {|ob,ky| ... }) o:Set("Ras4et3", {|ob,ky| ... }) ... На каких то событиях, а может просто где то, используем: в oBrw1 ставим нужные пользователю scope, filter ... и считаем o:Do("Ras4et1", {|ob,ky| ... }) o:Do("Ras4et2", {|ob,ky| ... }) o:Do("Ras4et3", {|ob,ky| ... }) результаты куда то отправляем На др. окнах тот же тсб будет иметь имя oBrw2 или другое, сделав o:Obj := oBrw2 можно выполнять теже блоки, они получат ссылку на объект oBrw2. ... С любым обектом можете проделать такое же. Даже объект TaskDialog можно передать. цитата: | В METHOD Destroy() CLASS TKeyData тогда зачем проверок напихали? |
| Если использовали :Cargo как oKeyData(), я проделываю все как с :aKey. Для hb хватило бы и o := Nil или уничтожение локальной переменной, приводило бы к автоматическому вызову :Destroy(). Но в xhb, от вас узнал, этого нет, поэтому, как вы говорите, "понапихал" принудительные вызовы Destroy(), значит возможны "лишние" вызовы, это просто учтено в Destroy(). METHOD GetListType() CLASS TWndData LOCAL oType := oKeyData() LOCAL aType := {} ::oName:Eval({|k,o,i| k := i, oType:Set(o:cType, o:cType) }) oType:Eval({|k,v,i| k := i, aAdd(aType, v) }) oType:Destroy() oType := Nil RETURN aType выделенное для hb можно не делать цитата: | Эта функция линкуется в любой harbour бинарник при использовании ключа -mt Прямой ее вызов в нужном месте "дешевле" хранения стандартных переменных и тем более переменных обьекта |
| Причем здесь линкование hb_mtvm() ? Если я, сделаю, как вы предлагали, зашить в класс hb_mtvm CLASSVAR lVmMt INIT hb_mtvm() READONLY Возможно, что вы что то удешивили, но получили только 2-а состояния .T. и .F. А, я, хотел получить ИМЕННО внешнее управление, что бы при hb_mtvm() .T., поставить в объект окна\контрола - .F. Причем здесь "дешевле", если это удобно, минимум ЧЕЛОВЕЧЕСКИХ затрат и решаются просто, это так же относится и .Show, .Show(), :Show, :Show(), ... . Что вы пытаетесь экономить ? Все классы hb просто небольшие, в сравнении с классами VO со строгим стилем программирования. Программы VO как и clipper шустро работали на очень слабеньких машинах. цитата: | Вот вы не собираетесь использовать, я тоже, если Андрею придется использовать TKeyData в mt режиме и у него будет .T., может он рассчитывать на безопасность этого класса? И если да, то чем вы ее обеспечили? |
| Я был бы рад, сказать, Я ОБЕСПЕЧИЛ ...), но к радости это обеспечивает hb, вернее SYNC METHOD ... . hb обеспечивает синхронизацию выполнения мтодов в потоках (на мутексах). Потому с классом TKeyData должно быть все хорошо в mt, синхронизированный метод доступа к контейнеру :aKey организован. Следовательно и TWndData, TCnlData что касается работы с контейнерами - будет нормально, а что касается вызовов функций в hmg методах класса - это как было. Работу hmg классами я не затрагивал. Как было, так осталось. Делал Андрей в WaitWindow_2 в потоке окно ... это я ничего не трогал и безопасность не обеспечивал.
| |
|
Петр
|
| постоянный участник
|
Пост N: 1528
Зарегистрирован: 09.10.06
|
|
Отправлено: 19.06.17 21:41. Заголовок: SergKis пишет: Если..
SergKis пишет: цитата: | Если я, сделаю, как вы предлагали, зашить в класс hb_mtvm CLASSVAR lVmMt INIT hb_mtvm() READONLY Возможно, что вы что то удешивили, но получили только 2-а состояния .T. и .F. А, я, хотел получить ИМЕННО внешнее управление |
| Петр пишет: цитата: | Ну если вам так нужна эта lVmMt (мое мнение - не нужна ) то можно просто добавить, не раздувая класса |
| А можно добавить в EXPORTED секцию VAR lVmMt INIT что-то там и иметь внешнее управление, в большинстве случаев в Clipper так и работали. цитата: | Причем здесь "дешевле", если это удобно, минимум ЧЕЛОВЕЧЕСКИХ затрат и решаются просто, это так же относится и .Show, .Show(), :Show, :Show(), ... . |
| :Show и :Show() - разницу в затратах ЧЕЛОВЕЧЕСКИХ определите? Есть ведь еще сопровождение и там затраты ничуть не меньше. Каждый раз в исходники лезть не очень то и комфортно. цитата: | METHOD GetListType() CLASS TWndData LOCAL oType := oKeyData() LOCAL aType := {} ::oName:Eval({|k,o,i| k := i, oType:Set(o:cType, o:cType) }) oType:Eval({|k,v,i| k := i, aAdd(aType, v) }) oType:Destroy() oType := Nil RETURN aType выделенное для hb можно не делать |
| В GetListType oType нафиг не нужен, он там за уши притянут, как и большинство ваших ASSIGN/ACCESS.
| |
|
SergKis
|
| постоянный участник
|
Пост N: 1551
Зарегистрирован: 17.02.12
|
|
Отправлено: 20.06.17 11:41. Заголовок: Петр пишет нафиг не ..
Петр пишет цитата: | нафиг не нужен, он там за уши притянут, как и большинство ваших ASSIGN/ACCESS |
| Давайте определимся, класс TaskDialog не типизированный, т.е. работаем как в Clipper и др. не типизированных языках, т.е. убрав все методы SETGET в классе ничего не изменится, как был не типизированным, так и остался. Представленные классы написаны в строго типизированном стиле, где доступы к переменным осуществляются через ACCESS\ASSIGN (методы и там и там) и объявления переменных должны быть типизированы. Последнее пока не сделал (только для объектов AS OBJECT сделал) из за метода Destroy(). Если пропишу AS STRING, AS NUMERIC, AS LOGIC, то в Destroy() должен присваивать не NIL, а соответсвующие объявлению значения, в hb я не знаю хорошо ли в Destroy() сделать ::cName := "", ::nHandle := 0, ... подвиснут или уберутся. Потому предложение убрать ACCESS\ASSIGN или заменить на SETGET переведет класс в не типизированный. Если бы я этого хотел, так писал сразу. Да, набирать классы начинал не типизированными, но постепенно переводил в строгую типизацию. цитата: | А можно добавить в EXPORTED секцию VAR lVmMt INIT что-то там и иметь внешнее управление, в большинстве случаев в Clipper так и работали. |
| Даже, если вы так сделаете, все равно придется добавлять метод для установления свойства :MT в объектах TKeyData (тут ASSIGN, у вас может SETGET или просто метод) ASSIGN MT( lVmMt ) INLINE ( ::lMT := iif( HB_ISLOGICAL(lVmMt), lVmMt, .F. ), ; ::oName:MT := ::lMT, ::oHand:MT := ::lMT, ; ::oCargo:MT := ::lMT, ::oEvent:MT := ::lMT, ; ::oUserKeys:MT := ::lMT ) цитата: | :Show и :Show() - разницу в затратах ЧЕЛОВЕЧЕСКИХ определите? Есть ведь еще сопровождение и там затраты ничуть не меньше. Каждый раз в исходники лезть не очень то и комфортно. |
| В данном случае, вы определили только программистские затраты и не учли затраты эксплуатационные. Т.е. не дали :Show. Пользователь hmg, неважно каким способом, написал где то в одном месте так. Проверял ..., (что бы все режимы проверить, возможно, надо держать человека или группу), но отвлекли, ..., пропустил. Ушло в эксплуатацию, режим с ошибкой редкий, раз в месяц. И как, бутерброд с маслом, вылезет в неподходящее время. И что дороже, продублировать несколько строк, в каждой исправив несколько букв или заложить мину ? Я говорю о данном случае, а не вообще ... . цитата: | В GetListType oType нафиг не нужен |
| Предложите реализацию получения уникального списка типов по другому. Я сделал так.
| |
|
Andrey
|
| постоянный участник
|
Пост N: 5423
Зарегистрирован: 12.09.06
|
|
Отправлено: 20.06.17 12:45. Заголовок: Петр да помоги напис..
Петр да помоги написать как нужно и всех делов то... Меньше ругани - больше дела !
| |
|
Петр
|
| постоянный участник
|
Пост N: 1530
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.06.17 13:26. Заголовок: Andrey пишет: Петр ..
Andrey пишет: цитата: | Петр да помоги написать как нужно и всех делов то... |
| Кому от этого легче станет? Пускай человек учится..
| |
|
Петр
|
| постоянный участник
|
Пост N: 1531
Зарегистрирован: 09.10.06
|
|
Отправлено: 20.06.17 13:36. Заголовок: Петр пишет: через A..
Петр пишет: цитата: | через ACCESS\ASSIGN (методы и там и там) и объявления переменных должны быть типизированы. Последнее пока не сделал (только для объектов AS OBJECT сделал) из за метода Destroy(). Если пропишу AS STRING, AS NUMERIC, AS LOGIC, то в Destroy() должен присваивать не NIL, а соответсвующие объявлению значения, в hb я не знаю хорошо ли в Destroy() сделать ::cName := "", ::nHandle := 0, ... подвиснут или уберутся. Потому предложение убрать ACCESS\ASSIGN или заменить на SETGET переведет класс в не типизированный. Если бы я этого хотел, так писал сразу. Да, набирать классы начинал не типизированными, но постепенно переводил в строгую типизацию. |
| Значит класс не закончен и смотреть не на что. И не пишите, пожалуйста, то чего не знаете - я не знаю как на это реагировать, ну типа плакать или смеяться Я привел вам пример (destruct.prg) - там и деструктор и неявный конструктор init.. Там (папка tests) есть и другие примеры, например, реализация FOREACH, OPERATOR для классов - очень даже интересно.
| |
|
gfilatov2002
|
| moderator
|
Пост N: 1120
Зарегистрирован: 11.02.10
|
|
Отправлено: 21.06.17 11:31. Заголовок: Завершена подготовка..
Завершена подготовка новой сборки 17.06 для BCC 5.51 (Harbour и xHarbour) , которая будет опубликована завтра. Под заказ возможно сделать индивидуальные сборки для таких дополнительных С-компиляторов: - MinGW 7.1.0 32-bit и Harbour 3.4.0dev; - MinGW 7.1.0 64-bit и Harbour 3.4.0dev; - MS VisualC 2015 32-bit и Harbour 3.2.0dev; - MS VisualC 2017 32-bit и Harbour 3.2.0dev; - BCC 10.1 32-bit и Harbour 3.2.0dev; - PellesC 8.0 32-bit и xHarbour 1.2.3 build 10194. Благодарю за Ваше внимание
| |
|
gfilatov2002
|
| moderator
|
Пост N: 1121
Зарегистрирован: 11.02.10
|
|
Отправлено: 22.06.17 10:46. Заголовок: Опубликована очередн..
| |
|
Ответов - 300
, стр:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
All
[только новые]
|
|
|