Duvida sobre um o processamento de BUTTON

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Fernando Almeida
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 24 Set 2016 12:53
Localização: Dourados - MS

Duvida sobre um o processamento de BUTTON

Mensagem por Fernando Almeida »

Boa tarde colegas.
Gostaria de encontrar uma solução para o problema com que me debato.
Fiz no Form de vendas uma rotina de escolha de mesa por definição, e em termos de apresentação está a funcionar bem.
Mas quando eu vou fazer a escolha desse botão que pretendo, não consigo selecionar na ação o valor dele.
Abaixo vou colocar as imagens para verem como é apresentado.

Imagem da sala interior:
Imagem

Imagem da Sala no exterior:
Imagem

A rotina apresenta as mesas definidas nesses espaços e com a imagem de acordo com o estado da mesa como veem na imagem.
A parte mais dificil é eu conseguir ir buscar o valor que se encontra no respectivo botão.
Vou apresentar aqui a rotina no qual zim um tabelador com os departamentos que preciso, e disponho os botões de acordo com o numero de mesas lá colocadas.

Código: Selecionar todos

DEFINE TAB Tab_BuscaMesa AT 20 , 20 WIDTH 690 HEIGHT 320 VALUE 1 FONT "Comic Sans MS" SIZE 11;
	       TOOLTIP "" HOTTRACK ON CHANGE Nil MULTILINE    &&VERTICAL .f.  
	  
        cTextFName := GetStartUpFolder()+"\CONF\DEFBOTAO.TXT"
        IF !FILE( cTextFName )
           HB_MEMOWRIT( cTextFName, ;
                        "40" + CRLF + "40" + CRLF + "80" + CRLF + "80" + CRLF +;
                        "numMesaVD :=VAL(matApreMesas[numMesaApr])" + CRLF + "matApreMesas[numMesaApr]" + CRLF +;
                        "Selecione a mesa pretendida." + CRLF +; 
			            ".t." + CRLF + ".f." + CRLF + "Imagens\GrafMesas\" + CRLF + "TOP" )
        ENDIF 
		
        FOR xTab :=1 TO LEN( matLocalMesa )
           PAGE RTRIM(matLocalMesa[xTab,1]) IMAGE RTRIM(matLocalMesa[xTab,2])
		        SELECT('P_MESAS')
                GO xTab 

                matApreMesas := HB_ATokens( RTRIM(P_MESAS->PlanoMesas), '.', .F., .F. )
                matMesaBotao := HB_ATokens( MEMOREAD( cTextFName ), CRLF )

                LnBotao :=0
                ColBotao:=0    
                FOR numMesaApr :=1 TO LEN(matApreMesas)
                    SELECT('MOVVDDIA')
	                OrdSetFocus(1)
					
                    oNomeBotao :='M'+IF(MOVVDDIA->(DBSEEK(VAL(matApreMesas[numMesaApr]))),;
	                                    IF(MOVVDDIA->MesaFecha==.f., HB_USUBSTR(matLocalMesa[xTab,1],1,4)+'Ocupada',;
								           HB_USUBSTR(matLocalMesa[xTab,1],1,4)+'Fechada'), HB_USUBSTR(matLocalMesa[xTab,1],1,4)+'Livre') 
					oPicture   :=oNomeBotao
					oNomeBotao +=matApreMesas[numMesaApr]
					
			        oPicture   :=STRTRAN(oPicture, "Sala", "esa")  
					oPicture   :=STRTRAN(oPicture, 'Espl', 'esa') 
					oPicture   :=STRTRAN(oPicture, 'Balc', 'esa') 
					oPicture   :=STRTRAN(oPicture, 'IFoo', 'esaIF') + "_28x28.PNG"
									
	                DEFINE BUTTON &oNomeBotao
                        ROW    VAL(matMesaBotao[1]) + LnBotao 
                        COL    VAL(matMesaBotao[2]) + ColBotao
                        WIDTH  VAL(matMesaBotao[3])  
                        HEIGHT VAL(matMesaBotao[4]) 
                        ACTION {|| MsgInfo({'Nº Mesa   : ' + HB_NTos(VAL(oNomeBotao)), CHR(13),;
						                    'Nome Botao: ' + oNomeBotao}), Nil }        &&ThisWindow.Release }    
                        CAPTION "&"+&(matMesaBotao[6])   
                        FONTNAME "Arial"
                        FONTSIZE 9
                        TOOLTIP matMesaBotao[7]
                        FONTBOLD .T.						
                        VISIBLE .T.
                        TRANSPARENT .T.
                        MULTILINE .F.
                        PICTURE matMesaBotao[10] + oPicture 
                        PICTALIGNMENT TOP 
                        ONGOTFOCUS {|| ExpFilter :='FormBuscaMesa.' + oNomeBotao + '.CAPTION' }						
                    END BUTTON
		   
	                ColBotao +=VAL(matMesaBotao[3]) + 5
	                IF ColBotao>=690 - ( VAL(matMesaBotao[3]) + VAL(matMesaBotao[2]) ) 
	                   ColBotao :=0  
	                   LnBotao  +=VAL(matMesaBotao[4])
	                ENDIF 
	
                NEXT numMesaApr	
                SELECT('P_MESAS') 
				
		   END PAGE 
		NEXT xTab    	        
		
    END TAB 
Fico a aguardar a resposta e disponível para quaiquer esclarecimentos adicionais.
Não sei se estou a colocar a msg no local certo, mas presumo que sim.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

aqui

Código: Selecionar todos

 DEFINE BUTTON &oNomeBotao
	                        ROW    VAL(matMesaBotao[1]) + LnBotao
	                        COL    VAL(matMesaBotao[2]) + ColBotao
	                        WIDTH  VAL(matMesaBotao[3]) 
	                        HEIGHT VAL(matMesaBotao[4])
	                        ACTION {|| MsgInfo({'Nº Mesa   : ' + HB_NTos(VAL(oNomeBotao)), CHR(13),;
	                                      'Nome Botao: ' + oNomeBotao}), Nil }       
Não entendo dessa LIB, mas tem a ver com o codeblock.
Veja se tem função pra nome do botão atual.
Ou, se aceitar, criar o codeblock numa função pra garantir o conteúdo da variável.

Código: Selecionar todos

ACTION ClickOnButton( oNomeBotao )
...
FUNCTION ClickOnButton( oNomeBotao )
 RETURN {|| MsgInfo({'Nº Mesa   : ' + HB_NTos(VAL(oNomeBotao)), CHR(13),;
	                                      'Nome Botao: ' + oNomeBotao}), Nil }
Parece a mesma coisa, mas não é.
Desse jeito oNomeBotao usado no codeblock é a variável local da função e vai ter o mesmo conteúdo na execução, o mesmo de quando foi criado.
Do outro jeito, o conteúdo da variável vai ser o último atribuído, e não o que está pensando que vai ser.
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/
Fernando Almeida
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 24 Set 2016 12:53
Localização: Dourados - MS

Duvida sobre um o processamento de BUTTON

Mensagem por Fernando Almeida »

Boa noite Sr. José Quintas, aproveito para lhe agradeçer.
Sobre a rotina, ela foi criada por mim, não é de lib nenhuma.
O que eu faço é o seguinte:
Leio os departamentos ativos no arquivo de plano de mesas de cada usuário, porque tenho um plano de mesas por usuário, e crio uma matriz com os nomes, mesas ativas nesse usuário e as imagens desses departamentos.
Em seguida abro o form de busca das mesas.

Código: Selecionar todos

FUNCTION BuscaMesas()
PRIVATE cTextFName, oPicture 
PRIVATE matApreMesas, numMesaApr                                          &&matMesaBotao, oNomeBotao
PRIVATE aLinhas, LnBotao, ColBotao
PRIVATE matLocalMesa :={}, xTab, FechaQuadroMesas :=.f. 

SELECT('P_MESAS')
GO TOP
DO WHILE !EOF()
   AADD(matLocalMesa, {P_MESAS->Localizaca, P_MESAS->Img} )
   SKIP
ENDDO

IF IsWindowActive("Main")
   DoMethod("Main", "Minimize")
ENDIF 

IF IsWindowActive("FormBuscaMesa")
   DoMethod("FormBuscaMesa", "MINIMIZE")
   DoMethod("FormBuscaMesa", "RESTORE")
   DoMethod("FormBuscaMesa", "SETFocus")
ELSE
   Load Window FormBuscaMesa
   FormBuscaMesa.Center 
   FormBuscaMesa.Activate
ENDIF 
Return Nil
No form eu crio um Tabelador e suas PAGES de apresentação dos departamentos com as respectivas mesas
Após isso crio o arquivo caso ele ainda não exista, se exister só o lê, com as coordenadas dessas mesas para apresentar no local, com a medida, Image, Caption e Action.

Assim se aumentar ou diminuir o numero de mesas, basta alterar no arquivo de configurações para ele fazer a apresentação automaticamente, sem ter que mexer no aplicativo.
Após ter lido esse arquivo, verifico o estado da mesa e escolho a imagem que lhe corresponde, Apresenta as mesas livres, ocupadas ou fechadas.
O aplicativo com essa informação cria automaticamente os botões para poder fazer a sua escolha.
Isso tudo esta a funcionar perfeitamente, como mostro nas imagens acima apresentadas, só não consigo usar o ACTION bem porque ele vai buscar o nome do botão da ultima posição da matriz.
Curioso é que se eu uso por exemplo a macro &oNomeBotao, ele apresenta o nome correto do botao onde me encontro, mas dá erro dizendo que essa variavél não existe.
Ex: estando colocado no botao da mesa da Sala Interior nº 10 ele dá: oNomeBotao=MesaSala41 e a &oNomeBotao=MesaSala10.

Já tinha feito dessa maneira, enviar a variavél para uma função e apresenta-la na funcao, mas o resultado e o mesmo:

oNomeBotao=MesaSala41

Fico-lhe muito grato, afinal domina muito bem a linguagem pelo que eu leio aqui, se me conseguir dar alguma pista para eu poder colmatar esse problema.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

Fernando Almeida escreveu:Sobre a rotina, ela foi criada por mim, não é de lib nenhuma.
Eu disse sobre a LIB, que deve ser minigui.

Sobre o problema:
Por acaso ACTION por sí só já não é um codeblock ?
Se for assim, só se atribuir em separado e não em ACTION

Algo como button:bAction := e a rotina que já coloquei

Esse negócio das LIBs ficarem alterando o comportamento normal do Harbour só complica tudo.
O fonte que você vê de um jeito é usado de outro jeito.
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/
Fernando Almeida
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 24 Set 2016 12:53
Localização: Dourados - MS

Duvida sobre um o processamento de BUTTON

Mensagem por Fernando Almeida »

Boa tarde Sr. José.

Resolvi o problema desta forma:

Código: Selecionar todos

DEFINE BUTTON &oNomeBotao
                        ROW    VAL(matMesaBotao[1]) + LnBotao 
                        COL    VAL(matMesaBotao[2]) + ColBotao
                        WIDTH  VAL(matMesaBotao[3])  
                        HEIGHT VAL(matMesaBotao[4]) 
                        ACTION {|| numMesaVD :=ClickOnButton( numMesaVD, CATS_getControlFocus(), this.focusedcontrol, CATS_getFormFocus() ),;
						           ThisWindow.Release, DoMethod('Pedido_de_Vendas', 'Grid_Pedidos', 'SetFocus') }
					    CAPTION "&"+&(matMesaBotao[6])   
Assim com estas funções dá a possibilidade de ir buscar o Nome do Form, do Button e da Caption.
Eu ontem a noite lembrei-me deles, usei-os e funciona bem.

Pergunto-lhe se acha normal abrir este Form, fazer umas 3 ou 4 mesas e ele no gerenciador de tarefas do windows apresentar um consumo de 40mb de RAM.
Eu não vejo porquê este consumo todo, mas como não tenho muita experiencia ainda com esta linguagem faço essa pergunta.
Ainda não tive problemas com a memória mas gostaria de saber se é normal ou não esse gasto todo.
Como voltei a programar, após a ausencia de alguns anos, e nestas novas linguagens gráficas como ainda tenho pouca experiencia é natural que me depare com algumas duvidas.
Vou fazer-lhe uma pergunta, tem alguma rotina com o control TREE por definição ?
Eu gostaria e vou tentar criar uma rotina com esse control de grupos e sub-grupos por definição, ou seja lendo os dados do arquivo DBF e contruindo-a com esse dados.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

Como eu disse, não uso essa LIB, alguém que usa deve ter rotina pra isso.

Em GUI, tudo consome recurso, principalmente imagens.
Imagens não liberadas vão consumir memória, mesmo que não estejam na tela.
Um recurso do windows é compartilhar imagens, assim uma mesma imagem pode ser utilizada várias vezes sem consumo adicional de memória. As LIBs costumam chamar isso de OEM ao invés de SHARED, o que acaba não chamando atenção ao recurso.
Já hwgui, que é outra lib e não essa, criou seu array de imagens, e acaba fazendo parecido, mas de outro jeito.
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/
Fernando Almeida
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 24 Set 2016 12:53
Localização: Dourados - MS

Mensagem por Fernando Almeida »

Boa noite Sr. José,
Eu vou perguntar se acha mais conveniente criar um arquivo RC com as imagesn lá definidas ou usar as imagens usanso os caminhos.
Porque eu estou a usar as imagens por chamada, se assim posso dizer.
Eu peço-lhe algumas orientações porque eu não tenho muita "rodagem" ainda e talvez não siaba escolher as melhores escolhas.
Pergunto-lhe, eu tenho uma rotina de gerador de listagens em MS-DOS feita e a funcionar bem, com escolha e indices, campos, totalizadores, etc, a funcionar em MS-DOS bem. Se lhe pedisse para passar para ambiente gráfico, estava disposto a fazer isso. E fazer um orçamento ?
Peço para tolerar alguma insistencia da minha parte mas como estou num pais diferente do meu, gostaria de ter algum apoio.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

Pra imagens uso 3 formas diferentes:
- Em resource do Windows (RC)
- Em resource do Harbour #pragma
- No banco de dados MySQL
Depende da finalidade de uso, e algumas delas obrigatoriamente precisam existir no EXE e não depender de nada externo

Sobre a transformação pra GUI, você tem mais experiência do que eu.
Se o problema é por causa do EXE em separado, GTWVG pode ser uma opção alternativa pra usar simultâneo com minigui - no Harbour pode, no XHarbour não sei.
E tem a PDFClass que gera relatórios em PDF aproveitando um pouco a forma tradicional, o que pode aproveitar um pouco os fontes.
Basicamente mudaria de @ row, col SAY pra oPDF:DrawText( row, col, informacao, picture )
A princípio isso alteraria pra PDF, mas pode acrescentar mais recursos, não apenas texto.
minigui tem algo parecido, mas acho que é por coordenadas x/y.
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/
Fernando Almeida
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 24 Set 2016 12:53
Localização: Dourados - MS

Duvida sobre um o processamento de BUTTON

Mensagem por Fernando Almeida »

Mas ao criar um RC com as imagens todas, o executável fica demasiado grande, penso eu.
Sobre o consumo de memória, o aplicativo como está, inacabado, ao ser executado apresenta um consumo de 5,9Mb.
Chamo o form de vendas e faço umas 3, 4 mesas e ele mostra um consumo de 40Mb.
Ainda não tive problemas de memória, mas acho o consumo alto.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

memoria.png
Isso é relativo.
Aqui meu aplicativo ocupa 11MB.
Se comparar ao whatsapp ocupando 150MB, whatsapp faz muito menos que o aplicativo.
Padronizei imagens, de ícones pelo menos, a 32 x 32.
BMP acho que é o maior vilão.
As imagens são convertidas para o formato usado pelo Windows, independente de como seja a origiral.
Modificar a imagem original pode economizar tamanho e memória.
Imagens grandes, melhor deixar no disco ou MySQL ou outra base de dados.
Antes, até DLL eu deixava como resource.
Atualmente, até a atualização do aplicativo acaba sendo mais fácil através do MySQL: um terminal salva no MySQL, os demais baixam automático de lá.
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/
Fernando Almeida
Usuário Nível 1
Usuário Nível 1
Mensagens: 33
Registrado em: 24 Set 2016 12:53
Localização: Dourados - MS

Duvida sobre um o processamento de BUTTON

Mensagem por Fernando Almeida »

Vou continuar, se aparecer algum problema, resolvo-o depois.
Pergunto-lhe como estou a fazer isto por definição, encontrei um novo problema.
Quando entro no Form com o Tabelador constituido por o numero de secções de um restaurante, preencho esses espaços com as respectivas mesas.
Faço uma verificação e se o numero de mesas for superior ao ocupado nesse espaço, apenas apresento as mesas que o espaço comporta
e acrescentei uns botões para mudar de página. Assim que eu digito um desses botões, faço um release das mesas apresentadas e faço um novo ciclo
para criar os botões com as novas mesas. até aqui está tudo a funcionar bem, ele elimina essa mesas apresentadas, mas quando faço o DEFINE BUTTON da mesma forma que no inicio do Form ele dá o erro que eu exponho em seguida.

Data:25/05/2023 Hora: 14:49:06
Erro BASE/1081 Erro nos parノetros: +


Chamado de _DEFINEMIXEDBUTTON(361)
Chamado de ACERTAPAG(160)
Chamado de (b)BUSCAMESAS(238)
Chamado de _DOCONTROLEVENTPROCEDURE(6056)
Chamado de EVENTS(1801)
Chamado de DOMESSAGELOOP(0)
Chamado de _ACTIVATEWINDOW(5717)
Chamado de DOMETHOD(9003 )
Chamado de BUSCAMESAS(621)
Chamado de (b)MAIN_BUTTON_PEDIDOS_DE_VENDA_ACTION(1269)
Chamado de _DOCONTROLEVENTPROCEDURE(6056)
Chamado de EVENTS(1801)
Chamado de DOMESSAGELOOP(0)
Chamado de _ACTIVATEWINDOW(5717)
Chamado de MAIN_BUTTON_PEDIDOS_DE_VENDA_ ACTION(51)
Chamado de MAIN_FORM_ONINIT( 81)
Chamado de (b)MAIN(14)
Chamado de _PROCESSINITPROCEDURE(5876)
Chamado de _ACTIVATEWINDOW(5627)
Chamado de DOMETHOD(9003)
Chamado de MAIN(84)

A função para a nova apresentação e a seguinte:

aqui faço um ciclo de release das mesas.

Código: Selecionar todos

FUNCTION ACERTAPAG( NmrBotao, CtrlNmPag  ) 
LOCAL PscaoTab :=FormBuscaMesa.Tab_BuscaMesa.Value, TotalPaginas
LOCAL NmeBotao, PrmNmrBotao, UltNmrBotao, NrmMaxBt

SELECT('P_MESAS')
GO PscaoTab

MatrizMesas  :=SUBSTR(matLocalMesa[PscaoTab,1],1,3) + 'Mesas'
&MatrizMesas :=HB_ATokens( RTRIM(P_MESAS->PlanoMesas), '.', .F., .F. )

TotalPaginas:=INT(LEN(&MatrizMesas) / P_MESAS->NrMaxiMesa) + 1
PrmNmrBotao :=CtrlNmPag[PscaoTab,2] 
UltNmrBotao :=CtrlNmPag[PscaoTab,3]

SELECT('MOVVDDIA')
OrdSetFocus(1)
FOR NrmMaxBt :=CtrlNmPag[PscaoTab,2] TO CtrlNmPag[PscaoTab,3]
       NmeBotao :='M'+IF(MOVVDDIA->(DBSEEK(VAL( &MatrizMesas[NrmMaxBt]))),;
	                  IF(MOVVDDIA->MesaFecha==.f., HB_USUBSTR(matLocalMesa[PscaoTab,1],1,4)+'Ocupada',;
			     HB_USUBSTR(matLocalMesa[PscaoTab,1],1,4)+'Fechada'), HB_USUBSTR(matLocalMesa[PscaoTab,1],1,4)+'Livre') + &MatrizMesas[NrmMaxBt]
  	
   DoMethod(CATS_getFormFocus(), NmeBotao, 'Release')
     
NEXT NrmMaxBt
Após isso calculo o numero da 1ª e da ultima mesa a apresentar na respectiva página.

Código: Selecionar todos

DO CASE 
   CASE NmrBotao=='1P'  && 1ª Página
      PrmNmrBotao :=1
	  UltNmrBotao :=IF(LEN(&MatrizMesas)<=P_MESAS->NrMaxiMesa, LEN(&MatrizMesas), P_MESAS->NrMaxiMesa)
   CASE NmrBotao=='PA'   &&Página A nterior
      PrmNmrBotao :=(PrmNmrBotao-P_MESAS->NrMaxiMesa)+1
	  IF PrmNmrBotao<1
	     PrmNmrBotao :=1
		 UltNmrBotao :=IF(LEN(&MatrizMesas)<=P_MESAS->NrMaxiMesa, LEN(&MatrizMesas), P_MESAS->NrMaxiMesa)
	  ELSE 
	     UltNmrBotao :=IF(LEN(&MatrizMesas)<=(PrmNmrBotao+P_MESAS->NrMaxiMesa)-1, LEN(&MatrizMesas), (PrmNmrBotao+P_MESAS->NrMaxiMesa)-1)
	  ENDIF 
   CASE NmrBotao=='PS'   &&Página Seguinte
      UltNmrBotao++
	  IF UltNmrBotao>TotalPaginas*P_MESAS->NrMaxiMesa
	     PrmNmrBotao :=((TotalPaginas*P_MESAS->NrMaxiMesa)-P_MESAS->NrMaxiMesa)+1
	  ELSE 
	     PrmNmrBotao :=UltNmrBotao
	  ENDIF 
      UltNmrBotao :=IF(LEN(&MatrizMesas)<=(PrmNmrBotao+P_MESAS->NrMaxiMesa)-1, LEN(&MatrizMesas), (PrmNmrBotao+P_MESAS->NrMaxiMesa)-1)
   CASE NmrBotao=='UP'   &&Ultima Página 
      PrmNmrBotao :=((TotalPaginas*P_MESAS->NrMaxiMesa)-P_MESAS->NrMaxiMesa)+1
	  UltNmrBotao :=(TotalPaginas*P_MESAS->NrMaxiMesa)
ENDCASE


Em seguida atualizo a matriz que criei para guardar o 1º numero de mesa e o ultimo numero de mesa a ser usados no ciclo.

Código: Selecionar todos

ColBotao     :=0
LnBotao      :=0
IF ASCAN(CtrlNmPag, {|x|x[1]=PscaoTab})<>0
   CtrlNmPag[PscaoTab,2] :=PrmNmrBotao
   CtrlNmPag[PscaoTab,3] :=UltNmrBotao
ENDIF 
E no final faço o cliclo de apresentação dos botões com as novas mesas, mas é aqui que ele dá erro, dentro do DEFINE BUTTON.

Código: Selecionar todos

FOR numMesaApr :=PrmNmrBotao TO UltNmrBotao
    cTextFName := GetStartUpFolder()+"\DEFMESAS\" + SUBSTR(matLocalMesa[PscaoTab,1],1,1)+;
				  "BOT" + &MatrizMesas[numMesaApr] + ".TXT"

    SELECT('MOVVDDIA')
    OrdSetFocus(1)
					
    oNomeBotao :='M'+IF(MOVVDDIA->(DBSEEK(VAL( &MatrizMesas[numMesaApr]))),;
	                    IF(MOVVDDIA->MesaFecha==.f., HB_USUBSTR(matLocalMesa[PscaoTab,1],1,4)+'Ocupada',;
					       HB_USUBSTR(matLocalMesa[PscaoTab,1],1,4)+'Fechada'), HB_USUBSTR(matLocalMesa[PscaoTab,1],1,4)+'Livre')
    oPicture   :=oNomeBotao
	oNomeBotao +=&MatrizMesas[numMesaApr]
	
	oPicture   :=STRTRAN(oPicture, "Sala", "esa")  
	oPicture   :=STRTRAN(oPicture, 'Espl', 'esa') 
	oPicture   :=STRTRAN(oPicture, 'Balc', 'esa') 
	oPicture   :=STRTRAN(oPicture, 'IFoo', 'esaIF') + "_28x28.PNG"
					
	matMesaBotao := HB_ATokens( MEMOREAD( cTextFName ), CRLF )
				
   DEFINE BUTTON &oNomeBotao
        ROW    VAL(matMesaBotao[1]) + LnBotao 
        COL    VAL(matMesaBotao[2]) + ColBotao
        WIDTH  VAL(matMesaBotao[3])  
        HEIGHT VAL(matMesaBotao[4]) 
        ACTION {|| numMesaVD :=ClickOnButton( numMesaVD, CATS_getControlFocus(), this.focusedcontrol, CATS_getFormFocus() ),;
		           ThisWindow.Release, DoMethod('Pedido_de_Vendas', 'Grid_Pedidos', 'SetFocus') }
		CAPTION "&"+&(matMesaBotao[6])   
        FONTNAME "Arial"
        FONTSIZE 9
        TOOLTIP matMesaBotao[7]
        FONTBOLD .T.						
        VISIBLE .T.
        TRANSPARENT .T.
        MULTILINE .F.
        PICTURE matMesaBotao[10] + oPicture 
        PICTALIGNMENT TOP 
        ONGOTFOCUS Nil  
        ONLOSTFOCUS Nil    						
    END BUTTON
       
    ColBotao +=VAL(matMesaBotao[3]) + 5
    IF ColBotao>=690 - ( VAL(matMesaBotao[3]) + VAL(matMesaBotao[2]) ) 
       ColBotao :=0  
       LnBotao  +=VAL(matMesaBotao[4])
    ENDIF
	   
    IF LnBotao>=320 - ( VAL(matMesaBotao[1]) + VAL(matMesaBotao[4]) )
       LnBotao :=0
       ColBotao:=0
    ENDIF
 	
NEXT numMesaApr	
SELECT('P_MESAS') 		   
 
RETURN( NmrBotao, CtrlNmPag ) 
Será que não me deixa criar os botões dentro de uma função chamada do Tabelador ?
Editado pela última vez por Itamar M. Lins Jr. em 25 Mai 2023 19:03, em um total de 1 vez.
Razão: O presente tópico foi movido da seção Harbour, uma vez que seu conteúdo não tem relação com os objetivos daquela seção, onde só podem constar dúvidas técnicas de programação diretamente relacionadas com o [x]Harbour.
ivanil
Usuário Nível 3
Usuário Nível 3
Mensagens: 166
Registrado em: 11 Set 2004 15:13
Localização: Florianópolis/SC

Duvida sobre um o processamento de BUTTON

Mensagem por ivanil »

Se me permite opinar algumas coisas;

Seu uso de memória não é normal, pode estar ligado em como você usa os recursos;

ao que me parece, você usa a leitura de um arquivo texto; ou seja, constantemente lendo o disco, e como estamos falando de recursos chamados por eventos, isso pode estar sendo disparado, mas que o necessário;

Você mostrou os erros com as linhas, mas ao adicionar aqui as linhas ficaram diferentes por conta do recorte.

Você pode dar release nos objetos e recriá-los, mas seria mais eficiente usar as propriedades visible/disable/Caption/picture sem necessariamente ter que recriar tudo a cada repaginação.
Todos os objetos, inclusive a window, tem uma propriedade "cargo" que você pode fazer maravilhas com ela sem precisar criar macro ou variáveis desnecessárias.



Sem entrar no mérito no arquivo texto agora ...
01 FOR numMesaApr :=PrmNmrBotao TO UltNmrBotao
02 cTextFName := GetStartUpFolder()+"\DEFMESAS\" + SUBSTR(matLocalMesa[PscaoTab,1],1,1)+;
03 "BOT" + &MatrizMesas[numMesaApr] + ".TXT"

seria mais eficiente:
Local cPath := GetStartUpFolder()+"\DEFMESAS"
/*
...
*/
01 FOR numMesaApr :=PrmNmrBotao TO UltNmrBotao
02 cTextFName := cPath + SUBSTR(matLocalMesa[PscaoTab,1],1,1)+;
03 "BOT" + &MatrizMesas[numMesaApr] + ".TXT"

Quando for criar um objeto fora da estrutura de uma janela, você necessariamente tem que indicar a Janela.

Function AlgumaCoisa(cForm)
/*
...
*/

Declare window &(cForm)
21 DEFINE BUTTON &oNomeBotao
PARENT &cForm
22 ROW VAL(matMesaBotao[1]) + LnBotao
23 COL VAL(matMesaBotao[2]) + ColBotao
24 WIDTH VAL(matMesaBotao[3])

O uso de THIS/THISWINDOW após o retorno de uma função dentro do bloco pode causar bug difícil de localizar; opte por nome do form;

26 ACTION {|| numMesaVD :=ClickOnButton( numMesaVD, CATS_getControlFocus(), this.focusedcontrol, CATS_getFormFocus() ),;
27 ThisWindow.Release, DoMethod('Pedido_de_Vendas', 'Grid_Pedidos', 'SetFocus') }

É melhor passar o nome do objeto, você tem acesso direto a todas as propriedades.
26 ACTION {|cName| cName:=this.name, numMesaVD :=ClickOnButton( numMesaVD, cName, cForm ), &(cForm).Release }

Essas funções podem te dar dor de cabeça.
CATS_getControlFocus()
CATS_getFormFocus()

Esse comando talvez fique melhor se chamado no OnRelease do form =: DoMethod('Pedido_de_Vendas', 'Grid_Pedidos', 'SetFocus')

Se me permite dar mais uma opinião é na forma como lida com o DBF, elimine o uso de "select area", você já usa os parcialmente no código os aliases para os campos, passe a usar nas chamadas de funções também, seu código ficará mais legível para outros que derem manutenção no seu sistema.
Mesas->(Dbgoto(n))
Mesas->(Dbgotop())
Mesas->(OrdSetFocus(n))
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

Não tem nada equivalente a this ?
Tipo...

Código: Selecionar todos

oThis := GetCurrentControl() // suposição, não sei se existe
? oThis:Name
? oThis:Cargo
No VB, por exemplo, tem o ME, talvez equivalente ao SELF do Harbour

Código: Selecionar todos

? me.name
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/
ivanil
Usuário Nível 3
Usuário Nível 3
Mensagens: 166
Registrado em: 11 Set 2004 15:13
Localização: Florianópolis/SC

Duvida sobre um o processamento de BUTTON

Mensagem por ivanil »

Olá Quintas,

Sim, há sim. Veja abaixo:

26 ACTION {
|cName|
cName := this.name;
numMesaVD := ClickOnButton(numMesaVD, cName, cForm);
&(cForm).Release;
}

Mencionei ao colega que é melhor evitar usar o "this/thiwwindow" após o retorno da função. Isso ocorre porque, dependendo da função chamada, ela pode mudar o foco e disparar outros eventos, fazendo com que o "this/thiwwindow" não seja mais o mesmo. No exemplo acima, o nome do controle é armazenado em uma variável local, então seu valor é preservado, independentemente do que a função chamada faça. Dessa forma, é possível utilizar qualquer propriedade dentro do bloco:

26 ACTION {
|cName|
cName := this.name;
&(cForm).&cName.Enabled := FALSE;
numMesaVD := ClickOnButton(numMesaVD, cName, cForm);
&(cForm).&cName.Enabled := TRUE;
}

No entanto, de qualquer forma, eu desencorajo o uso de blocos na criação do controle, pois isso torna o código muito complexo e, basicamente, não há ganho. Criar uma "static function" para cada evento tem demonstrado maior legibilidade. Importante ressaltar que tudo isso depende da forma como o programador estrutura as coisas. Enfim, é difícil opinar sobre qualquer coisa sem ter uma visibilidade do todo.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Duvida sobre um o processamento de BUTTON

Mensagem por JoséQuintas »

ivanil escreveu:eu desencorajo o uso de blocos na criação do controle, pois isso torna o código muito complexo
Por isso a pergunta.
Mas esse this.name é meio falso, não tem outro?

Código: Selecionar todos

ACTION MyClick()
...
STATIC FUNCTION MyClick()

cName := This.Name
Isso acima já não funcionaria, porque o this é traduzido pelo pré-processador, e não vai ter o mesmo efeito.
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