Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Capturar imagen de ventana inactiva (https://www.clubdelphi.com/foros/showthread.php?t=84937)

look 31-12-2013 15:20:05

Capturar imagen de ventana inactiva
 
Hola amigos, estoy desarrollando un pequeño programa para control remoto, tengo una aplicacion cliente y una server, la aplicacion cliente manda una peticion cada segundo al servidor y este le manda al cliente una imagen de una ventana todo esto por medio de sockets, esto funcionan bien, el problema es que al bloquear la sesion ("WIN+L") , la aplicacion cliente conecta bien pero de alguna manera la imagen de capatura que envia se vuelve en blanco, he probado con varias funciones para capturar la imagen pero creo que el problema no va por ahi, pareciera que al bloquear la sesion la ventana queda inactiva... :confused: .
lo que quiero hacer es que se puede capturar la imagen de la ventana aun bloqueada la session, me parece extraño ya que la aplicacion cliente conecta bien con la aplicacion server. :(
Código Delphi [-]
procedure ScreenShot(activeWindow: bool; destBitmap : TBitmap ; hWin : Cardinal) ;
 var
    w,h : integer;
    DC : HDC;
    r : TRect;
 begin
    if activeWindow then
    begin
      hWin := GetForegroundWindow;
      hWin := GetForegroundWindow;
      dc := GetWindowDC(hWin) ;
      GetWindowRect(hWin,r) ;
      w := r.Right - r.Left;
      h := r.Bottom - r.Top;
    end
    else
    begin
      hWin := GetDesktopWindow;
      dc := GetDC(hWin) ;
      w := GetDeviceCaps (DC, HORZRES) ;
      h := GetDeviceCaps (DC, VERTRES) ;
    end;
    try
     destBitmap.Width := w;
     destBitmap.Height := h;
     BitBlt(destBitmap.Canvas.Handle,
            0,
            0,
            destBitmap.Width,
            destBitmap.Height,
            DC,
            0,
            0,
            SRCCOPY) ;
    finally
     ReleaseDC(hWin, DC) ;
    end;
 end;

ecfisa 31-12-2013 17:54:20

Hola look.

Tal vez te sirva impedir el bloqueo durante la duración de tu programa 'cliente' y restaurar la condición al finalizar, algo como:
Código Delphi [-]
implementation

uses Registry;

var
  PrevLockState: Boolean;

function LockWorkstationState: Boolean;
var
  r: TRegistry;
begin
  Result := False;
  with TRegistry.Create do
  try
    RootKey := HKEY_CURRENT_USER;
    if OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\System', False) then
    begin
      Result := Boolean(ReadInteger('DisableLockWorkstation'));
      CloseKey;
    end;
  finally
    Free;
  end;
end;

procedure DisableLockWorkstation(Lock: Boolean);
begin
  with TRegistry.Create do
  try
    RootKey := HKEY_CURRENT_USER;
    if OpenKey('\Software\Microsoft\Windows\CurrentVersion\Policies\System', True) then
    begin
      WriteInteger('DisableLockWorkstation', Integer(Lock));
      CloseKey;
    end;
  finally
    Free;
  end;
end;

procedure TfrmClienteMain.FormCreate(Sender: TObject);
begin
  PrevLockState := LockWorkstationState;
  DisableLockWorkstation(True);
  ...
end;

...

procedure TfrmClienteMain.FormDestroy(Sender: TObject);
begin
  DisableLockWorkstation(PrevLockState);
  ...
end;

Saludos :)

look 31-12-2013 18:23:54

Cita:

Empezado por ecfisa (Mensaje 471193)
Hola look.

Tal vez te sirva impedir el bloqueo durante la duración de tu programa 'cliente' y restaurar la condición al finalizar, algo como:


Saludos :)

Hola amigo, ya habia pensado algo como eso, de esa manera funciona bien, en mi caso lo que quiero monitorear es un servidor, el la aplicacion permite embeber a otra para que otros usuarios no tengan acceso total al servidor utilizando la aplicacion cliente, todo funciona de maravilla, pero el problema es que al bloquear la session el servidor ya deja de funcionar la captura solamente, si me conecto por remotdestktop al servidor y cierro la ventana del del remot desktop el servidor se queda con la ventana del login, es por eso que se me ocurrio si hay alguna manera de capturar la imagen de una ventana en particular aunque la session de windows este en modo lock y la aplicacion este corriendo en el background la aplicacion cliente se comunica bien con el servidor aunque este en modo lock pero no obtengo la captura. :o

look 02-01-2014 15:02:13

hola, parece complicado no, se me ocurre que tel vez si la misma aplicacion pudiera iniciar session en windows cuando el cliente se conecte esto permitiria que trabajara bien, ¿ sera posible esto?, ¿iniciar session desde mi aplicacion en windows sabiendo el usuario y clave?

escafandra 02-01-2014 21:22:55

Cuando una sesión es bloqueada, el sistema cambia de escritorio por lo que es imposible interactuar desde una aplicación que corre como otro usuario que no sea system. En WinXp si tu App corre como system puede cambiar al nuevo escritorio y capturar la pantalla de bloqueo. Si estás simulando entradas de teclado y ratón puedes iniciar o desbloquear la sesión en cuestión.

Saludos.

escafandra 03-01-2014 17:27:50

Para documentar con código lo que expuse anteriormente propongo una función para apropiarse del escritorio que usa el sistema por defecto en un momento dado:

Código Delphi [-]
const WINSTA_ALL_ACCESS = $37F;
procedure SetDefaultWSDesktop;
var
  hWSTA: HWINSTA;
  hDSK: HDESK;
begin
  // Me asigno la estación de ventana y el escritorio por defecto
  hWSTA:= OpenWindowStation('winsta0', true, WINSTA_ALL_ACCESS);
  if hWSTA<>0 then
    if SetProcessWindowStation(hWSTA) then CloseWindowStation(hWSTA);

  hDSK:= OpenInputDesktop(0, true, GENERIC_ALL);
    if hDSK <> 0  then
      if SetThreadDesktop(hDSK) then CloseDesktop(hDSK);
end;

A la hora de capturar conviene antes repetir la secuencia:
Código Delphi [-]
var
  hDSK: HDESK;
begin
  hDSK:= OpenInputDesktop(0, true, GENERIC_ALL);
    if hDSK <> 0  then
      if SetThreadDesktop(hDSK) then CloseDesktop(hDSK);
......

Tu aplicación residente en el PC remoto deberá ser un servicio, como forma más fácil de correr como SYSTEM, pero con la dificultad de acceder al GUI. También podrá ser una simple App que se lance desde un servicio, por lo que será SYSTEM también.

Para completar, conviene revisar los siguientes enlaces Lanzar una aplicación GUI desde un servicio y MiniSystem, una miniaplicación para ejecutar programas con privilegios SYSTEM, que te aclararan conceptos y te darán pautas para realizar lo que pretendes.


Saludos.

look 03-01-2014 21:23:35

Cita:

Empezado por escafandra (Mensaje 471280)
Para documentar con código lo que expuse anteriormente propongo una función para apropiarse del escritorio que usa el sistema por defecto en un momento dado:

Gracias amigo, voy a investigar sobre lo que mencionas.

Saludos!


La franja horaria es GMT +2. Ahora son las 10:29:46.

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