HMG 3.4.4

HMG Unicode versions 3.1.x related

Moderator: Rathinagiri

martingz
Posts: 244
Joined: Wed Nov 18, 2009 11:14 pm
Location: Mexico
Has thanked: 12 times
Been thanked: 9 times

Re: HMG 3.4.4

Post by martingz » Mon Jul 30, 2018 7:28 pm

Mario te preguntaba eso por que me intrigo esto

Called from _DOCONTROLEVENTPROCEDURE(6056)
Called from EVENTS(1763)
Called from DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(5717)
Called from ALTA_VENTA(607)
Called from (b)PRESU(1178)
Called from _DOCONTROLEVENTPROCEDURE(6056)
Called from EVENTS(1801)
Called from DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(5717)
Called from ALTA_VENTA(607)
Called from (b)PRESU(1178)

Called from _DOCONTROLEVENTPROCEDURE(6056)
Called from EVENTS(1801)
Called from DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(5717)
Called from ALTA_VENTA(607)
Called from (b)PRESU(1178)

Called from _DOCONTROLEVENTPROCEDURE(6056)
Called from EVENTS(1801)
Called from DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(5717)
Called from ALTA_VENTA(607)
Called from (b)ACEPTAR_CLIENTE(518)
Called from _DOCONTROLEVENTPROCEDURE(6056)
Called from EVENTS(828)
Called from DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(5717)
Called from ALTA_VENTA(607)
Called from (b)PRESU(1178)
Called from _DOCONTROLEVENTPROCEDURE(6056)
Called from EVENTS(1801)
Called from DOMESSAGELOOP(0)
Called from _ACTIVATEWINDOW(5717)
Called from ALTA_VENTA(607)

como puedes ver se repite demasiado ALTA_VENTA(607), como si estuvieras llamando muchas veces a esta funcion y no se liberara, estoy revisando tu codigo, pero eso me parecio extraño

User avatar
SALINETAS24
Posts: 171
Joined: Tue Feb 27, 2018 3:06 am
DBs Used: DBF
Has thanked: 2 times
Been thanked: 3 times

Post by SALINETAS24 » Tue Jul 31, 2018 4:51 pm

Hola, como ya te comente tienes un problema de recursividad.

Un principio del CLIPPER y que HARBOUR ha heredado es que para salir de una función o procedimiento se tiene que hacer mediente un RETURN, en caso contrario eso quedará pendiente en la memoria del ordenador a la espera de recibir el RETURN. Como puedes ver en tu programa, cuando detectas un error, presentas un mensaje y le das el foco a un textbox..., y vuelves a empezar, quedando el RETURN pendiente de ejecutar.
Cuantos más errores tengas más RETURN's quedarán ocupando memoria y más rápido "cascara" tu programa.
Por cierto he detectado el mismo problema en la funcion "Actualiza_Venta()", asignas el FOCO antes del Return. Como me dijo alguien por estos foros, creo que tienes que replantearte el programa, no tiene un flujo correcto.

Yo todavía no trabajo con IDE no me hecho a ello (soy de la vieja escuela), pero te pongo seguidamente lo que sería una manera correcta de trabajar en clipper/harbour.

Ah, y recuerda que aunque el programa funcione no quiere decir que sea correcto.

Code: Select all

/*
 * HMG - Harbour Win32 GUI library Demo
 *
 * Copyright 2002 Roberto Lopez <mail.box.hmg@gmail.com>
 * http://www.hmgforum.com//
*/

#include "hmg.ch"

Function Main

	DEFINE WINDOW Form_122 ;
		AT 0,0 ;
		WIDTH 640 HEIGHT 480 ;
		TITLE 'HMG Demo' ;
		MAIN 

		@ 10,10 TEXTBOX Text_1 ;
			VALUE 123 ;
			TOOLTIP 'Numeric TextBox' ;
			NUMERIC ;
			MAXLENGTH 5 ;
			RIGHTALIGN ;
			ON LOSTFOCUS IF(Aceptar_Venta(),Nil,This.SetFocus)  
			//-------------------------------------------------------------------
			// Cuando cambie LOSTFOCUS Comprobará si el valor es correcto
			// la función devolverá .T. si todo va bien, y .F. si está mal.
			// En este ultimo caso, se foco no cambiará.
		
		@ 40,10 TEXTBOX Text_2 ;
			VALUE 123 ;
			TOOLTIP 'Numeric TextBox' ;
			NUMERIC ;
			MAXLENGTH 5 ;
			RIGHTALIGN ;
			ON LOSTFOCUS IF(Aceptar_Venta(),Nil,This.SetFocus)
		

		DEFINE BUTTON C
			ROW	250
			COL	100
			WIDTH	160
			CAPTION	'Set Text_2 ReadOnly .T.'
			ACTION	Form_1.Text_2.ReadOnly := .T.
		END BUTTON

		DEFINE BUTTON D
			ROW	250
			COL	290
			WIDTH	160
			CAPTION	'Set Text_2 ReadOnly .F.'
			ACTION	Form_1.Text_2.ReadOnly := .F.
		END BUTTON


	END WINDOW

	Form_1.Center

	Form_1.Activate

Return Nil






*----------------------
Static Procedure Aceptar_Venta
*----------------------
// -> Utilizamos una variable tipo Swp, tiene un valor lógico.
// -> si en .T. es que todo fue bien, y si cambial a .F. es que algo fallo.

LOCAL lOk:=.T.     //--> Empezamos con cierto .t.

	If Empty(Form_122.Text_1.Value)   
		MsgInfo("Disculpe !!" + chr(10) + ;
		"El codigo de articulo ingresado es inválido","Atención")
		lOK:=.F.   //--> como es incorrecto la pasamos a falso .F.
	Endif
	
	IF lOk .AND. Empty(Form_122.Text_2.Value) //-> Añadimos a la condición "lOK" así solo se ejecutará si no hay error
		MsgInfo("Disculpe !!" + chr(10) + ;
		"El nombre de articulo codigo ingresado es inválido","Atención")
		lOK:=.F.  //--> como es incorrecto la pasamos a falso .F.
	ENDIF
	
/* -> y asi con el resto de condiciones	
	IF lOk .AND. Empty(Form_122.Text_3,4,5,6,.Value) //-> Añadimos a la condición "lOK" así solo se ejecutará si no hay error
		MsgInfo("Disculpe !!" + chr(10) + ;
		"El nombre de articulo codigo ingresado es inválido","Atención")
		lOK:=.F.  //--> como es incorrecto la pasamos a falso .F.
	ENDIF
*/

	// --> Cuando llega aquí solo se ejecutará si esta todo correcto ".T."
	IF lOk
		Do Case
			Case Terminal = 3
				Select Ventas3
			Case Terminal = 2
				Select Ventas2
			Case Terminal = 1
				Select Ventas
		ENDCASE	
		If c_Modo = 1
			Append Blank // Ventas->(DbAppend())
		Endif 

		Replace Tipo With c_TipoFac
		Replace Compro With c_Compro
		Replace Numero With c_Numero
		Replace Fecha With Date()
		Replace Hora With c_Hora
		Replace Codigo With Form_122.Text_1.Value
		Replace Familia With Arti->Familia
		Replace Rubro With Arti->Rubro
		Replace Articulo With Form_122.Text_2.Value
		Replace Cantidad With Form_122.Text_3.Value
		Replace Tiva With Arti->Tiva
		Replace Impint With Arti->Impint
		Replace Descuento With Form_122.Text_4.Value
		If c_TipoFac = "A"	
			Replace Unitario With Form_122.Text_5.Value / (1 + (Tiva/100))
		Else
			Replace Unitario With Form_122.Text_5.Value
		Endif
		Replace Importe With Unitario * Cantidad

		Thiswindow.Release (****** Aqui ******)

		Form_120.Button_2.Enabled := .T.
		Form_120.Button_3.Enabled := .T.
		Form_120.Button_4.Enabled := .T.
		Form_120.Button_5.Enabled := .T.
		ON KEY F4 OF Form_120 ACTION (Modi_Venta())
		ON KEY F5 OF Form_120 ACTION (Borra_Venta())
		ON KEY F6 OF Form_120 ACTION (Pago_Venta())
		ON KEY F8 OF FORM_120 ACTION nil

		//--------------------------------------------------
		// --> ¡¡OJO !! EN EL PROCEDIMIENTO "ACTULIZA_VENTA"
		// --> TIENES EL MISMO PROBLEMA ASIGNAS EL FOCO "Form_120.Browse_1.Setfocus" antes del RETURN 
		//--------------------------------------------------
		Actualiza_Venta()  

	ENDIF
	
Return lOk  // --> DEVUELVE COMO TERMINO LA OPERACIÓN

*-


martingz
Posts: 244
Joined: Wed Nov 18, 2009 11:14 pm
Location: Mexico
Has thanked: 12 times
Been thanked: 9 times

Post by martingz » Tue Jul 31, 2018 5:08 pm

Salinetas no creo que sea problema de asignar el foco antes del return, eso lo hago yo para regresar al control que me interesa que tenga el foco, despues de desplegar el mensaje deseado, esto me sirve para montar un valid o para asegurarme que el usuario siga un determinado orden en los controles, y como le comentaba a Mario, tenemos funcionando estos programas en mas de 50 equipos con atencion al publico de 8 de la mañana a 3 de la tarde sin que aparezca este tipo de problemas, mas si estoy de acuerdo contigo en que parece un problema de recursividad, Mario estoy un poco falto de tiempo para seguir revisando el programa cada 5 dias pierdo dos en el proceso de facturacion y timbrado de mis xml, pero terminando esto sigo mirando tu codigo.

saludos

Mario Mansilla
Posts: 244
Joined: Wed Aug 13, 2008 2:35 pm
Location: Córdoba - Argentina
Been thanked: 2 times

Post by Mario Mansilla » Wed Aug 01, 2018 12:07 pm

Hola Amigos :
muchas gracias por su colaboracion .
Asi es Salinetas , como te explica Martin lo uso de esa manera para dejar el foco en el control donde se debe reingresar el dato invalido .
Lo unico que es a prueba y error , es realizar una correccion y probar a ciegas para ver si sucede el error , no conozco una funcion de harbour que me permita ver el estado del stack para verificar donde se produce el problema .
Saludos
Mario Mansilla

Hello friends :
Thank you very much for your help .
This is Salinetas, as Martin explains, I use it that way to leave the focus on the control where the invalid data must be re-entered.
The only thing that is trial and error, is to make a correction and blind test to see if the error happens, I do not know a function of Harbour that allows me to see the status of the stack to verify where the problem occurs.
regards
Mario Mansilla

Post Reply