Página 1 de 1

CodeBlock com Macro Substituição

Enviado: 10 Jun 2022 16:30
por carlaoonline
Boa tarde!


Estou com dificuldades em colocar um CodeBlock no evento ON CHANGE de um CheckBox.

O detalhe é que esse CodeBlock está em um elemento de uma matriz.

Queria fazer exatamente como fazemos com a macro substituição, mas no caso do codeblock atribuído a uma variável, está ficando sempre o conteúdo da última variável (pois trata-se de um codeblock)

Ex.:
No lugar disso

Código: Selecionar todos

   on change {||ManipulaCheckAcessos(6,24,This.Value)}
Quero usar isso:

Código: Selecionar todos

aCaixas:="{      {  10 ,  "teste"   ,  {||ManipulaCheckAcessos(6,24,This.Value)}     }   , ;
                      {   20    "teste2"  ,                   ""                                                  }

 bBloco:= aCaixas[1][3]        
  
  // e ao criar o controle, que o evento seja
   on change bBloco

Já tentei de várias maneiras mas aind não achei a forma correta.

Segue um código de exemplo que fiz, se eu colocar um IF lá na criação do controle, até resolvo meu problema, mas para o futuro gostaria de saber como se faz.


Código: Selecionar todos

#include "minigui.ch"

//-----------------------------------------------------------
Function Main()
//-----------------------------------------------------------
local nCaixa, nLinha, nColuna, bBloco, cNomeControle, nValorAcesso, aCaixas

       
       
define window form_acesso;
   at 000,000;    
   width 760;    
   height 560;    
   title 'Teste';    
   main ;    
   nosize    
   
   define tab tab_acesso;    
      of form_acesso;        
      at 003,010;        
      width form_acesso.width-020;        
      height form_acesso.height-090;        
      font 'verdana';        
      size 010;        
      bold;        
      value 001;        
      flat        
      
      
      
      page 'Clientes'         
      

      
           //   Coluna01         Coluna02                              Coluna03          

 // aCaixas:={ {   005   ,  "Menu Clientes"                  ,  "{||ManipulaCheckAcessos(6,24,This.Value)}" } , ;  // Enable ou Disable os chkbox_acesso_006 a 024        
    aCaixas:={ {   005   ,  "Menu Clientes"                  ,    "ManipulaCheckAcessos(6,24,This.Value)"   } , ;  // Enable ou Disable os chkbox_acesso_006 a 024                               
               {   007   ,  "Menu Clientes->Incluir"         ,                 ""                           } , ;        
               {   008   ,  "Menu Clientes->Ver"             ,                 ""                           } , ;        
               {   010   ,  "Menu Clientes->Transferir"      ,                 ""                           } , ;        
               {   011   ,  "Menu Clientes->Pesquisar"       ,                 ""                           } , ;        
               {   013   ,  "Tela do cliente->Botao Editar"  ,                 ""                           }  }        
      
      
            nLinha=20        
            nColuna=120        
      

            FOR nCaixa = 1 to LEN(aCaixas)        
                nLinha = nLinha + 30        
      
                // msgbox("teste    "+STR(nCaixa)+"     " +HB_VALTOSTR(Empty(aCaixas[nCaixa][03]) ) )        
      
                IF Empty(aCaixas[nCaixa][03])  // Se não houver codeblock na coluna 3        
      
                   bBloco:="Nothing()"           
                   // bBloco:="{||Nothing()}"        
      
                 ELSE        
      
      
        // AQUI, NAO SEI COMO COLOCAR O CODEBLOCK DENTRO DA VARIAVEL        
        // DE MODO QUE CADA "ON CHANGE" DE CADA CONTROLE CRIADO ABAIXO        
        // RECEBA O CODEBLOCK DA COLUNA 3 DA MATRIZ aCaixas, CASO POSSUA.        
      
                   // bBloco := aCaixas[nCaixa][03]        
                   // bBloco := &( "{ || " + aCaixas[nCaixa][03] + " }" )        
                   // bBloco := & ( {||ManipulaCheckAcessos(6,24,This.Value)}  )        
                   //  bBloco := "ManipulaCheckAcessos(6,24,This.Value)"        
                   // bBloco:=aCaixas[nCaixa][03]             
                   bBloco := "{||ManipulaCheckAcessos(6,24,This.Value)}"        
      
                ENDIF        
      
                cNomeControle="chkbox_acesso_"+RIGHT( "00"+ALLTRIM(     STR(  aCaixas[nCaixa][01]   )    ) ,3 )        
                define checkbox &cNomeControle        
                       caption aCaixas[nCaixa][02]        
                       col nColuna        
                       row nLinha        
                       width 350        
                       value .T.        
                       fontname 'verdana'        
                       fontsize 10        
                       fontbold .T.        
                       transparent .F.        
                       on change &(bBloco)          
                       // on change {||ManipulaCheckAcessos(6,24,This.Value)}        
                       // on change & (  {||ManipulaCheckAcessos(6,24,This.Value)}  )        
                       // on change &bBloco        
                       // on change bBloco        
      
      
                end checkbox        
            NEXT        
      
      end page        
                       
   end tab    
   
   on key escape action thiswindow.release    
end window
       

form_acesso.center
form_acesso.activate

Return 
//-------------------------------------------------



//-------------------------------------------------
Function ManipulaCheckAcessos(nInicio,nFinal,lMostra)
// Caso, por exemplo, se nInicio=6 e nFinal=24, entao, confomre lMostra
// habilita ou desabilita os controles checkBox_006 ate checkbox_Acesso_024
// caso existam.
//-------------------------------------------------
Local nControleCount, cNomeControle
FOR nControleCount=nInicio TO nFinal
    cNomeControle="chkbox_acesso_"+RIGHT("00"+ALLTRIM(STR(nControleCount)) ,3)
    IF _IsControlDefined(cNomeControle,"Form_Acesso")
       SETPROPERTY("Form_Acesso",cNomeControle,"ENABLED",lMostra)
    ENDIF
NEXT

// MSGBOX("Funcionou-> "+Str(nInicio)+ "   " + Str(nFinal) + "     "+Hb_ValToStr(lMostra) )
Return
//-------------------------------------------------



//-----------------------------------------------------------
Function Nothing()  // Retorna NIL
//-----------------------------------------------------------
MSGBOX("NADA")
Return Nil
//-----------------------------------------------------------


Grato por enquanto.

CodeBlock com Macro Substituição

Enviado: 10 Jun 2022 16:54
por alxsts
Olá!

Esqueça macro substituição...

A linha abaixo, da forma como você escreveu, cria uma string...

Código: Selecionar todos

bBloco := "{||ManipulaCheckAcessos(6,24,This.Value)}"
Se quer um code block, retire as aspas:

Código: Selecionar todos

bBloco := { |l, c, v| ManipulaCheckAcessos( l, c, v ) }
No evento, avalie o code block com a função própria (Eval():

Código: Selecionar todos

on change Eval( bBloco, 6, 24, This.Value )   
Pode até não funcionar pois não conheço MiniGUI mas, o caminho é este...

CodeBlock com Macro Substituição

Enviado: 10 Jun 2022 22:12
por carlaoonline
Opa!

Valeu pela ajuda.
carlaoonline escreveu:No evento, avalie o code block com a função própria (Eval():
Expandir visualizacaoVer codigo
1 on change Eval( bBloco, 6, 24, This.Value )   


Pode até não funcionar pois não conheço MiniGUI mas, o caminho é este...
O exemplo vai me servir bastante para outras partes, nesse caso aqui funciona da mesma forma que colocando o codeblock direto,
o problema é que na criação dos controles em um loop, ficam todo os eventos ON CHANGE Iguais (diferenciados apenas pelos parâmetros)

O que eu preciso é colocar no evento ON CHANGE de cada checkbox (que são criados vários em um único loop)
, um codeblock que talvez sejam totalmente diferentes, ou seja, são os codeblocks que estão na matriz "aCaixas" que serão passada como referência.


on change (QUERO COLOCAR AQUI O CODEBLOCK CORRESPONDENTE QUE ESTÁ NA MATRIZ aCaixas[coluna3] A CADA LOOP)


Reparem no loop que os controles CheckBox são criados na quantidade da LEN(aCaixas)
e em cada CheckBox eu queria colocar o codeblock da matriz.

Código: Selecionar todos

#include "minigui.ch"

//-----------------------------------------------------------
Function Main()
//-----------------------------------------------------------
local nCaixa, nLinha, nColuna, bBloco, cNomeControle, nValorAcesso
Local cStringCodeBlock, aCaixas

define window form_acesso;
   at 000,000;    
   width 760;    
   height 560;    
   title 'Teste';    
   main ;    
   nosize    
   
   define tab tab_acesso;    
      of form_acesso;        
      at 003,010;        
      width form_acesso.width-020;        
      height form_acesso.height-090;        
      font 'verdana';        
      size 010;        
      bold;        
      value 001;        
      flat        
   
           //   Coluna01         Coluna02                              Coluna03          

    aCaixas:={ {   005   ,  "Menu Clientes"                  ,  {||ManipulaCheckAcessos(6,24,This.Value)} } , ;  // Enable ou Disable os chkbox_acesso_006 a 024        
               {   007   ,  "Menu Clientes->Incluir"         ,  {||Nothing()}                           } , ;        
               {   008   ,  "Menu Clientes->Ver"             ,  {||MsgBox("Teste"), Muda_fnt(This.name) }                           } , ;        
               {   010   ,  "Menu Clientes->Transferir"      ,  {||Nothing()}                           } , ;        
               {   011   ,  "Menu Clientes->Pesquisar"       ,  {||MsgBox("Novo"), Muda_Cor(This.Name)  }                       } , ;        
               {   013   ,  "Tela do cliente->Botao Editar"  ,  {||Nothing()}                           }  }        
      
      
            nLinha=20        
            nColuna=120        
      
      page 'Clientes'         
            FOR nCaixa = 1 to LEN(aCaixas)        
                nLinha = nLinha + 30        
                cNomeControle = "chkbox_acesso_"+RIGHT( "00"+ALLTRIM(     STR(  aCaixas[nCaixa][01]   )    ) ,3 )        
				cStringCodeBlock = aCaixas[nCaixa][03]
                define checkbox &cNomeControle        
                       caption aCaixas[nCaixa][02]  
                       col nColuna        
                       row nLinha        
					   
					   
                       on change (QUERO COLOCAR AQUI O CODEBLOCK CORRESPONDENTE   aCaixas[nCaixa][3]   A CADA LOOP)
					   
					   
					   
                end checkbox        
            NEXT        
      end page        
                       
   end tab    
   
   on key escape action thiswindow.release    
end window
       

form_acesso.center
form_acesso.activate

Return 
//-------------------------------------------------



//-------------------------------------------------
Function Cria_Bloco(cValor)
//-------------------------------------------------
return &("{||"+cValor+"}")
//-------------------------------------------------


//-------------------------------------------------
Function Muda_Fnt(cNomeControle)
//-------------------------------------------------
SETPROPERTY("Form_Acesso",cNomeControle,"FontBold", GETPROPERTY("Form_Acesso",cNomeControle,"value") )
return 
//-------------------------------------------------


//-------------------------------------------------
Function Muda_Cor(cNomeControle)
//-------------------------------------------------
IF GETPROPERTY("Form_Acesso",cNomeControle,"value")
   SETPROPERTY("Form_Acesso",cNomeControle,"fontname","Arial"  )
 ELSE  
   SETPROPERTY("Form_Acesso",cNomeControle,"fontname","Times New Roman"  )
ENDIF   
return 
//-------------------------------------------------




//-------------------------------------------------
Function ManipulaCheckAcessos(nInicio,nFinal,lMostra)
// Caso, por exemplo, se nInicio=6 e nFinal=24, entao, confomre lMostra
// habilita ou desabilita os controles checkBox_006 ate checkbox_Acesso_024
// caso existam.
//-------------------------------------------------
Local nControleCount, cNomeControle
FOR nControleCount=nInicio TO nFinal
    cNomeControle="chkbox_acesso_"+RIGHT("00"+ALLTRIM(STR(nControleCount)) ,3)
    IF _IsControlDefined(cNomeControle,"Form_Acesso")
       SETPROPERTY("Form_Acesso",cNomeControle,"ENABLED",lMostra)
    ENDIF
NEXT

// MSGBOX("Funcionou-> "+Str(nInicio)+ "   " + Str(nFinal) + "     "+Hb_ValToStr(lMostra) )
Return
//-------------------------------------------------

//-----------------------------------------------------------
Function Nothing()  // Retorna NIL
//-----------------------------------------------------------
MSGBOX("NADA")
Return Nil
//-----------------------------------------------------------


Esse exemplo é apenas didático, obviamente será usado em outra finalidade.

Ainda não consegui.

Grato.

CodeBlock com Macro Substituição

Enviado: 11 Jun 2022 16:46
por JoséQuintas
As vezes com variáveis, melhor usar uma função.

Código: Selecionar todos

bCode := ToBlock( array[3] )
...
FUNCTION ToBlock( x )
   RETURN &( x )
Deste jeito, não importa se array[3] vai mudar de valor depois.
Apenas exemplo, e com macro, porque citou macro.

CodeBlock com Macro Substituição

Enviado: 11 Jun 2022 22:11
por carlaoonline
Usando com funções realmente funciona, porém se quiser usar os recursos de um codeblock não tem como, e tb
o empecilho é que não pode usar "this.value" ou qualquer outra referência 'This',
tem que usar GetProperty('Form_Acesso','chkbox_acesso_005','value') mencionando o 'nome do controle'
e daí já sai um pouco do automático dependendo a utilização...


Resumindo, tentei de inúmeras maneiras e cheguei a conclusão que:

No ON CHANGE do checkbox (e talvez de outas propriedades e tb de outros controles...)
NÃO TEM COMO usar um CodeBlock que está em uma matriz,

tem que digitar ele na linha ON CHANGE.


Assim é tranquilo...

Código: Selecionar todos

ON CHANGE {||MsgBox(This.Name) , ManipulaCheckAcessos(6,24,this.value)} 


Assim não teve jeito...

Código: Selecionar todos

     // o bloco direto na matriz...
aCaixas:= {   005 ,  "Menu 1" ,  {||MsgBox(This.Name) , ManipulaCheckAcessos(6,24,this.value)}   }
bCode= aCaixas[3]

     //  ou  o bloco com aspas (dentro de uma String) ...
aCaixas:= {   005 ,  "Menu 1" ,  " {||MsgBox(This.Name) , ManipulaCheckAcessos(6,24,this.value)}"  }
bCode= aCaixas[3]

    // ou o bloco ainda sem formato de bloco, a ser convertido depois em uma função   
aCaixas:= {   005 ,  "Menu 1" ,  "MsgBox(This.Name) , ManipulaCheckAcessos(6,24,this.value) "  }
bBloco=Cria_Bloco( aCaixas[3])


...
ON CHANGE     ??  bBloco  ??  &bBloco  ??  EVAL...   ??   // não teve jeito com codeblock, somente com função




Assim FUNCIONOU,
usando macro substituição da string que contém as funções que está na matriz,
funciona se não usar a referência "This"

Código: Selecionar todos

#include "minigui.ch"

//-----------------------------------------------------------
Function Main()
//-----------------------------------------------------------
local nCaixa, nLinha, nColuna, bBloco, cNomeControle, nValorAcesso, cString
Local cStringCodeBlock, aCaixas

define window form_acesso;
   at 000,000;    
   width 760;    
   height 560;    
   title 'Teste';    
   main ;    
   nosize    
   
   define tab tab_acesso;    
      of form_acesso;        
      at 003,010;        
      width form_acesso.width-020;        
      height form_acesso.height-090;        
      font 'verdana';        
      size 010;        
      bold;        
      value 001;        
      flat        

   

/*
           //   Coluna01         Coluna02                              Coluna03          
    aCaixas:={ {   005   ,  "Menu Clientes"                  ,  {||ManipulaCheckAcessos(6,24,this.value)}                } , ; // GetProperty('Form_Acesso','chkbox_acesso_005','value')
               {   007   ,  "Menu Clientes->Incluir"         ,  {||Nothing(), msgbox('Valor='+HB_ValToStr(This.Value))}  } , ;        
               {   008   ,  "Menu Clientes->Ver"             ,  {||MsgBox('Teste'), Muda_fnt(This.name)}                 } , ;        
               {   010   ,  "Menu Clientes->Transferir"      ,  {||Nothing(), msgbox('Linha='+HB_ValToStr(This.Row))}    } , ;        
               {   011   ,  "Menu Clientes->Pesquisar"       ,  {||MsgBox('Novo'), Muda_Cor(This.Name)}                  } , ;        
               {   013   ,  "Tela do cliente->Botao Editar"  ,  {||Nothing(), msgbox('Testando')}                        }   }      
*/

           //   Coluna01         Coluna02                              Coluna03          	  
    aCaixas:={ {   005   ,  "Menu Clientes"                  ,  "Nothing(), ManipulaCheckAcessos(6,24,GetProperty('Form_Acesso','chkbox_acesso_005','value'))"     } , ; // GetProperty('Form_Acesso','chkbox_acesso_005','value')
               {   007   ,  "Menu Clientes->Incluir"         ,  "Nothing(), msgbox('Valor='+HB_ValToStr(GetProperty('Form_Acesso','chkbox_acesso_007','value')))"  } , ;        
               {   008   ,  "Menu Clientes->Ver"             ,  "MsgBox('Teste'), Muda_fnt(GetProperty('Form_Acesso','chkbox_acesso_008','name'))"                 } , ;        
               {   010   ,  "Menu Clientes->Transferir"      ,  "Nothing(), msgbox('Linha='+HB_ValToStr(GetProperty('Form_Acesso','chkbox_acesso_010','row')))"    } , ;        
               {   011   ,  "Menu Clientes->Pesquisar"       ,  "MsgBox('Novo'), Muda_Cor(GetProperty('Form_Acesso','chkbox_acesso_011','name'))"                  } , ;        
               {   013   ,  "Tela do cliente->Botao Editar"  ,  "Nothing(), msgbox('Testando')"                        }   }      	  
	  
	  
            nLinha=20        
            nColuna=120        
      
      page 'Clientes'         
            FOR nCaixa = 1 to LEN(aCaixas)        
                nLinha = nLinha + 30        
                cNomeControle = "chkbox_acesso_"+RIGHT( "00"+ALLTRIM(     STR(  aCaixas[nCaixa][01]   )    ) ,3 )        
				
				cString=aCaixas[nCaixa][03]
				MsgBox("nCaixa="+Alltrim(Str(nCaixa))+"    cString="+HB_ValToStr(cString))				
				
                define checkbox &cNomeControle        
                       caption  aCaixas[nCaixa][02]  
                       col      nColuna        
                       row      nLinha        
                       value    .T.
	   
	   
                       on change &cString

				  
                end checkbox      
   
				
            NEXT        
      end page        
                       
   end tab    
   
   on key escape action thiswindow.release    
end window
       

form_acesso.center
form_acesso.activate

Return 
//-------------------------------------------------



//-------------------------------------------------
Function ToBlock( x )
//-------------------------------------------------
RETURN &( x )
//-------------------------------------------------


//-------------------------------------------------
Function Cria_Bloco(cValor)
//-------------------------------------------------
return &("{||"+cValor+"}")
//-------------------------------------------------


//-------------------------------------------------
Function Muda_Fnt(cNomeControle)
//-------------------------------------------------
msgbox("Controle->"+cNomeControle)
SETPROPERTY("Form_Acesso",cNomeControle,"FontBold", GETPROPERTY("Form_Acesso",cNomeControle,"value") )
return 
//-------------------------------------------------

//-------------------------------------------------
Function Muda_Cor(cNomeControle)
//-------------------------------------------------
IF GETPROPERTY("Form_Acesso",cNomeControle,"value")
   SETPROPERTY("Form_Acesso",cNomeControle,"fontname","Arial"  )
 ELSE  
   SETPROPERTY("Form_Acesso",cNomeControle,"fontname","Times New Roman"  )
ENDIF   
return 
//-------------------------------------------------

//-------------------------------------------------
Function ManipulaCheckAcessos(nInicio,nFinal,lMostra)
// Caso, por exemplo, se nInicio=6 e nFinal=24, entao, confomre lMostra
// habilita ou desabilita os controles checkBox_006 ate checkbox_Acesso_024
// caso existam.
//-------------------------------------------------
Local nControleCount, cNomeControle
FOR nControleCount=nInicio TO nFinal
    cNomeControle="chkbox_acesso_"+RIGHT("00"+ALLTRIM(STR(nControleCount)) ,3)
    IF _IsControlDefined(cNomeControle,"Form_Acesso")
       SETPROPERTY("Form_Acesso",cNomeControle,"ENABLED",lMostra)
    ENDIF
NEXT

// MSGBOX("Funcionou-> "+Str(nInicio)+ "   " + Str(nFinal) + "     "+Hb_ValToStr(lMostra) )
Return
//-------------------------------------------------

//-----------------------------------------------------------
Function Nothing()  // Retorna NIL
//-----------------------------------------------------------
MSGBOX("NADA")
Return Nil
//-----------------------------------------------------------

Lá no fundo, ainda existe a esperança, quem sabe está na declaração da variável:
Local bBloco AS codeblock ...


Grato pelo apoio.

CodeBlock com Macro Substituição

Enviado: 12 Jun 2022 00:45
por JoséQuintas
quote="carlaoonline"]Resumindo, tentei de inúmeras maneiras e cheguei a conclusão que:

No ON CHANGE do checkbox (e talvez de outas propriedades e tb de outros controles...)
NÃO TEM COMO usar um CodeBlock que está em uma matriz,
tem que digitar ele na linha ON CHANGE.[/quote]

Pequena correção

NÃO existe OOP em minigui, isso é criado apenas pra fonte DO USUÁRIO, que passa pelo pré-processador e processa os #include.
Quando coloca o mesmo fonte em codeblock, ele não existe, porque não tem pré-processador.
Não é que não funciona em array, é que o código fonte NÃO existe pra fazer o macro, ele NÃO é aceito sem pré-processador.

Funciona direto no ON CHANGE porque aí ele é traduzido na compilação pelo pré-processador.
Mas como texto.... o texto está errado, em formato inválido pra run-time.

CodeBlock com Macro Substituição

Enviado: 12 Jun 2022 00:49
por JoséQuintas
Simples:

Compile com /p e olhe o arquivo PPO.
Se colocar igual no codeblock funciona.

Vai ter que fazer sempre isso?
Vai sim, fazer o que....