PDA

Ver la Versión Completa : Captura de pantalla en el OnDeactivate


afxe
03-10-2006, 18:06:04
Hola foristas.

He realizado un programa mdi en el cual al desactivarse un form capturo el area cliente del form desactivado (con la api bitblt), lo grabo como bitmap, lo recupero en un TImage, lo obscurezco y lo repinto en el form desactivado, para dar la impresión de dejarlo "en la sombra" :D (en el evento OnActivate hago desaparecer el TImage, apareciendo de nuevo el form claro y nítido).


procedure TFrmB_Base.FormDeactivate(Sender: TObject);
var
B: TBitmap;
SrcDC : HDC;
iLT : Integer;
begin
iLT := GetSystemMetrics(SM_CYCAPTION);
B := TBitmap.Create;
B.Width := Self.Width;
B.Height := Self.Height-iLT;
try
SrcDC := GetWindowDC(Self.Handle);
BitBlt(B.Canvas.handle, 0, 0, B.Width, B.Height, SrcDC, 0, iLT, SRCCOPY);
finally
ReleaseDC(Self.Handle, SrcDC);
end;
b.SaveToFile ('c:\t.bmp');
b.Free;
MiPanel.Align := alClient;
Image2.Picture.LoadFromFile('c:\t.bmp');
MiPanel.Visible := True;
MiPanel.BringToFront;
OscurecerTImage(Image2, 180);
end;



(El componente TImage está dentro de un TPanel, para que se superponga a cualquier otro componente del form)

¿El problema? Pues que el evento OnDeactivate, que es donde hago la captura de pantalla, se lanza despues del OnCreate del nuevo Form, por lo cual en la captura realizada aparece el borde y el caption del Form que se está creado, pues hasta que no se ha creado no ha cojido el foco y no se lanza el evento Deactivate. :mad:

Creo haber rebuscado bastante en el foro pero no he encontrado la solución a esta pregunta: ¿Cómo puedo capturar el área cliente de un form sin tener en cuenta lo que pueda tener "superpuesto"? :confused:

Gracias de antemano.

seoane
03-10-2006, 18:20:50
Dependiendo de la versión de delphi que tengas, el formulario tendrá el método GetFormImage, que provoca que todos los controles del formulario se dibujen en un bitmap. Es decir:


var
Bitmap: TBitmap;
begin
Bitmap:= GetFormImage;
try
// Aquí tienes el formulario dibujado en un bitmap, haz con el lo que quieras
finally
Bitmap.Free;
end;
end;

afxe
04-10-2006, 11:21:17
:eek: Después de dejarme los ojos buscando información sobre captura de pantallas en el foro me cuentas que esto:

var
B: TBitmap;
SrcDC : HDC;
iLT : Integer;
begin
iLT := GetSystemMetrics(SM_CYCAPTION);
B := TBitmap.Create;
B.Width := Self.Width;
B.Height := Self.Height-iLT;
try
SrcDC := GetWindowDC(Self.Handle);
BitBlt(B.Canvas.handle, 0, 0, B.Width, B.Height, SrcDC, 0, iLT, SRCCOPY);
finally
ReleaseDC(Self.Handle, SrcDC);
end;
b.SaveToFile ('c:\t.bmp');
b.Free;
end;


Equivale exactamente a esto:


begin
GetFormImage.SaveToFile('c:\t.bmp');
end;


y sin el inconveniente de que capture las pantallas superpuestas.... pues eso.... de piedra :eek: .

Mil Gracias Seoane, era lo que necesitaba.

seoane
04-10-2006, 13:30:29
Solo dos apuntes, GetFormImage devuelve un TBitmap y hay que destruirlo cuando ya no lo necesitemos, de lo contrario quedara en memoria. Y segundo, si lo que quieres es mostrar la imagen en un TImage no hace falta que lo guardes primero en disco, el objeto TImage cuenta con el método Assign que cumple perfectamente esa función.


var
Bitmap: TBitmap;
begin
Bitmap:= GetFormImage;
try
Image1.Picture.Assign(Bitmap);
finally
// Importante destruir el bitmap
Bitmap.Free;
end;
end;

afxe
04-10-2006, 18:32:27
Efectivamente... tras estar trabajando alocadamente con el aplicativo he obtenido un bonito error de memoria insuficiente.

Gracias por ambos consejos. Ahora estoy tratando de resolver una cosa... Tengo un grid predefinido dentro de un frame que he usado en los forms (uso las infopower y D7). Al capturar la pantalla, si el foco está fuera del Grid o, si está en el grid, el foco lo tiene el InplaceEditor del Grid, no hay problema, pero si el foco lo tiene el Grid solo aparece en la captura la celda seleccionada, el resto del grid es un gran cuadrado gris :confused: . Raro no???

Gracias de nuevo Seoane.

seoane
04-10-2006, 18:49:49
Raro no???


Pues no es tan raro, el método GetFormImage crea un bitmap y fuerza a cada uno de los componentes a dibujarse en el. En principio el método es ideal porque es independiente de lo que realmente se este viendo en la pantalla, pero también hay que ver como interpretan los componentes la orden de dibujarse. Parece ser que a ese componente en concreto se le atraganta la orden, pero ese ya es problema del componente.