To rindo à toa ao ver HMG 4

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem 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 }   } ) 
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Claudio Soto
Colaborador
Colaborador
Mensagens: 566
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

To rindo à toa ao ver HMG 4

Mensagem 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.
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

To rindo à toa ao ver HMG 4

Mensagem 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
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem por JoséQuintas »

Dá uma olhada nesta descoberta recente, pode ser interessante pra isso.

CLASS VAR

https://pctoledo.org/forum/viewto ... =4&t=18224
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Claudio Soto
Colaborador
Colaborador
Mensagens: 566
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

To rindo à toa ao ver HMG 4

Mensagem 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

Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

To rindo à toa ao ver HMG 4

Mensagem 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.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

To rindo à toa ao ver HMG 4

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder