hmg extend com oop
Enviado: 29 Mai 2023 08:32
veja em funcionamento;
Código: Selecionar todos
PROCEDURE Main
LOCAL oMain, oFrame1, oLabel1, oProgbar1, oButton1, oButton2, oButton3
LOCAL oButton31, oButton4, oButton5, oFrame2, oFrame3
WITH OBJECT oMain := WindowClass():New( .T. )
:nCol := 197
:nRow := 437
:nWidth := 550
:nHEIGHT := 350
:Caption := "Multi threads Sample"
:Create( .T. )
ENDWITH
Código: Selecionar todos
WITH OBJECT oButton1 := ButtonClass():New()
:nROW := 10
:nCOL := 10
:nWIDTH := 160
:nHEIGHT := 28
:bACTION := { || main_button_1_action( @pClockThread, @oMain, @oButton1, @oLabel1, @oFrame2, @oFrame3 ) }
:CAPTION := "Start Clock Thread"
:Create( oMain )
ENDWITH
Código: Selecionar todos
FUNCTION main_button_1_action( /*@*/ pClockThread, oMain, oButton1, oLabel1, oFrame2, oFrame3 )
//MsgExclamation("aqui" )
Altd()
IF ValType( oMain:GetProperty( "Cargo" ) ) == "L" .AND. oMain:GetProperty( "Cargo" )
IF ! hb_threadQuitRequest( pClockThread )
msgExclamation( "Can't stop thread!" )
ELSE
oButton1:SetProperty( "Cargo", .F. )
oButton1:SetProperty( "Caption", "Start Clock Thread" )
//oLabel1:SetProperty( "FontBold", .F. )
//oLabel1:SetProperty( "FontSize", 10 )
oLabel1:SetProperty( "Value", "00:00:00" )
pClockThread := NIL
ENDIF
ShowThreadsIDs( oFrame2, oFrame3 )
RETURN NIL
ENDIF
IF ! hb_mtvm()
msgStop( "There is no support for multi-threading, clock will not be seen." )
ELSE
//oLabel1:SetProperty( "FontBold", .T. )
//olabel1:SetProperty( "nFontSize", 12 )
oButton1:SetProperty( "Caption", "Click to Stop Clock" )
pClockThread := hb_threadStart( HB_THREAD_INHERIT_PUBLIC, { || Show_Time( oLabel1 ) } )
oMain:SetProperty( "Cargo", .T. )
ENDIF
ShowThreadsIDs( oFrame2, oFrame3 )
RETURN NIL
Código: Selecionar todos
PROCEDURE ShowThreadsIDs( oFrame2, oFrame3 )
ALtd()
oFrame2:Caption := "Clock (Thread pointer: " + hb_ntos( win_P2N( pClockThread ) ) +")"
oFrame3:Caption := "Progressbar (Thread pointer: " + hb_ntos( win_P2N( pProgThread ) ) +")"
RETURN
Código: Selecionar todos
/*
Multi-Thread sample by Roberto Lopez.
*/
STATIC pClockThread, pProgThread // hold pointers of threads
PROCEDURE Main
LOCAL oMain, oFrame1, oLabel1, oProgbar1, oButton1, oButton2, oButton3
LOCAL oButton31, oButton4, oButton5, oFrame2, oFrame3
WITH OBJECT oMain := WindowClass():New( .T. )
:nCol := 197
:nRow := 437
:nWidth := 550
:nHEIGHT := 350
:Caption := "Multi threads Sample"
:Create( .T. )
ENDWITH
WITH OBJECT oFrame1 := FrameClass():New()
:nROW := 10
:nCOL := 200
:nWIDTH := 315
:nHEIGHT := 278
:CAPTION := "Threads"
:Create( oMain )
ENDWITH
WITH OBJECT oLabel1 := LabelClass():New()
:nROW := 60
:nCOL := 290
:nWIDTH := 120
:nHEIGHT := 24
:Caption := "Clock Here!"
:Create( oMain )
ENDWITH
WITH OBJECT oProgbar1 := ProgbarClass():New()
:nROW := 150
:nCOL := 290
:nWIDTH := 150
:nHEIGHT := 30
:nRANGEMIN := 1
:nRANGEMAX := 10
:Create( oMain )
ENDWITH
WITH OBJECT oButton1 := ButtonClass():New()
:nROW := 10
:nCOL := 10
:nWIDTH := 160
:nHEIGHT := 28
:bACTION := { || main_button_1_action( @pClockThread, @oMain, @oButton1, @oLabel1, @oFrame2, @oFrame3 ) }
:CAPTION := "Start Clock Thread"
:Create( oMain )
ENDWITH
WITH OBJECT oButton2 := ButtonClass():New()
:nROW := 50
:nCOL := 10
:nWIDTH := 160
:nHEIGHT := 28
:bACTION := { || main_button_2_action( @pProgThread, @oMain, @oProgbar1, @oButton2, @oFrame2, @oFrame3 ) }
:CAPTION := "Start ProgressBar Thread"
:Create( oMain )
ENDWITH
WITH OBJECT oButton3 := ButtonClass():New()
:nROW := 90
:nCOL := 10
:nWIDTH := 160
:nHEIGHT := 28
:bACTION := { || main_button_3_action( @pClockThread, @pProgThread ) }
:CAPTION := "Stop All Threads"
:Create( oMain )
ENDWITH
WITH OBJECT oButton31 := ButtonClass():New()
:nROW := 130
:nCOL := 10
:nWIDTH := 160
:nHEIGHT := 28
:bACTION := { || main_button_31_action( @pClockThread, @pProgThread ) }
:CAPTION := "Start All Threads"
:Create( oMain )
ENDWITH
WITH OBJECT oButton4 := ButtonClass():New()
:nROW := 220
:nCOL := 220
:nWIDTH := 260
:nHEIGHT := 28
:bACTION := { || main_button_4_action( pClockThread, pProgThread ) }
:CAPTION := "Main Thread Button"
:Create( oMain )
ENDWITH
WITH OBJECT oButton5 := ButtonClass():New()
:nROW := 250
:nCOL := 10
:nWIDTH := 160
:nHEIGHT := 28
:bACTION := {|| hb_threadTerminateAll(), DoMethod( "MainWin", "Release") }
:CAPTION := "Exit (closing all threads)"
:Create( oMain )
ENDWITH
WITH OBJECT oFrame2 := FrameClass():New()
:nROW := 30
:nCOL := 220
:nWIDTH := 272
:nHEIGHT := 75
:cFONTNAME := 'Arial'
:nFONTSIZE := 10
:lFONTBOLD := .T.
:CAPTION := "Clock Thread - ID:"
:lOPAQUE := .T.
:Create( oMain )
ENDWITH
WITH OBJECT oFrame3 := FrameClass():New()
:nROW := 120
:nCOL := 220
:nWIDTH := 272
:nHEIGHT := 75
:cFONTNAME := 'Arial'
:nFONTSIZE := 10
:lFONTBOLD := .T.
:CAPTION := "Progressbar Thread - ID:"
:lOPAQUE :=.T.
:Create( oMain )
ENDWITH
//END WINDOW
_EndWindow()
oButton1:Cargo := .F.
oButton2:Cargo := .F.
//ShowThreadsIDs( oFrame2, oFrame3 )
oMain:Center()
oMain:Activate()
(oFrame1)
(oLabel1)
(oProgbar1)
(oButton3)
(oButton31)
(oButton4)
(oButton5)
(oFrame2)
(oFrame3)
RETURN
FUNCTION Show_Time( oLabel1 )
// please note that this function will NEVER return the control!
// but do not 'locks' the user interface since it is running in a separate thread
DO WHILE .T.
oLabel1:Caption := Time()
hb_idleSleep( 0.1 )
ENDDO
RETURN NIL
FUNCTION Show_Progress( oProgbar1 )
LOCAL nValue
DO WHILE .T.
nValue := oProgbar1:Caption
IF ValType( nValue ) != "N"
IF ValType( nValue ) == "C"
nValue := Val( nValue )
ELSE
nValue := 0
ENDIF
ENDIF
nValue ++
if nValue > 10
nValue := 1
endif
oProgbar1:Caption := Ltrim( Str( nValue ) )
hb_idleSleep( 0.2 )
ENDDO
RETURN NIL
PROCEDURE ShowThreadsIDs( oFrame2, oFrame3 )
oFrame2:Caption( "Clock (Thread pointer: " + hb_ntos( win_P2N( pClockThread ) ) +")" )
oFrame3:Caption( "Progressbar (Thread pointer: " + hb_ntos( win_P2N( pProgThread ) ) +")" )
RETURN
Código: Selecionar todos
#include "hbclass.ch"
#include "hmg.ch"
STATIC nObject := 0
CREATE CLASS WindowClass INHERIT ObjectClass
VAR cType INIT "Mainwin"
METHOD Create( oMain )
ENDCLASS
METHOD Create( oMain ) CLASS WindowClass
hb_Default( @oMain, .F. )
IF oMain
DEFINE WINDOW &(::cName) AT ::nCol, ::nRow ;
WIDTH ::nWidth HEIGHT ::nHeight TITLE ::hAll[ "Caption" ] MAIN
ENDIF
::lCreated := .T.
RETURN Nil
CREATE CLASS FRAMEClass INHERIT ObjectClass
VAR cType INIT "Frame"
VAR lOpaque INIT .F.
METHOD Create( oMain )
ENDCLASS
METHOD Create( oMain ) CLASS FrameClass
::oParent := oMain
DEFINE FRAME &(::cName)
ROW ::nRow
COL ::nCol
WIDTH ::nWidth
HEIGHT ::nHeight
CAPTION ::hAll[ "Caption" ]
FONTNAME ::cFontName
FONTSIZE ::nFontSize
FONTBOLD ::lFontBold
CAPTION ::hAll[ "Caption" ]
PARENT &( ::oParent:cName )
OPAQUE ::lOpaque
END FRAME
::lCreated := .T.
RETURN Nil
CREATE CLASS BUTTONClass INHERIT ObjectClass
VAR cType INIT "Button"
METHOD Create( oMain )
ENDCLASS
METHOD Create( oMain ) CLASS ButtonClass
::oParent := oMain
DEFINE BUTTON &(::cName)
ROW ::nRow
COL ::nCol
WIDTH ::nWidth
HEIGHT ::nHeight
ACTION Eval( ::bAction )
CAPTION ::hAll[ "Caption" ]
PARENT &( ::oParent:cName )
END BUTTON
::lCreated := .T.
RETURN Nil
CREATE CLASS LABELClass INHERIT ObjectClass
VAR cType INIT "Label"
METHOD Create( oMain )
ENDCLASS
METHOD Create( oMain ) CLASS LabelClass
::oParent := oMain
DEFINE LABEL &(::cName)
ROW ::nRow
COL ::nCol
WIDTH ::nWidth
HEIGHT ::nHeight
VALUE ::hAll[ "Caption" ]
PARENT &( ::oParent:cName )
END LABEL
::lCreated := .T.
RETURN Nil
CREATE CLASS ProgbarClass INHERIT ObjectClass
VAR cType INIT "Progbar"
VAR nRangeMin INIT 0
VAR nRangeMax INIT 0
METHOD Create( oMain )
ENDCLASS
METHOD Create( oMain ) CLASS ProgbarClass
::oParent := oMain
DEFINE PROGRESSBAR &(::cName)
ROW ::nRow
COL ::nCol
WIDTH ::nWidth
HEIGHT ::nHeight
RANGEMIN ::nRangeMin
RANGEMAX ::nRangeMax
PARENT &( ::oParent:cName )
END PROGRESSBAR
::lCreated := .T.
RETURN Nil
Código: Selecionar todos
CREATE CLASS ObjectClass
VAR cType INIT "None"
VAR oParent INIT Nil
VAR cName INIT "X"
VAR hAll INIT hb_Hash()
VAR nRow INIT 0
VAR nCol INIT 0
VAR nWidth INIT 0
VAR nHeight INIT 0
VAR cFontName INIT "Arial"
VAR nFontSize INIT 10
VAR lFontBold INIT .F.
VAR bAction INIT { || Nil }
VAR aControlList INIT {}
VAR lCreated INIT .F.
METHOD New()
METHOD Cargo( xValue ) SETGET
METHOD Center() INLINE ::DoMethod( "center" )
METHOD Activate() INLINE ::DoMethod( "activate" )
METHOD Caption( cText ) SETGET
METHOD DoMethod( cName )
METHOD GetProperty( cName )
METHOD SetProperty( cName, xValue )
ENDCLASS
METHOD New() CLASS ObjectClass
nObject += 1
IF ::cType == "Mainwin"
::cName := "Mainwin"
else
::cName := ::cType + StrZero( nObject, 6 )
ENDIF
RETURN Self
METHOD Caption( cText ) CLASS ObjectClass
IF cText != Nil
::hAll[ "Caption" ] := cText
IF ::lCreated
::SetProperty( "Caption", cText )
ENDIF
ENDIF
IF ::lCreated
::hAll[ "Caption" ] := ::GetProperty( "Caption" )
ENDIF
RETURN ::hAll[ "Caption" ]
METHOD DoMethod( cName ) CLASS ObjectClass
LOCAL aList, oThis, oThisAnt
aList := { ::cName }
oThis := Self
oThisAnt := oThis
DO WHILE ( oThis := oThis:oParent ) != Nil
hb_AIns( aList, 1, oThis:cName, .T. )
oThisAnt := oThis
ENDDO
IF oThisAnt:lCreated
DoMethod( hb_ArrayToParams( aList ), cName )
ENDIF
RETURN Nil
METHOD GetProperty( cName ) CLASS ObjectClass
LOCAL aList, oThis, oThisAnt
aList := { ::cName }
oThis := Self
oThisAnt := oThis
DO WHILE ( oThis := oThis:oParent ) != Nil
hb_AIns( aList, 1, oThis:cName, .T. )
oThisAnt := oThis
ENDDO
IF oThisAnt:lCreated
GetProperty( hb_ArrayToParams( aList ), cName )
ENDIF
RETURN Nil
METHOD SetProperty( cName, xValue ) CLASS ObjectClass
LOCAL aList, oThis, oThisAnt // , cText
aList := { ::cName }
//MsgInfo( "atual " + ::cName )
oThis := Self
oThisAnt := oThis
DO WHILE ( oThis := oThis:oParent ) != Nil
hb_AIns( aList, 1, oThis:cName, .T. )
oThisAnt := oThis
ENDDO
//cText := "SetProperty(" + ["] + aList[1] + ["]
//DO CASE
//CASE Len( aList ) == 2
// cText += "," + ["] + aList[2] + ["]
//CASE Len( aList ) == 3
// cText += "," + ["] + aList[3] + ["]
//CASE Len( aList ) == 4
// cText += "," + ["] + aList[4] + ["]
//ENDCASE
//cText += "," + ["] + cName + ["] + ","
//DO CASE
//CASE ValType( xValue ) == "C"; cText += ["] + xValue + ["]
//CASE ValType( xValue ) == "N"; cText += Ltrim( Str( xValue ) )
//CASE ValType( xValue ) == "D"; cText += "Stod(" + Dtos( xValue ) + ")"
//CASE ValType( xValue ) == "L"; cText += iif( xValue, ".T.", ".F." )
//OTHERWISE ; cText += Transform( xValue, "" )
//ENDCASE
//cText += ")"
//MsgInfo( cText )
IF oThisAnt:lCreated
SetProperty( hb_ArrayToParams( aList ), cName, xValue )
ENDIF
RETURN Nil
METHOD Cargo( xValue ) CLASS ObjectClass
IF xValue != Nil
::hAll[ "Cargo" ] := xValue
IF ::lCreated
::SetProperty( "Cargo", xValue )
ENDIF
ELSE
IF ::lCreated
::GetProperty( "Cargo", xValue )
ENDIF
ENDIF
RETURN ::hAll[ "Cargo" ]
Código: Selecionar todos
METHOD IsCreated() CLASS ObjectClass
DO WHILE ! ::lCreated .AND. ( oThis := oThis:oParent ) != Nil
::lCreated := oThis:lCreated
IF oThis:Type == "Mainwin"
EXIT
ENDIF
ENDDO
RETURN ::lCreated
...
METHOD DoMethod( cName ) CLASS ObjectClass
LOCAL aList, oThis, oThisAnt
IF ! ::IsCreated() .AND. ::cName != "Mainwin"
RETURN Nil
ENDIF
aList := { ::cName }
oThis := Self
oThisAnt := oThis
DO WHILE ( oThis := oThis:oParent ) != Nil
hb_AIns( aList, 1, oThis:cName, .T. )
oThisAnt := oThis
ENDDO
DoMethod( hb_ArrayToParams( aList ), cName )
IF cName == "Activate"
::lCreated := .T.
ENDIF
RETURN Nil
Acho que não expliquei direito:ivanil escreveu:Quanto ao assunto não depender do fonte HMG; é justamente o oposto do que penso, pois posso usar o designer para posicionar os objetos rapidamente sem interferir em absolutamente nada e quanto a mudanças no núcleo da minigui não faz muito sentido, qualquer coisa que venha a ser implementado seria uma propriedade, mas isso seria transparente... eu uso desta forma ha muitos anos e funciona bem.
Código: Selecionar todos
#ifdef _NAMES_LIST_
_SetNameList( mVar , k )
#else
Public &mVar. := k
#endif
Código: Selecionar todos
/* ***********************************************************************
* Enable this option if you want that the internal Public variables were
* stored in the Global hash instead of the many Public variables.
*
* By default this is turned ON.
*/
#ifndef __XHARBOUR__
#define _NAMES_LIST_
#endif
Código: Selecionar todos
#xtranslate _SetNameList( <x> , <v> ) => _SetGetNamesList( <x> , <v> )
Código: Selecionar todos
#ifdef _NAMES_LIST_
*-----------------------------------------------------------------------------*
FUNCTION _SetGetNamesList( cName, nIndex, lDelete )
*-----------------------------------------------------------------------------*
STATIC _HMG_NAMESLIST
IF HB_ISNIL( _HMG_NAMESLIST )
_HMG_NAMESLIST := oHmgData()
ENDIF
Código: Selecionar todos
#translate oHmgData( [ <lUpper> ] ) => THmgData():New( hb_defaultValue( <lUpper>, .T. ) )
Código: Selecionar todos
CLASS THmgData
///////////////////////////////////////////////////////////////////////////////
PROTECTED:
VAR lUpp AS LOGICAL
VAR aKey INIT hb_Hash()
EXPORTED:
Código: Selecionar todos
/* ***********************************************************************
* Enable support for the internal OOP classes
*
* By default this is turned ON.
*/
#define _OBJECT_
Agora que percebi como fez, e tem a ver diretamente com isso.ivanil escreveu:Assim como em hwgui, na minigui você também consegue trabalhar usando a boa prática de programação, ou seja, não misturar visão com lógica;(embora nos viciamos em fazer um pacotão só);
Nada impede você de colocar os eventos a serem disparados, inclusive às vezes eu faço assim.JoséQuintas escreveu:O desenho da tela só tem... o desenho da tela, mas sem os procedimentos adicionais.
Isso permite usar o código fonte normal da minigui pra desenhar telas (ou IDE).
Depois de uma olhada no arquivo h_objects.prg, faz bastante tempo que existe, mas percebi que o pessoal não gosta muito de lidar com objetos; embora também ache que as nomenclaturas adotadas nestas classes dificultam o aprendizado.JoséQuintas escreveu: Por enquanto tá esquisito isso, não parece nada com OOP.
Acho que está sendo preparado pra isso aos poucos.
Nem sei como conseguem manter tudo que é opção que inventaram ao mesmo tempo.