PDA

Ver la Versión Completa : ¿¿Aplicacion no GUI. que no se cierre sola???


JXJ
20-05-2007, 03:15:53
Hola. estoy viendo como hacer una aplicacion, que no
muestre una interfaz grafica. pensando en hacer un
para un servidor FTP , para la pc donde vivo poder subir
mis archivos de trabajo..

tengo este esqueleto basico,


program miprograma;
uses
SysUtils;

//Inicia el programa
begin

end.


Entonces, les pregunto,
¿ como puedo hacer que
mi programa no se cierre, o finalize hasta que se le ordene
finalizar.?

el programa no se comparta como si fuese
una aplicacion delphi normal
esperando algo a que explicitamente se le ordene cerrarse.

quiero que el ftp se quede escuchando en un puerto
y si recibe el comando de cerrar, finalize la aplicación.

gracias por su atención

seoane
20-05-2007, 03:29:01
:confused: ¿Que tal con un bucle?

program miprograma;
uses
SysUtils;

//Inicia el programa
begin
while TRUE do
begin

end;
end.


Aunque puede que necesitemos que la CPU respire:

program miprograma;
uses
SysUtils;

//Inicia el programa
begin
while TRUE do
begin


Sleep(10);
end;
end.

JXJ
20-05-2007, 05:28:11
Hola
Seoane
gracias por tu atención

este... como que no entiendo bien, como funciona eso de
Mientras sea verdad ¿¿que ???
Esta criptico para mi.


while TRUE do //True o verdad que ??:S:S:S
begin


Sleep(10);//<- Este si se que detiene en milisegundos.
end;



//--Asi probe el codigo y funciona.


{$SetPEFlags 1} //<-Directiva reduce tamaño del exe, solo disponible desde delphi 2005 hasta D2007 win32
program GServerc;

uses
SysUtils, Dialogs;

var
contador: Integer;
Cerrar : Boolean;

//Inicia el programa
begin
Contador := 1;
Cerrar := False;
//Bucle que mantendrá el programa vivo
while True do
begin
Sleep(10);//<- Descansamos el CPU :D
if Cerrar = False then
begin
Contador := Contador +1;
if contador = 100 then
begin
Cerrar := True;
showmessage(intToStr(Contador));
end

end
else
//Si deseamos hacer algo al salir ponerlo aquí
Break;
end;


end.

MAXIUM
20-05-2007, 05:44:36
en mis tiempos de Turbo Pascal usaba un keypressed con un
While, lo que resultaba que al presionar una tecla o una determinada tecla (ESC) finalizaba la instrucción.

Alternativas sencillas: usar un readkey o un comando SHELL (pause) al final.

if Cerrar = False then

Cerra es un boleano entonces:

if not Cerrar then

JXJ
20-05-2007, 05:51:04
MAXIUM

voy a probar lo que mencionas.

seoane
20-05-2007, 10:09:33
Bien, si un bucle no es suficiente vamos a hacer las cosas a lo grande. Primero necesitamos crear una función para manejar las señales que son enviadas a la aplicación. Una como esta:

function HandlerRoutine(dwCtrlType: DWORD): BOOL; stdcall;
begin
Result:= TRUE;
case dwCtrlType of
CTRL_C_EVENT:
Terminar:= TRUE;
CTRL_CLOSE_EVENT:
Terminar:= TRUE;
CTRL_LOGOFF_EVENT:
Terminar:= TRUE;
CTRL_SHUTDOWN_EVENT:
Terminar:= TRUE;
else
Result:= FALSE;
end;
end;

Aquí yo pongo una variable global (Terminar) a false como respuesta a todos los eventos. Tu puedes manejar esos eventos como prefieras, solo tienes que tener en cuenta que si la función devuelve FALSE la señal se pasa al siguiente manejador.

Ahora que ya manejamos los eventos Ctrl+C, Close, Logoff y Shutdown, no estaría mal disponer de un bucle de mensajes en nuestra aplicación. Si vas a usar algún timer, o algún componente que maneje internamente mensajes, este bucle sera imprescindible. Lo primero vamos a crear una función similar al famoso "Application.ProcessMessages", algo así:

procedure ProcessMessages;
var
Msg: TMsg;
begin
while PeekMessage(Msg,0,0,0,PM_REMOVE) do
begin
if Msg.Message = WM_QUIT then
begin
Terminar:= TRUE;
break;
end else
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;


Ahora solo nos falta encajar todo esto en nuestra aplicacion la cosa quedaria mas o menos asi:

program Ejemplo;

{$APPTYPE CONSOLE}

uses Windows, Messages, SysUtils;

var
Terminar: Boolean;

procedure ProcessMessages;
var
Msg: TMsg;
begin
while PeekMessage(Msg,0,0,0,PM_REMOVE) do
begin
if Msg.Message = WM_QUIT then
begin
Terminar:= TRUE;
break;
end else
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;

function HandlerRoutine(dwCtrlType: DWORD): BOOL; stdcall;
begin
Result:= TRUE;
case dwCtrlType of
CTRL_C_EVENT:
Terminar:= TRUE;
CTRL_CLOSE_EVENT:
Terminar:= TRUE;
CTRL_LOGOFF_EVENT:
Terminar:= TRUE;
CTRL_SHUTDOWN_EVENT:
Terminar:= TRUE;
else
Result:= FALSE;
end;
end;

begin
Terminar:= FALSE;
if SetConsoleCtrlHandler(@HandlerRoutine,TRUE) then
while not Terminar do
begin
// Aqui haz lo que quieras

ProcessMessages;
if not Terminar then
Sleep(10);
end;
end.


Donde pone "Aquí haz lo que quieras" coloca tu código, solo recuerda, que si vas a colocar un bucle dentro de tu código, deberás tener en cuenta la variable Terminar y llamar de vez en cuando a la función "ProcessMessages" para vaciar la cola de mensajes.

Por cierto, para cerrar la aplicación puedes usar Ctrl+C o la X de la ventana con la consola, da igual, la aplicación se cerrara limpiamente poniendo la variable Terminar a true y saliendo del bucle.

JXJ
20-05-2007, 22:08:14
Muy interesante, gracias Seoane

dec
20-05-2007, 22:11:40
Hola,

Me sumo a lo dicho por JXJ, Seoane, muy interesante. Muchas gracias. :)

JXJ
10-07-2008, 19:43:42
una dudas mas

¿para cerrarlo, via codigo, digamos con sin ser una aplicacion tipo cosola?



program Ejemplo;


uses Windows, Messages, SysUtils;

var
Terminar: Boolean;

procedure ProcessMessages;
var
Msg: TMsg;
begin
while PeekMessage(Msg,0,0,0,PM_REMOVE) do
begin
if Msg.Message = WM_QUIT then
begin
Terminar:= TRUE;
break;
end else
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;

function HandlerRoutine(dwCtrlType: DWORD): BOOL; stdcall;
begin
Result:= TRUE;
case dwCtrlType of
CTRL_C_EVENT:
Terminar:= TRUE;
CTRL_CLOSE_EVENT:
Terminar:= TRUE;
CTRL_LOGOFF_EVENT:
Terminar:= TRUE;
CTRL_SHUTDOWN_EVENT:
Terminar:= TRUE;
else
Result:= FALSE;
end;
end;

begin
Terminar:= FALSE;
if SetConsoleCtrlHandler(@HandlerRoutine,TRUE) then
while not Terminar do
begin
// Aqui haz lo que quieras


ProcessMessages;
if not Terminar then
Sleep(10);
end;
end.



ya me perdi. en esto :S

gracias..

seoane
10-07-2008, 22:02:51
¿para cerrarlo, via codigo, digamos con sin ser una aplicacion tipo cosola?


Lo adecuado, si no quieres una aplicación de consola, es crear una ventana (aunque permanezca oculta) y utilizar su bucle de mensajes. Cuando quieras cerrar la aplicación solo tendrás que mandar el mensaje WM_CLOSE. Por otro lado si tu aplicación no es de consola, por que no creas una aplicación normal de delphi y ocultas el formulario principal :confused:

JXJ
10-07-2008, 22:36:38
por creerme bien picudo..

estoy re-revisando tu servidor web pico..
y en creer que puedo hacer un servidor tcpip. con indy. usando el dpr.
y darle la opcion de desconectarse y cerrarse a si mismo usando un comando
desde el cliente..