Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: Autenticação 2FA para Usuário Root no WSL

--- # naldodj-wsl-2FA ## Autenticação 2FA para Usuário Root no WSL ### Introdução O Windows Subsystem for Linux (WSL) é uma ferramenta poderosa que permite aos desenvolvedores executar um ambiente Linux diretamente no Windows. No entanto, a segurança é uma preocupação importante, especialmente quando se trata de acessar o usuário root. Neste post, vamos mostrar como configurar a autenticação de dois fatores (2FA) para o usuário root ao acessar o WSL, garantindo uma camada adicional de segurança. ### Objetivo Vamos configurar um script de login que valida a senha do root e usa autenticação 2FA baseada em Time-based One-Time Password (TOTP), usando ferramentas comuns como `openssl`, `oathtool`, e `perl`. ### Passo 1: Instalar as Ferramentas Necessárias Primeiro, precisamos garantir que temos todas as ferramentas necessárias instaladas. Isso inclui `openssl`, `oathtool`, e `perl`. ```bash sudo apt-get update sudo apt-get install openssl oathtool perl ``` Para os scripts em Lua.

Protheus :: ADVPL : The Container : Presents Pandora's box

Era uma vez um objeto que não queria limitar-se pelo escopo, seu desejo era fazer-se presente em todos os momentos, em todos os lugares, e que, como a um "Buraco Negro", tomava para si todos os demais objetos devorando-os e controlando-os. Tornou-se Publico por sua natureza e arrastou contigo tudo o que se lhe apresentava.

Um meio-youkai poderoso em busca do corpo perfeito. Queria tornar-se indestrutível.

Seu Nome a muito se perdeu. Uns o chamavam de Naraku, outros "The Container" (O Recipiente) e, muito recentemente, passou a denominar-se oWnd.

Sem Controle o devorador de objetos poderia ser invocado por GetWndDefault() e, quase tudo o que lhe pertencia estava contido em __ClsArr(). __ClsArr() uma "Internal Function" do "Protheus" (agora mais conhecido como By You) revela todos os poderes e segredos daqueles que podem ser devorados por oWnd.

As histórias se misturam, youkais, Deuses Gregos. Tudo sem controle. Descontrolado. Um perfeito CAOS na mais perfeita "Desordem". E eis que surge o "Mago иαldσ" e invoca o método ThePandorasBox():Open() e o processo descontrolado de controle têm inicio. E agora? Onde está Wally?

Posso usar :cCaption, :cTitle, :HWND, :cResName, ... etc. Uma certeza. O único exclusivo é :HWND mas ele pode trocar de lugar, se teletransportar e te enganar. Ele pode fazer a troca com outro que se pretende pôr-se em seu lugar. Não desaparecerá, mas poderá não estar onde o encontrou da última vez.

Eles são tendenciosos, cuidado. Podem se mesclar, se misturar, se disfarçar e a confusão está feita.

Domine-os para que não seja dominado. Obtenha e tome o controle.

Entenda o seu funcionamento: como aparecem e desaparecem, seu ordenamento, suas nomenclaturas, suas origens e não se deixe enganar, senão o próximo a ser devorado será você!

The Container : O Código


#INCLUDE "PROTHEUS.CH"
#INCLUDE "TRYEXCEPTION.CH"
/*/
 Funcao: U_TContainer()
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
User Function TContainer()

 Local bWindowInit
 
 Local cTitle  := "The Container"
 
 Local nVarNameLen := SetVarNameLen( 100 ) //Redefino para poder usar Nomes Longos
 
 Local oBmpNaraku

 IF !( Type( "oMainWnd" ) == "O" )

  Private oMainWnd
  
  bWindowInit := { || Pandora() , oMainWnd:End() }
 
  DEFINE WINDOW oMainWnd FROM 001,001 TO 400,500 TITLE OemToAnsi( cTitle )
   @ 0,0 BITMAP oBmpNaraku RESNAME "NARAKU" OF oMainWnd SIZE 0,0 NOBORDER WHEN .F. PIXEL
   oBmpNaraku:lAutoSize := .T.
   oBmpNaraku:lStretch  := .T.
   oBmpNaraku:Align   := CONTROL_ALIGN_ALLCLIENT
  ACTIVATE WINDOW oMainWnd MAXIMIZED ON INIT Eval( bWindowInit )

 Else

  Pandora()

 EndIF

 SetVarNameLen( nVarNameLen )    //Restauro o Padrao

Return( NIL )

/*/
 Funcao: Pandora
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function Pandora()

 Local aButtons  := {}
 Local aAdvSize  := MsAdvSize( NIL , .F. )
 Local aInfoAdvSize := { aAdvSize[1] , aAdvSize[2] , aAdvSize[3] , aAdvSize[4] , 0 , 0 }
 Local aObjCoords := { { 000 , 000 , .T. , .T. } }
 Local aMsObjSize := MsObjSize( aInfoAdvSize , aObjCoords )
 
 Local bSet15  := { || oDlg:End() }
 Local bSet24  := { || oDlg:End() } 
 Local bInitDlg  := { || EnchoiceBar( @oDlg , @bSet15 , @bSet24 , NIL , @aButtons ) }

 Local oDlg
 Local oBtnWally
 Local oHideEBar
 Local oShowEBar
 
 Private cAcesso  := "" //humpf... EnchoiceBar() necessita Disso...

 DEFINE MSDIALOG oDlg TITLE "Pandora" FROM aAdvSize[7],0 TO aAdvSize[6],aAdvSize[5]/1.3 OF GetWndDefault() PIXEL 

  @ 0,0 BITMAP oBmpPandora RESNAME "PANDORA" OF oDlg SIZE 0,0 NOBORDER WHEN .F. PIXEL
  oBmpPandora:lAutoSize := .T.
  oBmpPandora:lStretch  := .T.
  oBmpPandora:Align   := CONTROL_ALIGN_ALLCLIENT

  @ ( aMsObjSize[1,1] ) + 005 , ( aMsObjSize[1,2] ) BUTTON oBtnWally PROMPT OemToAnsi( "Onde Está Wally?" )         OF oDlg SIZE 150,13 PIXEL ACTION ShowWally()
  @ ( aMsObjSize[1,1] ) + 020 , ( aMsObjSize[1,2] ) BUTTON oHideEBar PROMPT OemToAnsi( "Esconda a Enchoice Bar" )       OF oDlg SIZE 150,13 PIXEL ACTION HideEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 035 , ( aMsObjSize[1,2] ) BUTTON oShowEBar PROMPT OemToAnsi( "Apresente a Enchoice Bar" )      OF oDlg SIZE 150,13 PIXEL ACTION ShowEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 050 , ( aMsObjSize[1,2] ) BUTTON oHideEBar PROMPT OemToAnsi( "Esconda Botão Ok da Enchoice Bar" )    OF oDlg SIZE 150,13 PIXEL ACTION HideBOKEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 065 , ( aMsObjSize[1,2] ) BUTTON oShowEBar PROMPT OemToAnsi( "Apresente Botão Ok da Enchoice Bar" )   OF oDlg SIZE 150,13 PIXEL ACTION ShowBOKEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 080 , ( aMsObjSize[1,2] ) BUTTON oHideEBar PROMPT OemToAnsi( "Esconda Botão Cancel da Enchoice Bar" )   OF oDlg SIZE 150,13 PIXEL ACTION HideBCancelEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 095 , ( aMsObjSize[1,2] ) BUTTON oShowEBar PROMPT OemToAnsi( "Apresente Botão Cancel da Enchoice Bar" )  OF oDlg SIZE 150,13 PIXEL ACTION ShowBCancelEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 110 , ( aMsObjSize[1,2] ) BUTTON oHideEBar PROMPT OemToAnsi( "Esconda Todos os Botões da Enchoice Bar" )   OF oDlg SIZE 150,13 PIXEL ACTION HideAllButtonsEnchoiceBar()
  @ ( aMsObjSize[1,1] ) + 125 , ( aMsObjSize[1,2] ) BUTTON oShowEBar PROMPT OemToAnsi( "Apresente Todos os Botões da Enchoice Bar" ) OF oDlg SIZE 150,13 PIXEL ACTION ShowAllButtonsEnchoiceBar()

 ACTIVATE DIALOG oDlg CENTERED ON INIT Eval( bInitDlg )

Return( NIL )

/*/
 Funcao: ShowWally
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowWally()

 Local aBitMap  := FindMsObject( "TBITMAP" )
 Local aButtons  := FindMsObject( "TBUTTON" )
 Local aMsDialg  := FindMsObject( "MSDIALOG" )
 Local oDlg   := aMsDialg[ aScan( aMsDialg , { |oObj| ( oObj:cCaption == OemToAnsi( "Pandora" ) ) } ) ]
 Local oBtnWally  := GetOctlFocus()

 Local oDlgWally
 Local oBmpWally
 Local oHideWally

 TRYEXCEPTION
  oBmpWally  := aBitMap[ aScan( aBitMap , { |oObj| ( oObj:cResName == OemToAnsi( "WALLY" ) ) } ) ]
    ENDEXCEPTION
 
 TRYEXCEPTION
  oHideWally  := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Olá, eu Sou Wally. Clique aqui e me esconda" ) ) } ) ]
 ENDEXCEPTION

 TRYEXCEPTION
  oDlgWally  := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Ou, aqui, me Mostre em uma Nova Dialog" ) ) } ) ]
    ENDEXCEPTION

 IF ( oBtnWally:cCaption == "Se Escondeu a ele, Apresente-o Clicando aqui" )
  oHideWally  := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Olá, eu Sou Wally. Clique aqui e me esconda" ) ) } ) ]
  oBmpWally  := aBitMap[ aScan( aBitMap , { |oObj| ( oObj:HWND == 4020 ) } ) ]
 EndIF

 IF !( ValType( oBmpWally ) == "O" )
  @ 015,170 BITMAP oBmpWally  RESNAME "WALLY" OF oDlg SIZE 500,500 NOBORDER WHEN .F. PIXEL MESSAGE OemToAnsi( "Olá, eu Sou Wally?" )
 Else
  oBmpWally:Show()
 EndIF  
 IF !( ValType( oHideWally ) == "O" )
  @ 175,170 BUTTON oHideWally PROMPT OemToAnsi( "Olá, eu Sou Wally. Clique aqui e me esconda" ) OF oDlg SIZE 180,13 PIXEL ACTION HideWally()
 Else
  oHideWally:Show()
 EndIF 

 IF !( ValType( oDlgWally ) == "O" )
  @ 190,170 BUTTON oDlgWally PROMPT OemToAnsi( "Ou, aqui, me Mostre em uma Nova Dialog" )  OF oDlg SIZE 180,13 PIXEL ACTION ShowNewWally()
 Else
  oDlgWally:Show()
 EndIF 

 oBtnWally:bAction := { || MsgInfo( "Já Me Encontrou" , "WALLY" ) }

Return( .T. )

/*/
 Funcao: HideWally
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function HideWally()
 Local aBitMap  := FindMsObject( "TBITMAP" )
 Local aButtons  := FindMsObject( "TBUTTON" )
 Local oDlgWally  := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Ou, aqui, me Mostre em uma Nova Dialog" ) ) } ) ]
 Local oBmpWally  := aBitMap[ aScan( aBitMap , { |oObj| ( oObj:cResName == OemToAnsi( "WALLY" ) ) } ) ]
 Local oBtnWally  := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Onde Está Wally?" ) ) } ) ]
 Local oHideWally := GetOctlFocus()
 Local oShowWally
 IF ( oHideWally:cCaption == "Esconda o Meu Parente" )
  oHideWally   := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Olá, eu Sou Wally. Clique aqui e me esconda" ) ) } ) ]
  oHideWally:Hide()
  oBmpWally   := aBitMap[ aScan( aBitMap , { |oObj| ( oObj:HWND == 4020 ) } ) ]
  oBmpWally:Hide()
  oDlgWally:Hide()
  oShowWally   := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Se Escondeu a ele, Apresente-o Clicando aqui" ) ) } ) ]
  oShowWally:bAction := { || ShowWally() }
 Else
  oHideWally:Hide()
  oBmpWally:Hide()
  oBtnWally:bAction := { || ShowWally() }
  oDlgWally:Hide()
 EndIF 
Return( .T. )

/*/
 Funcao: ShowNewWally
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowNewWally()

 Local aButtons  := {}
 Local aAdvSize  := MsAdvSize( .F. , .F. )
 Local aInfoAdvSize := { aAdvSize[1] , aAdvSize[2] , aAdvSize[3] , aAdvSize[4] , 0 , 0 }
 Local aObjCoords := { { 000 , 000 , .T. , .T. } }
 Local aMsObjSize := MsObjSize( aInfoAdvSize , aObjCoords )
    
 Local bInitDlg  := { || .T. }

 Local oDlg
 Local oBmpWally
 Local oBtnWally
 Local oBtnHideWSelf
 Local oBtnShowWSelf
 Local oBtnHideWParent
 Local oBtnShowWParent

 DEFINE MSDIALOG oDlg TITLE "Wally" FROM aAdvSize[7],0 TO aAdvSize[6],aAdvSize[5]/2.8 OF GetWndDefault() PIXEL 

  @ ( aMsObjSize[1,1] ) + 005 , ( aMsObjSize[1,2] ) BITMAP oBmpWally  RESNAME "WALLY" OF oDlg SIZE 500,500 NOBORDER WHEN .F. PIXEL MESSAGE OemToAnsi( "Olá, eu Sou Wally?" )
  @ ( aMsObjSize[1,1] ) + 160 , ( aMsObjSize[1,2] ) BUTTON oBtnWally  PROMPT OemToAnsi( "Quantos Wally´s?" ) OF oDlg SIZE 180,13 PIXEL ACTION CountWally()
  @ ( aMsObjSize[1,1] ) + 175 , ( aMsObjSize[1,2] ) BUTTON oBtnHideWSelf PROMPT OemToAnsi( "Clique aqui e Me Esconda" ) OF oDlg SIZE 180,13 PIXEL ACTION HideWallySelf()
  @ ( aMsObjSize[1,1] ) + 190 , ( aMsObjSize[1,2] ) BUTTON oBtnShowWSelf PROMPT OemToAnsi( "Se me Escondeu, Apresente-me Clicando aqui" ) OF oDlg SIZE 180,13 PIXEL ACTION MsgInfo( "Já Estou Visível" , "WAlly" )
  @ ( aMsObjSize[1,1] ) + 205 , ( aMsObjSize[1,2] ) BUTTON oBtnHideWSelf PROMPT OemToAnsi( "Esconda o Meu Parente" ) OF oDlg SIZE 180,13 PIXEL ACTION HideWally()
  @ ( aMsObjSize[1,1] ) + 220 , ( aMsObjSize[1,2] ) BUTTON oBtnShowWSelf PROMPT OemToAnsi( "Se Escondeu a ele, Apresente-o Clicando aqui" ) OF oDlg SIZE 180,13 PIXEL ACTION ShowWally()

 ACTIVATE DIALOG oDlg ON INIT Eval( bInitDlg )

Return( .T. )

/*/
 Funcao: CountWally
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function CountWally()

 Local aBitMap  := FindMsObject( "TBITMAP" )
 
 Local nWallyCount := 0
 
 aEval( aBitMap , { |oObj| IF( oObj:cResName == OemToAnsi( "WALLY" ) , ++nWallyCount , NIL ) } )

Return( MsgInfo( nWallyCount ) )

/*/
 Funcao: HideWallySelf
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function HideWallySelf()
 Local aBitMap := FindMsObject( "TBITMAP" )
 Local aButtons := FindMsObject( "TBUTTON" )
 Local oBmpWally := aBitMap[ aScan( aBitMap , { |oObj| ( oObj:cResName == OemToAnsi( "WALLY" ) ) } ) ]
 Local oBtnWally := aButtons[ aScan( aButtons , { |oObj| ( oObj:cCaption == OemToAnsi( "Se me Escondeu, Apresente-me Clicando aqui" ) ) } ) ]
 oBmpWally:Hide()
 oBtnWally:bAction := { || ShowWallySelf() }
Return( .T. )

/*/
 Funcao: ShowWallySelf
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowWallySelf()
 Local aBitMap := FindMsObject( "TBITMAP" )
 oBmpWally  := aBitMap[ aScan( aBitMap , { |oObj| ( oObj:cResName == OemToAnsi( "WALLY" ) ) } ) ]
 oBmpWally:Show()
Return( .T. )

/*/
 Funcao: HideEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function HideEnchoiceBar()
 Local aEBar := FindMsObject( "TBAR" )
 aEBar[1]:Hide()
Return( .T. )

/*/
 Funcao: ShowEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowEnchoiceBar()
 Local aEBar := FindMsObject( "TBAR" )
 aEBar[1]:Show()
Return( .T. )

/*/
 Funcao: HideBOKEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function HideBOKEnchoiceBar()
 Local aBtnBmp := FindMsObject( "TBTNBMP" )
 Local oBtnOk := aBtnBmp[ aScan( aBtnBmp , { |oObj| ( oObj:cCaption == OemToAnsi( "OK" ) ) } ) ]
 oBtnOk:Hide()
Return( .T. )

/*/
 Funcao: ShowBOKEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowBOKEnchoiceBar()
 Local aBtnBmp := FindMsObject( "TBTNBMP" )
 Local oBtnOk := aBtnBmp[ aScan( aBtnBmp , { |oObj| ( oObj:cCaption == OemToAnsi( "OK" ) ) } ) ]
 oBtnOk:Show()
Return( .T. )

/*/
 Funcao: HideBCancelEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function HideBCancelEnchoiceBar()
 Local aBtnBmp  := FindMsObject( "TBTNBMP" )
 Local oBtnCancel := aBtnBmp[ aScan( aBtnBmp , { |oObj| ( oObj:cCaption == OemToAnsi( "Cancelar" ) ) } ) ]
 oBtnCancel:Hide()
Return( .T. )

/*/
 Funcao: ShowBCancelEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowBCancelEnchoiceBar()
 Local aBtnBmp  := FindMsObject( "TBTNBMP" )
 Local oBtnCancel := aBtnBmp[ aScan( aBtnBmp , { |oObj| ( oObj:cCaption == OemToAnsi( "Cancelar" ) ) } ) ]
 oBtnCancel:Show()
Return( .T. )

/*/
 Funcao: HideAllButtonsEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function HideAllButtonsEnchoiceBar()
 Local aBtnBmp := FindMsObject( "TBTNBMP" )
 aEval( aBtnBmp , { |oObj| oObj:Hide() } )
Return( .T. )

/*/
 Funcao: ShowAllButtonsEnchoiceBar
 Autor: Marinaldo de Jesus
 Data: 26/06/2011
 Uso: Demostrar a Manipulacao de Objetos Visuais do Protheus
/*/
Static Function ShowAllButtonsEnchoiceBar()
 Local aBtnBmp := FindMsObject( "TBTNBMP" )
 aEval( aBtnBmp , { |oObj| oObj:Show() } )
Return( .T. )

/*/
 Funcao:  FindMsObject
 Autor:  Marinaldo de Jesus
 Data:  26/06/2011
 Uso:  Retornar Array com os Objetos conforme cMsClassName
 Sintaxe: StaticCall( RNPLIB016 , FindMsObject , cMsClassName )
/*/
Static Function FindMsObject( cMsClassName , oWnd )

 Local aMsObject := {}

 Local oException
 
 TRYEXCEPTION
 
  DEFAULT oWnd := GetWndDefault()
  
  IF !( ValType( oWnd ) == "O" )
   BREAK
  EndIF
  
  IF !( ValType( cMsClassName ) == "C" )
   BREAK
  EndIF

  cMsClassName := Upper( cMsClassName )
  aMsObject  := FindObject( @oWnd , @cMsClassName )
  AddObj( @oWnd , @cMsClassName , @aMsObject )

 CATCHEXCEPTION USIONG oException

 ENDEXCEPTION
 
Return( aMsObject )

/*/
 Funcao:  FindObject
 Autor:  Marinaldo de Jesus
 Data:  26/06/2011
 Uso:  Retornar Array com os Objetos conforme cMsClassName
/*/
Static Function FindObject( oWnd , cMsClassName , aMsObject )
 
 Local aChild
 Local aControls

 Local nChild
 Local nChilds
 Local nControl
 Local nControls
 
 Local oChild

 DEFAULT aMsObject := {}
 
 BEGIN SEQUENCE

  aControls := oWnd:aControls

  IF ( aControls == NIL )
   AddObj( @oWnd , @cMsClassName , @aMsObject )
   oChild := oWnd:oWnd
   IF !( oChild == NIL )
    AddObj( @oChild , @cMsClassName , @aMsObject )
    FindObject( @oChild , @cMsClassName , @aMsObject ) 
   EndIF 
   BREAK
  EndIF

  nControls := Len( aControls )
  For nControl := 1 To nControls
   oChild := aControls[ nControl ]
   IF ( oChild == NIL )
    Loop
   EndIF
   AddObj( @oChild , @cMsClassName , @aMsObject )
   TRYEXCEPTION
    aChild := oChild:aControls 
    IF !( aChild == NIL )
     nChilds := Len( aChild )
     For nChild := 1 To nChilds
      oChild := aChild[ nChild ]
      IF !( oChild == NIL )
       IF ( oChild == NIL )
        Loop
       EndIF
       AddObj( @oChild , @cMsClassName , @aMsObject )
       FindObject( @oChild , @cMsClassName , @aMsObject ) 
      EndIF 
     Next nChild
    EndIF  
   ENDEXCEPTION
  Next nControl

  oChild := oWnd:oWnd
  IF !( oChild == NIL )
   AddObj( @oChild , @cMsClassName , @aMsObject )
   FindObject( @oChild , @cMsClassName , @aMsObject ) 
  EndIF 

 END SEQUENCE

Return( aMsObject )

/*/
 Funcao:  AddObj
 Autor:  Marinaldo de Jesus
 Data:  26/06/2011
 Uso:  Adicionar o Objeto 
/*/
Static Function AddObj( oObj , cMsClassName , aMsObject )

 Local cClassName := Upper( oObj:ClassName() )
 
 Local lAddObj  := .F.

 IF ( cClassName == cMsClassName )
  IF ( lAddObj := ( aScan( aMsObject , { |oFind| ( oFind == oObj ) } ) == 0 ) )
   aAdd( aMsObject , oObj )
  EndIF
 EndIF

Return( lAddObj )

/*/
 Funcao:  GetOctlFocus
 Autor:  Marinaldo de Jesus
 Data:  26/06/2011
 Uso:  Retorna o Objeto Ativo
/*/
Static Function GetOctlFocus()
 Local oWnd := GetWndDefault()
Return( oWnd:oCtlFocus )

A origem de Tudo. Encontre-a clicando aqui

Post Scriptum:

1 ) U_TContainer foi implementada usando o Protheus 10. Para a versão 11 (by you) necessita alguns ajustes.

2 ) Para obter todo o conhecimento proposto, execute U_TContainer diretamente no programa Inicial do Protheus ou via IDE, caso contrário, surpresas aparecerão e, como ainda não tem o domínio... Imagine o que pode acontecer. Para executá-lo via "fórmula" ou "chamada via Menu" ajustes serão necessários. Tendo o domínio. Modifique-o.


[]s
иαldσ dj

Comentários

Postar um comentário

Postagens mais visitadas