Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-01-2006
Seba.F1 Seba.F1 is offline
Registrado
 
Registrado: nov 2004
Ubicación: ER - Argentina
Posts: 7
Poder: 0
Seba.F1 Va por buen camino
Angry Thread bendito thread...se me pierde la ventana

Hola gente como andan? llevo mas de 3 horas buscando en los foros de club delphi e internet algo que me ayude con mi problema pero no encuentro nada, si no les molesta a los que mas saben por favor denme una mano, o un pie o algo por favor!!!!!!!! estoy por volverme loco.

EL PROBLEMA
He desarrollado una aplicación que entre muchas cosas, lee datos de una balanza electrónica que pesa camiones (cuando comence con el desarrollo ya estaba). La cuestión es que esta balanza usa un ejecutable en DOS (si Disk Operating Sistem de Micro...), cuando lo ejecuto con cierta sintaxis me devuelve el valor del peso en un archivo .txt. Hasta aca todo bien. Por cuestiones de tiempo (demoras del archivito, mostrar los datos, etc) tuve que implementar un thread para que la aplicación pueda realizar otras tareas mientras pesa los camiones, y ejecuto dentro del thread el programita de la balanza, luego leo el archivo .txt y muestro el numerito en LA aplicación, cuando deja de pesar, se termina el thread, imprime el ticket y cuando cierro la ventana de la balanza, puuuuuuuuffffff,!"·$·$|@#~&·$&|@#~%&|@#~€|34% me tira el siguiente error (obviamente le meti un par de try except... y muestra un lindo mensajito).

Error Win32 Code1400
El identificador de la ventana no es válido

todo bien hasta que se quiere volver a abrir la ventana de la balanza.

Ya existe un componente con el nombre F_Balanza.

y no me lo deja crear, y cuando cierro la aplicaciópn paaaaaaassfff

violacion de acceso a la direccion 7c928fea en el módulo ntdll.dll

aca va el codigo de mi thread, junto con el que dispara el ejecutable de la balanza.

por favor les pido que si alguien me pude decir donde le estoy errando, porque ya no veo nada.


Código Delphi [-]
function T_Lectura_Balanza.Ejecutar(const AppName, Params:String):THandle;
var
   ProcInfo:TProcessInformation;
   Info:TStartupInfo;
begin
     FillChar(Info,SizeOf(Info),0);
     Info.cb:=SizeOf(Info);
     Info.dwFlags:=STARTF_USESHOWWINDOW;
     info.wShowWindow:=SW_HIDE;
     if not CreateProcess(nil, pchar(AppName+' '+Params),nil,nil,False,0,nil,nil,Info,ProcInfo) then
        raise Exception.Create('No se puede iniciar la lectura de la balanza.');
     Result:=ProcInfo.hProcess;
end;
procedure T_Lectura_Balanza.Esperar(H:THandle);
begin
     while WaitForSingleObject(H,100)=WAIT_TIMEOUT do
           begin
                Application.ProcessMessages;
                if Application.Terminated then
                   Break;
                if F_Balanza.Terminar then
                   Break;
           end;
end;
 
 
procedure T_Lectura_Balanza.Execute;
begin      Linea_Comando:=MD_Config.IBQ_CONFIGLINEA_COMANDO_BALANZA.AsString;
     repeat
           try
              Esperar(Ejecutar(Linea_Comando,''));
              Archivo_Peso:=F_Principal.Dir+'Peso';
              F_Balanza.Memo_Peso.Lines.LoadFromFile(Archivo_Peso);
              Archivo_Peso:=F_Balanza.Memo_Peso.Lines[0];
              if Archivo_Peso='E' then
                 begin
                      F_Balanza.Img_Error.Visible:=True;
                 end
              else
                  begin
                       F_Balanza.Img_Error.Visible:=False;
                       Peso:=Copy(Archivo_Peso,2,(Length(Archivo_Peso)-1));
                       try
                          Long_:=StrToFloat(Peso);
                       except
                             Long_:=0;
                       end;
                       if Long_=0 then
                          F_Balanza.Img_Cero.Visible:=True
                       else
                           F_Balanza.Img_Cero.Visible:=False;
                       F_Balanza.Kg:=Long_;
                       Decodificar_Numero(Long_,CM,DM,UM,C,D,U);
                       Mostrar(CM,DM,UM,C,D,U);
                  end;
          except
                 Decodificar_Numero(0,CM,DM,UM,C,D,U);
                 Mostrar(CM,DM,UM,C,D,U);
                 F_Balanza.Img_Cero.Visible:=True;
           end;
     until F_Balanza.Terminar;
end;

desde ya muchas gracias.
Responder Con Cita
  #2  
Antiguo 27-01-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No entiendo demasiado de hilos pero siento que tu código está muy enredado.

¿Para qué pones al WaitForSingleObject dentro de un while? En principio, no se pasará de esa línea hasta que no se cumpla el tiempo especificado y si no quieres que termine después de ese tiempo pones INFINITE como timeout y sólo terminará hasta que se cumpla la condición (que termine la otra aplicación)

Y así mismo, no entiendo para qué usas un repeat en el método execute. Si el WaitForSingleObject esta en INFINITE, el método Execute no terminará hasta que no acabe la otra aplicación.

Por otra parte no estoy seguro de si realmente es necesario usar un thread aparte. Cuando uses la balanza podrías poner algo como:

Código Delphi [-]
EjecutarBalanza;

DeleteFile('archivo.txt');

repeat
  Application.ProcessMessages;
until FileExists('balanza.txt') or Application.Terminated;

ShowMessage('Ya terminó');

// Saludos
Responder Con Cita
  #3  
Antiguo 27-01-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Solo un par de detalles. No deberias de utilizar componentes de un formulario desde un Thread sin usar el metodo "Synchronize".

Segundo, como haces para cerrar y mostrar la ventana F_Balanza porque puede que el problema este ahi y no en el thread.

Por ultimo la solucion de Roman me parece sencilla y deberia de funcionar de maravilla. Aunque al escribirlo CREO que no lo hizo en el orden correcto, deberia de ser:

Código:
DeleteFile('balanza.txt');
EjecutarBalanza;
repeat
  Application.ProcessMessages;
until FileExists('balanza.txt') or Application.Terminated;
ShowMessage('Ya terminó');
Si me equivoco, perdoname ...
Responder Con Cita
  #4  
Antiguo 27-01-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por seoane
CREO que no lo hizo en el orden correcto, deberia de ser:
¡Claro!, Tienes toda la razón. Probé el resto de la solución pero no tenía una de esas balanzas a la mano . Gracias por la aclaración.

// Saludos
Responder Con Cita
  #5  
Antiguo 28-01-2006
Seba.F1 Seba.F1 is offline
Registrado
 
Registrado: nov 2004
Ubicación: ER - Argentina
Posts: 7
Poder: 0
Seba.F1 Va por buen camino
aclaración sobre la consulta

No entiendo demasiado de hilos pero siento que tu código está muy enredado.

hola roman como andás agradezco mucho la respuesta.
te aclaro algunas cositas porque no fui muy claro.

¿Para qué pones al WaitForSingleObject dentro de un while? En principio, no se pasará de esa línea hasta que no se cumpla el tiempo especificado y si no quieres que termine después de ese tiempo pones INFINITE como timeout y sólo terminará hasta que se cumpla la condición (que termine la otra aplicación)

el WaitForSingleObject lo puse para que espere un ratito y se fije en la cola de mensajes a ver cuando termina la ejecución de la aplicacion cuando encuentra la finalización sale del while.

Y así mismo, no entiendo para qué usas un repeat en el método execute. Si el WaitForSingleObject esta en INFINITE, el método Execute no terminará hasta que no acabe la otra aplicación.

el repeat lo utilizo como pooling para ejecutar las otras tareas, hasta que el formulario F_Balanza dice que termine, ya que los camiones están durante algun tiempo en la balanza y se les agrega o saca granos para llegar a los kg exactos con los que pueden usar las rutas.

Por otra parte no estoy seguro de si realmente es necesario usar un thread aparte. Cuando uses la balanza podrías poner algo como:

Código Delphi [-]
EjecutarBalanza;
 
DeleteFile('archivo.txt');
 
repeat
Application.ProcessMessages;
until FileExists('balanza.txt') or Application.Terminated;
 
ShowMessage('Ya terminó');

esta version la estoy probando.
si se les ocurre algo nuevo lo agradecere mucho.
un saludo a todos.

// Saludos
Responder Con Cita
  #6  
Antiguo 02-02-2006
Seba.F1 Seba.F1 is offline
Registrado
 
Registrado: nov 2004
Ubicación: ER - Argentina
Posts: 7
Poder: 0
Seba.F1 Va por buen camino
Ya lo solucioné

Gracias chicos por la ayuda, la solucion la encontre en una combinación de las soluciones planteadas, por un lado roman utilice el borrar y verificar la existencia del archivo delpeso, con eso se me acabaron los problemas con la lectura del archivo, y por otro lado con el infinite en el waitforsingleobject, con eso anduvo barbaro.
por otro lado gracias seoane por el dato del syncronize no sabia que lo tenia que usar es mas el tthread te lo sugiere cuando lo creas, que tonto de mi parte.

bueno chicos nuevamente gracias por la ayuda y solucion de mi problema. saludos seba.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Problemas MDI cerrar ventana rafadrover Varios 3 28-01-2006 14:30:44
Cerrar componente con ventana modal elcigarra OOP 7 12-10-2005 14:17:53
En mi aplicacion MDI quiero crear una ventana hija desde otra ventana hija Durbed Varios 8 05-07-2005 12:51:54
Llamada de procedimientos wallesis OOP 19 27-01-2004 19:39:15


La franja horaria es GMT +2. Ahora son las 20:45:55.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi