Página 1 de 1

To rindo à toa ao ver HMG 4

Enviado: 17 Fev 2017 23:06
por JoséQuintas
Tô rindo à toa ao ver o fonte principal da HMG 4

Código: Selecionar todos

// Singleton implementation

FUNCTION HMGAPP()

   STATIC hmgapp := NIL

   IF hb_isnil( hmgapp ) 
      hmgapp := HMG_HMGAPP():New()
   ENDIF

RETURN hmgapp
E uma função, que dá acesso a uma variável STATIC, assim fica visível em multithread.
Neste caso, a variável é uma classe.

Agora lembrar a alteração que fiz pra HMG funcionar em multithread:

Código: Selecionar todos

STATIC __HMGS_SYSDATA := { ,,, }

FUNCTION _HmgApp()

   RETURN __HMGS_SYSDATA
Uma função, que dá acesso a uma variável STATIC, assim fica visível em multithread.
Neste caso, usa o array da HMG.

Só achei uma coincidência interessante.
Por pouco não fica até com o mesmo nome.
Parece que esse tipo de uso é comum.

To rindo à toa ao ver HMG 4

Enviado: 18 Fev 2017 00:00
por JoséQuintas
Este aqui também está interessante.

Código: Selecionar todos

#include "hmg.ch"

Function Main

Local oWindow , oButton1

With Object oWindow := Window():New()
:Width := 200
:Height := 80
:Type := WND_MAIN

With Object oButton1 := Button():New()
:Row := 20
:Col := 20
:Width := 160
:Caption := 'Click to Change Caption !'
:OnClick := { || ChangeCaption(oButton1) }
End With

End With

oWindow:Activate()

Return
Tá até parecendo GTWVG.

Considerando outros posts, a minha conclusão é uma só:

Quem conhece API de Windows conhece C, mas não o Harbour.
Quem conhece o Harbour, pode até conhecer API Windows, mas não conhece C.

A revolução maior da QT, parece ser padronizar os programadores.
E o resultado... algo parecido com GTWVG, no que diz respeito aos fontes.

A resposta pra tudo já está no Harbour, na GTWVG...
Isso tudo é de endoidar.

To rindo à toa ao ver HMG 4

Enviado: 18 Fev 2017 21:03
por JoséQuintas
Fui olhar o primeiro fonte da HMG4, do TAB, que é um que me interessa...
Já fiz um pedido aos desenvolvedores do Harbour, para que se possível, fontes desse tipo sejam rejeitados.

https://groups.google.com/forum/#!topic ... PPB9vJDUN8

Exemplo ensinando errado é fod.

Se os programadores Harbour desaprenderem, e desaparecerem, também desaparece o Harbour, e isso me afeta diretamente.
Preciso cuidar da minha ferramenta de trabalho, mesmo que indiretamente.

To rindo à toa ao ver HMG 4

Enviado: 18 Fev 2017 21:17
por JoséQuintas
Pra quem ficou curioso: WITH OBJECT que não serve pra nada.
É só comparar os dois fontes.

Código: Selecionar todos

   WITH OBJECT oWindow := MAINWINDOW():New()
      :Row     := 10
      :Col     := 10
      :Width   := 400
      :Height  := 400
      :Title   := 'Nice OOP Demo!!!'
      :OnInit  := { || oWindow:Center() }

      WITH OBJECT MainMenu():New()

         WITH OBJECT MenuPopup():New( 'PopupPageTest',, 'Page Tests' )
            WITH OBJECT MenuItem():New( 'Item1',, 'SET oPage1 Caption' , { || oPage1:Caption := 'New'      } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item2',, 'SET oPage1 Image'   , { || oPage1:Image   := 'open.png' } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item3',, 'SET oPage1 Disable' , { || oPage1:Enabled := .F.        } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item4',, 'SET oPage1 Enable'  , { || oPage1:Enabled := .T.        } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item5',, 'SET oPage1 ToolTip' , { || oPage1:ToolTip := 'ToolTip'  } ) ; END WITH
         END WITH

         WITH OBJECT MenuPopup():New( 'PopupTabTest',, 'Tab Tests' )
            WITH OBJECT MenuItem():New( 'Item6' ,, 'SET Tabs Position (Top)'    , { || oTab:Position := TAB_TOP     } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item7' ,, 'SET Tabs Position (Bottom)' , { || oTab:Position := TAB_BOTTOM  } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item8' ,, 'SET Tabs Position (Left)'   , { || oTab:Position := TAB_LEFT    } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item9' ,, 'SET Tabs Position (Right)'  , { || oTab:Position := TAB_RIGHT   } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item10',, 'SET Tabs Shape (Triangular)', { || oTab:Shape := TAB_TRIANGULAR } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item11',, 'SET Tabs Shape (Rounded)'   , { || oTab:Shape := TAB_ROUNDED    } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item12',, 'SET Active Page TO 1'       , { || oTab:Value := 1              } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item13',, 'SET Active Page TO 2'       , { || oTab:Value := 2              } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item14',, 'SET OnChange Event'         , { || oTab:OnChange := { || MsgInfo( 'Changed' ) } } ) ; END WITH
            WITH OBJECT MenuItem():New( 'Item15',, 'Clear OnChange Event'       , { || oTab:OnChange := { || NIL }   } ) ; END WITH
         END WITH

      END WITH

Código: Selecionar todos

   WITH OBJECT oWindow := MAINWINDOW():New()
      :Row     := 10
      :Col     := 10
      :Width   := 400
      :Height  := 400
      :Title   := 'Nice OOP Demo!!!'
      :OnInit  := { || oWindow:Center() }
   END WITH
      MainMenu():New()

         MenuPopup():New( 'PopupPageTest',, 'Page Tests' )
            MenuItem():New( 'Item1',, 'SET oPage1 Caption' , { || oPage1:Caption := 'New'      } )
            MenuItem():New( 'Item2',, 'SET oPage1 Image'   , { || oPage1:Image   := 'open.png' } )
            MenuItem():New( 'Item3',, 'SET oPage1 Disable' , { || oPage1:Enabled := .F.        } ) 
            MenuItem():New( 'Item4',, 'SET oPage1 Enable'  , { || oPage1:Enabled := .T.        } ) 
            MenuItem():New( 'Item5',, 'SET oPage1 ToolTip' , { || oPage1:ToolTip := 'ToolTip'  } ) 

         MenuPopup():New( 'PopupTabTest',, 'Tab Tests' )
            MenuItem():New( 'Item6' ,, 'SET Tabs Position (Top)'    , { || oTab:Position := TAB_TOP     } ) 
            MenuItem():New( 'Item7' ,, 'SET Tabs Position (Bottom)' , { || oTab:Position := TAB_BOTTOM  } )
            MenuItem():New( 'Item8' ,, 'SET Tabs Position (Left)'   , { || oTab:Position := TAB_LEFT    } ) 
            MenuItem():New( 'Item9' ,, 'SET Tabs Position (Right)'  , { || oTab:Position := TAB_RIGHT   } ) 
            MenuItem():New( 'Item10',, 'SET Tabs Shape (Triangular)', { || oTab:Shape := TAB_TRIANGULAR } )
            MenuItem():New( 'Item11',, 'SET Tabs Shape (Rounded)'   , { || oTab:Shape := TAB_ROUNDED    } )
            MenuItem():New( 'Item12',, 'SET Active Page TO 1'       , { || oTab:Value := 1              } ) 
            MenuItem():New( 'Item13',, 'SET Active Page TO 2'       , { || oTab:Value := 2              } ) 
            MenuItem():New( 'Item14',, 'SET OnChange Event'         , { || oTab:OnChange := { || MsgInfo( 'Changed' ) } } )
            MenuItem():New( 'Item15',, 'Clear OnChange Event'       , { || oTab:OnChange := { || NIL }   } ) 

To rindo à toa ao ver HMG 4

Enviado: 18 Fev 2017 23:25
por Claudio Soto
José, no entendí muy bien lo que quisiste decir.
Me parece que la idea de usar WITH OBJECT es para crear un constructor de clase limpio, sin parámetros, y luego de creado el objeto asignarle facilmente valores a las propiedades de la clase sin tener que tipear el nombre del objeto.
Las clases fueron creadas en su origen para darle claridad y legilibilidad al código ( para que se parezca más al lenguaje humano y menos al lenguaje de una máquina), un constructor con un montón de parámetros me parece que es más lo que oscurece que lo que aclara.

Solo como comentario: en el primer post aparece la implantación de una clase como singleton. Una clase singleton permite la creación de solo una instancia de la misma, y en el ej. de HMG4 eso solo es válido si no se usa MT. En MT hay que usar algún tipo de bandera global para impedir que dos thread creen instancias diferente de la misma clase. Además dicha bandera debe ser verificada dentro del constructor y no en la función que llama al constructor de clase.

To rindo à toa ao ver HMG 4

Enviado: 19 Fev 2017 09:52
por JoséQuintas
Este trecho, sem o uso de WITH OBJECT

Código: Selecionar todos

oWindow := MainWindow():New()
oWindow:Row     := 10
oWindow:Col     := 10
oWindow:Width   := 400
oWindow:Height  := 400
oWindow:Title   := 'Nice OOP Demo!!!'
oWindow:OnInit  := { || oWindow:Center() }
O mesmo trecho, com o uso de WITH OBJECT

Código: Selecionar todos

WITH OBJECT oWindow := MAINWINDOW():New()
      :Row     := 10
      :Col     := 10
      :Width   := 400
      :Height  := 400
      :Title   := 'Nice OOP Demo!!!'
      :OnInit  := { || :Center() }
END WITH
Vantagens: agrupou repetição, deixou o fonte mais limpo, evita erro de digitação.
Até se quiser alterar o nome do form, oWindow, basta alterar num único local do fonte.

Essa é a finalidade do WITH OBJECT: agrupar o uso repetitivo do mesmo objeto num bloco de fonte.
Só nesse bloco tem sentido usar WITH OBJECT, e não em todo o fonte.

Infelizmente, os usuários começam sempre copiando exemplos, com medo de fazer algo errado, então isso vai ser repassado pra mais e mais fontes.
Olhe novamente o fonte anterior, e vai confirmar que os outros WITH OBJECT são inúteis.

To rindo à toa ao ver HMG 4

Enviado: 11 Abr 2017 07:48
por Vlademiro
Estava buscando uma forma de implementar o singleton na minha aplicação quando encontrei essa dica. Agora eu elimino de vez a necessidade de variáveis públicas de configuração usando objetos.

A minha implementação ficou assim :

Código: Selecionar todos

FUNCTION ConfigSingleton( cSysCod )
   STATIC oConfig 
   //altd()
   IF .NOT. hb_isnil( cSysCod )
      oConfig := TVladConfig():New( cSysCod )
   ENDIF

RETURN oConfig

Eu tenho que chamar essa função uma única vez passando o parâmetro cSysCod (é uma variável que controla qual a configuração será carregada de acordo com o sistema - cSysCod ).

Eu chamo no início mais ou menos assim :

Código: Selecionar todos

           oCfg := ConfigSingleton( cSistemaSelecionado )
           oCfg:Init()
E depois, quando eu precisar faço apenas assim:

Código: Selecionar todos

    LOCAL   oCfg := ConfigSingleton() // Sem o parâmetro
Daí posso usar os métodos da classe que foi inicializada, por exemplo:

Código: Selecionar todos


   cEmpresa :=  oCfg:NomeEmpresa()

E por aí vai.

As postagens do Quintas são excelentes. Desconfio que ele usa o fórum como sua base de conhecimentos, o que é bom para todos nós. :D

To rindo à toa ao ver HMG 4

Enviado: 11 Abr 2017 08:22
por JoséQuintas
Dá uma olhada nesta descoberta recente, pode ser interessante pra isso.

CLASS VAR

https://pctoledo.org/forum/viewto ... =4&t=18224

To rindo à toa ao ver HMG 4

Enviado: 11 Abr 2017 16:44
por Claudio Soto
Vlademiro escreveu:Estava buscando uma forma de implementar o singleton na minha aplicação quando encontrei essa dica. Agora eu elimino de vez a necessidade de variáveis públicas de configuração usando objetos.

A minha implementação ficou assim :

Código: Selecionar todos

FUNCTION ConfigSingleton( cSysCod )
   STATIC oConfig 
   //altd()
   IF .NOT. hb_isnil( cSysCod )
      oConfig := TVladConfig():New( cSysCod )
   ENDIF

RETURN oConfig

Eu tenho que chamar essa função uma única vez passando o parâmetro cSysCod (é uma variável que controla qual a configuração será carregada de acordo com o sistema - cSysCod ).

Eu chamo no início mais ou menos assim :

Código: Selecionar todos

           oCfg := ConfigSingleton( cSistemaSelecionado )
           oCfg:Init()
E depois, quando eu precisar faço apenas assim:

Código: Selecionar todos

    LOCAL   oCfg := ConfigSingleton() // Sem o parâmetro
Daí posso usar os métodos da classe que foi inicializada, por exemplo:

Código: Selecionar todos


   cEmpresa :=  oCfg:NomeEmpresa()

E por aí vai.

As postagens do Quintas são excelentes. Desconfio que ele usa o fórum como sua base de conhecimentos, o que é bom para todos nós. :D
Una pequeña sugerencia para asegurar que no se cree más de una única instancia de la clase:

Código: Selecionar todos

FUNCTION ConfigSingleton( cSysCod )
   STATIC oConfig := nil
   //altd()
   IF .NOT. hb_isnil( cSysCod ) .And. oConfig == nil
      oConfig := TVladConfig():New( cSysCod )
   ENDIF

RETURN oConfig


To rindo à toa ao ver HMG 4

Enviado: 11 Abr 2017 17:35
por Pablo César
Vlademiro escreveu:As postagens do Quintas são excelentes. Desconfio que ele usa o fórum como sua base de conhecimentos, o que é bom para todos nós. :D
Sim. também concordo. Alias alto nível aqui... gostei de ver.

To rindo à toa ao ver HMG 4

Enviado: 11 Abr 2017 21:52
por JoséQuintas
As postagens do Quintas são excelentes. Desconfio que ele usa o fórum como sua base de conhecimentos, o que é bom para todos nós.
Vou aprendendo e vou compartilhando.
E vamos aprendendo mais coisas e mais utilidades pra tudo.

Só pra lembrar.
Agora parece brincadeira, mas em 2011, eu apanhando pra usar a GTWVG

https://pctoledo.org/forum/viewto ... =4&t=13221

Também aprendi e continuo aprendendo com o fórum.

Aliás... está aí uma coisa interessante:
Foi depois de começar a mexer com GTWVG, que comecei a mexer com multithread, e com essas variáveis.
A ajuda recebida em 2011 aqui no fórum foi o ponto de partida.....

Acho que eu apenas estou "acordando" o pessoal para o que sempre aconteceu.

Todos do fórum estão de parabéns.