PDA

Ver la Versión Completa : Algo superior a StayOnTop?


FDB
09-02-2005, 15:44:25
Hola.

Antes de nada felicitaros a los que haceis posible esto, puesto que aunque llevo bastante tiempo entrando en esta pagina, hasta dia de hoy no he necesitado de vuestra ayuda de forma mas especifica puesto que todo lo encontrado en esta inmensa base de datos, por todo ello gracias.

Ahora paso a comentaros un pequeño problemilla por así llamarlo.

Estoy intentando hacer un programa, el cual "bloquee" el windows, por asi decirlo, veamos... consiste en dejar una pantalla que hasta que no introduzcas un password dicha pantalla no se iria y ya recuperarias el windows.

He probado a crear un form, maximizado, a pantalla completa y stayOnTop. Y al crearlo desactivo la posibilidad de usar Ctrl-alt-supr, ctrl-esc, alt-F4, alt-tab, etc..
Por lo que no puedes cerrar el form hasta que no introduzcas la contraseña y demas.

El problema viene cuando por ejemplo te salta una ventanita de las que muestra el messenger cuando entra alguien y pinchas, puedes escribirle a esa persona...

Lo que me gustaria saber es como hacer para que esté el form por encima de todo, o bueno.. si vosotros veis que así es una forma que no es "buena" y sabeis alguna mejor pues estoy abierto a cualquier sugerencia.

Muchas gracias.

roman
09-02-2005, 16:40:20
Personalmente he encontrado de mucha utilidad para estos fines el uso de objetos Desktop. Cuando se incia Windows y aparece la ventana de usuario y contraseña, esta ventana está montada en un Desktop distinto del usual donde aparecen el resto de ventanas de manera que no existe posibilidad alguna de que surja una ventana inesperada. De manera similar uno puede crear objetos Desktop y cambiar a ellos cuando se requiera. El uso de estos objetos es más sencillo de lo que parece y podrás encontrar información detallada en el SDK de Windows.

// Saludos

roman
09-02-2005, 20:34:30
Aquí te va la idea más desarrollada.

Para el ejemplo uso dos aplicaciones: MainApp y LockApp

MainApp se ejecuta normalmente en el escritorio por defecto y al oprimir un botón manda ejecutar la otra en un escritorio alterno. Esta otra aplicación es un simple cuadro de usuario-contraseña. Al oprimir su botón "Ok" se cierra y regresa al escritorio usual.

Para que tengas claro el concepto te puedes bajar el ejemplo de mi página:

DesktopsSrc.zip (14.2kb) (http://romansg.net/ejemplos/DesktopsSrc.zip)
DesktopsExe.zip (398 kb) (http://romansg.net/ejemplos/DesktopsExe.zip)

El primer zip contiene el código fuente de ambas aplicaciones y el segundo son los ejecutables ya compilados.

Pon ambos ejecutables en la misma carpeta. La aplicación LockApp es sólo una simulación así que no requieres poner ninguna contraseña ni usuario.

Por cualquier cosa cierra todas tus aplicaciones antes de ejecutar MainApp, no vaya a ser que debas reiniciar Windows :p

La aplicación MainApp crea el escritorio alterno en el evento OnCreate:


procedure TMainForm.FormCreate(Sender: TObject);
begin
LockDesktop := CreateDesktop(
'LockDesktop', nil, nil, 0,
DESKTOP_CREATEWINDOW or DESKTOP_SWITCHDESKTOP, nil);
end;


donde LockDesktop es una variable privada de tipo HDesk y 'LockDesktop' es el nombre que le damos al escritorio alterno.

El escritorio se destruye en el evento OnDestroy del formulario:


procedure TMainForm.FormDestroy(Sender: TObject);
begin
CloseDesktop(LockDesktop);
end;


En el evento OnClick del botón btnLock es donde se hace el cambio al escritorio alterno:


var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;

begin
FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb := SizeOf(StartInfo);
StartInfo.lpDesktop := PChar('LockDesktop');
CreateProcess('LockApp.exe', nil, nil, nil, false, 0, nil, nil, StartInfo, ProcInfo);

SwitchDesktop(LockDesktop);
end;


Aquí se usa CreateProcess en lugar de algo más sencillo como WinExec para poder especificar en qué escritorio deseamos ejecutar la aplicación.

SwitchDesktop simplemente conmuta al escritorio alterno. Al hacer esto verás un escritorio vacío con una única ventana: la de LockApp.

Esta aplicación es la que debe validar el usuario y contraseña y en su caso conmutar de vuelta al escritorio por defecto:


var
DefaultDesktop: HDesk;

begin
// Cerramos LockApp
Close;

// Obtenemos un 'handle' al escritorio por defecto
DefaultDesktop := OpenDesktop(
'Default', 0, true, DESKTOP_SWITCHDESKTOP);

// conmutamos al escritorio por defecto
SwitchDesktop(DefaultDesktop);
end;


Y listo, eso es básicamente todo lo que hay que hacer.

Mientras el escritorio alterno esté visible el usuario no podrá hacer nada que no sea interactuar con el cuadro de usuario-contraseña.

Otras ventanas, como las que mencionas del Messenger, seguirán abriéndose pero no se verán ni se podrá hacer nada con ellas hasta que no se regrese al escritorio normal.

Ya en la aplicación real hay que cuidar algunos detalles: por ejemplo, impedir que la aplicación LockApp pueda cerrarse con Alt-F4 o cualquier método que no sea a través de la validación de los datos. Esto lo puedes hacer con el evento OnCloseQuery pero para ser más finos tendrás que manejar el mensaje WM_QUERYENDSESSION y dar una opción en LockApp para poder cerrar la sesión de Windows sin necesidad de regresar al escritorio normal pero esto es harina de otro costal... ;)

// Saludos

FDB
09-02-2005, 20:45:35
Muchisimas gracias.

Esto me hace ver que aun estoy crudillo en programación, pero bueno por ahora no puedo pedir mas teniendolo como hobbie.

Pues nada me pongo ahora mismo a estudiar el codigo.

Gracias de nuevo.

bustio
12-10-2005, 03:53:05
Aquí te va la idea más desarrollada.
{.......}
// Saludos

Hola a Roman:
Has explicado de lo mejor el funcionamiento de los Objetos Desktop y probe tus ejemplos y me corren a las mil maravillas.

Yo en lo particular estoy desarrollando una aplicacion algo similar, pero con sus diferencias. Por ejemplo, como hago para que mi aplicacion cree a un segundo Desktop y se llame a si misma?? O sea, que en tu ejemplo, LockApp cree el desktop sobre el que va a correr y luego se muestre a si misma y sea visible desde este nuevo desktop?
Y mi segunda duda es la siguiente: en mi aplicacion, tengo un boton Registrar y uno Cerrar Sesion. La idea es que cuando presiones el Registrar se conecte en ese momento a la BD y pueda entrar sus datos; y luego, una vez reconocido por el sistema la aplicacion se quede residente en la memoria hasta que quieras terminar; y sobre esta misma ventana principal(en la que te registraste) presiones el boton Cerrar Sesion y en ese momento el programa termine y cierre la sesion de windows sobre la que estas trabajando. Esto no se puede hacer con tu ejemplo. Tal pareciera que las aplicaciones que son llamadas desde este nuevo desktop que se crea "le pertenecieran" de algun modo y no se vieran desde el desktop normal.
Me interesaria saber como puedo lograr que mi aplicacion pueda ser visible desde el desktop normal del sistema y desde luego, poder interactuar con ella tambien.
Me parece que estoy pidiendo todo bien masticadito, pero en realidad en estas cosas raras de las APIs de Windows estoy bien perdido. Ojala y pudieras ayudarme.

Delfino
12-10-2005, 11:45:06
Un enclace (http://delphi.about.com/od/formsdialogs/l/aa073101b.htm) hablando de forms con "real stayontop"

bustio
14-10-2005, 03:45:34
Un enclace (http://delphi.about.com/od/formsdialogs/l/aa073101b.htm) hablando de forms con "real stayontop"


Muchas gracias por tu sugerencia, pero no me sirve de mucho. Probe lo que ahi decian y la ventana el task manager de windows me sale por encima de la ventana de mi aplicacion. Me parece que algo ahi esta mal o hice algo mal yo.
De todas maneras, si tienes algo mas que sugerirme con gusto aceptare cualquier ayuda!!
CReo que la solucion a mi problema esta con los objetos Desktop

fide_uci
01-02-2009, 23:53:32
Hola, todo eso esta de maravillas, pero hay una cosa. Si quiero ejecutar otro proceso que no sea LockApp?

Por ejemplo quiero ejecutar el Block de Notas, no me trabaja sustituyendo

esto

CreateProcess('LockApp.exe', nil, nil, nil, false, 0, nil, nil, StartInfo, ProcInfo);

por esto otro...

CreateProcess('C:\WINDOWS\notepad.exe', nil, nil, nil, false, 0, nil, nil, StartInfo, ProcInfo);


me podrian explicar por que no quiere ejecutarse el block de notas??

bLiNdEN
28-07-2011, 18:24:12
Hola roman la verdad que buena idea lo del escritorio alterno nunca se me hubiera ocurrido jajajaja.

te comento estoy usando tu source para crear un programa de bloqueo pero lo que pasa es lo siguiente:

Cuando creo el ejecutable al momento que inicia windows me corre el MainApp pero no el Lock App. Te dejo un link con las dudas que me han surgido en la elaboracion de etste proyecto:

http://www.clubdelphi.com/foros/showthread.php?t=75099

ojala y me puedas ayudar, Gracias.

Saludos!

bLiNdEN