Ir para conteúdo
Fórum Script Brasil
  • 0

Capturando Desktop


Paulo Nobre

Pergunta

Estou desenvolvendo, a título de estudo, um programa para capturar

telas;total,janela ativa e recorte.Só que é mais difícil do que imaginava.

As próximas perguntas, como esta, que postarei aqui no forum, dirão respeito

a isto.

Espero poder contar com a ajuda do forum para desenvolver este estudo.

Consegui a seguinte função para capturar o desktop:

procedure TForm1.ScreenCapture(Filename: TFilename);

var
DHDC: HDC;
Buffer : TBitmap;

Begin

 begin

 DHDC := GetWindowDC(GetDesktopWindow);
 Buffer := tBitmap.Create;
 Buffer.Width  := Screen.Width;
 Buffer.Height := Screen.Height;
 BitBlt(Buffer.Canvas.Handle,0,0,Screen.Width,Screen.Height,DHDC,0,0,SRCCOPY);
 Buffer.SaveToFile(Filename);
 Buffer.Free;
 ReleaseDC(GetDesktopWindow,DHDC);
 end;
End;
Gostaria de criar o bitmap(com o nome flash01.bmp) relativo a esta captura num caminho determinado, por exemplo C:\temp e exibí-lo num image. Como poderia fazer isto com função acima? Mesmo alterando FileName:String e colocando 'C:\temp'na chamada da função dá erro. Uma outra função que peguei por aí é a seguinte:
function CaptureScreenRect( ARect: TRect ): TBitmap;
//
// Captura a tela e salva-a em um Bitmap
//
// Use-a assim:
//
// Image1.picture.Assign(CaptureScreenRect(Rect(0,0,Width,Height)));
//
var
ScreenDC: HDC;
begin
Result := TBitmap.Create;
with Result, ARect do
     begin
     Width := Right - Left;
     Height := Bottom - Top;
     ScreenDC := GetDC( 0 );
     try
       BitBlt( Canvas.Handle, 0, 0, Width, Height, ScreenDC, Left, Top, SRCCOPY );
     finally
       ReleaseDC( 0, ScreenDC );
     end;
  //  Palette := GetSystemPalette;
     end;
end;
Usando Image1.picture.Assign(CaptureScreenRect(Rect(0,0,Width,Height))); consigo colocar o desktop na image1, porém não consigo salvar image1.Picture.SaveToFile('C:\temp');dá erro. O erro que aparece é o mesmo que aparece com o uso da procedure anteriormente citada: Não é possível criar o arquivo C:\temp, o acesso está negado Em resumo preciso do seguinte: 1) Capturar o desktop 2) Exibir num image 3) Salvar o desktop, num bitmap de nome Flash01.bmp, num diretório pré determinado, por exemplo C:\temp Dá para adaptar a procedure ou a função para fazer isto que preciso? O código abaixo também salva o desktop
keybd_event(vk_snapshot,0, 0, 0); {Tela toda.}

porém como pegar a tela toda salvar num arquivo .bmp e ainda

salvar este arquivo no C:\temp, por exemplo.

HELP,HELP,HELP.

Link para o comentário
Compartilhar em outros sites

16 respostass a esta questão

Posts Recomendados

  • 0

Acho que utilizando Keybd_Event é a mais prática:

var Bmp:TBitmap;
begin
  Bmp := TBitmap.Create;
  Keybd_Event(VK_Snapshot,0, 0, 0);
  Bmp.LoadFromClipboardFormat(CF_BitMap, Clipboard.GetAsHandle(CF_Bitmap), 0);
  Image1.Picture.Bitmap.Assign(Bmp);
  Bmp.SaveToFile('C:\Temp\Flash01.bmp');
  Bmp.Free;
end;

Link para o comentário
Compartilhar em outros sites

  • 0

S3C,

ESTOU TENDO DOIS PROBLEMAS:

1) ACHO QUE NÃO ESTOU SABENDO ALOCAR O CÓDIGO DE MANEIRA CORRETA.

APARECE O ERRO DE QUE O FORMATO DO CLIPBOARD NÀO ESTA CORRETO, POIS OU ESTÁ VAZIO OU ESTÁ COM TEXTO, POIS DA MANEIRA COMO ESTOU USANDO O CÓDIGO AO APERTAR PRINT

NÀO ESTÁ INDO O DESKTOP PARA O CLIPBOARD.

NO ONCREAT COLOQUEI:
{== Desabilita a tecla Print Screen ==}
 RegisterHotkey( Handle, 500, 0, VK_SNAPSHOT );
CRIEI A PROCEDURE(COM O CÓDIGO QUE VOCÊ FORNECEU-ESTÁ NA SEÇÃO PÚBLIC)
Procedure TfrmPrincipal.CapturarTelaTodaSalvarBitmap(Filename:TFilename);
Var
  Bmp:TBitmap;
begin
  Bmp := TBitmap.Create;
  Keybd_Event(VK_Snapshot,0, 0, 0);
  Bmp.LoadFromClipboardFormat(CF_BitMap, Clipboard.GetAsHandle(CF_Bitmap), 0);
  Image1.Picture.Bitmap.Assign(Bmp)// o erro acontece aqui pois o clipbarde está vazio ou com um formato diferente do de imagem.
  Bmp.SaveToFile(FileName);
  Bmp.Free;
end;
QUE ESTÁ SENDO CHAMADA PELA PROCEDURE
procedure TfrmPrincipal.WMHotKey (var Msg : TWMHotKey);
Var
  Destino:String;
  Numero:Integer;
begin
  if Msg.HotKey = 500 then
  begin
    reg.RootKey:=HKEY_LOCAL_MACHINE;
    reg.OpenKey('SOFTWARE\NOBRE INFORMÁTICA\FLASH',FALSE);
    Numero:= reg.ReadInteger('Número do último screen salvo')+ 1;
    Destino:= reg.ReadString('Diretório de Destino')+'\Flash'+IntToStr(Numero)+'.bmp';
    If reg.ReadString('Formato')= 'BMP 256' then
      If reg.ReadString('Capturar')= 'A tela toda' then
        begin
          CapturarTelaTodaSalvarBitmap(Destino);
        end
      Else If reg.ReadString('Capturar')= 'A janela ativa' then
        begin
          CapturarJanelaAtivaSalvarBitmap(Destino);
        end;
    //Else If reg.ReadString('Formato')= 'BMP TRUE ' then
  reg.CloseKey;
  end;
end;

QUANDO SAIO DO PROGRAMA E CLICO EM PRINT COLOCO O DESKTOP NO CLIPBOARD(o que mostra não ser do código o problema e sim como estou usando), PORÉM COM UM PROBLEMA: DEMORA MUUUUUUUUITO(2 MINUTOS-ESTE É O OUTRO PROBLEMA) PARA A IMAGEM APARECER NO IMAGE E O ÍCONE DO BITMAP APARECER NO DESTINO ESCOLHIDO(PASTA).

Eu achava que a função Keybd_Event(VK_Snapshot,0, 0, 0);já copiava o desktop para a área de tranferencia.

VOCÊ CONSEGUE VER ALGO ERRADO?

DESCONFIEI QUE DEVERIA COLOCAR ALGO NO EVENTO ONKEYDOW, MAS NÃO SEI COMO.

PENSEI EM

If Key = VK_SNAPSHOT then WMHOTKEY(?), MAS NÃO CONSEGUI PERCEBER O QUE COLOCAR NO LUGAR DA INTERROGAÇÀO(QUAL O PARÂMETRO).

A procedure WMHotkey não está sendo chamada em lugar nenhum apenas está declarada, talvez este possa ser o erro, mas não estou sabendo alocá-la, como mencionei acima.

Link para o comentário
Compartilhar em outros sites

  • 0

Olá Paulo, bom como você registrou a VK_Snapshot como uma tecla de atalho pelo RegisterHotKey, quando você pressiona PrintScreen, ele executa a procedure WMHotKey e nesta procedure você manda executar CapturarTelaTodaSalvarBitmap.

O que acontece:

CapturarTelaTodaSalvarBitmap executa Keybd_Event(VK_Snapshot,0, 0, 0);

Isso simula o pressionamento da tecla Print Screen e WMHotKey é novamente chamado.

Então é um looping infinito, pois WMHotKey executa CapturarTelaTodaSalvarBitmap que por sua vez executa WMHotKey através de Keybd_Event.

Como PrintScreen já foi pressionado, então você não precisa mais chamar Keybd_Event.

Link para o comentário
Compartilhar em outros sites

  • 0

Olá, s3c,

Mas o que eu faço para que o desktop vá para o clipboard.

Do jeito que o código está nada vai para o clipboard, porisso dá o erro.

O que está faltando para que isso aconteça?

O que você acha melhor fazer?

Tirar o registro?

Estou meio confuso!

Link para o comentário
Compartilhar em outros sites

  • 0

Deve ser porque você ainda está no evento WM_HotKey e a mensagem ainda não foi processada; ou seja; após terminar esse evento é que você terá acesso ao Clipboard com a imagem.

Sugiro que você capture as msgs diretamente do Clipboard e despreze RegisterHotKey. Tem um exemplo em: http://scriptbrasil.com.br/forum/index.php?showtopic=71182

Troque Clipboard.HasFormat(CF_TEXT) por Clipboard.HasFormat(CF_Bitmap)

Link para o comentário
Compartilhar em outros sites

  • 0

Ok, s3c,

Mas me diga uma coisa...

Você forneceu o código abaixo

Procedure TfrmPrincipal.CapturarTelaTodaSalvarBitmap(Filename:TFilename);
Var
 Bmp:TBitmap;
begin
 Bmp := TBitmap.Create;
 Bmp.LoadFromClipboardFormat(CF_BitMap, Clipboard.GetAsHandle(CF_Bitmap), 0);
 Image1.Picture.Bitmap.Assign(Bmp)
 Bmp.SaveToFile(FileName);
 Bmp.Free;
end;
Para salvar em forma de bitmap: Você poderia me dizer se para salvar em formato GIF e JPEG, basta trocar as extensões acima, ou seja ficaria:
Procedure TfrmPrincipal.CapturarTelaTodaSalvarGIF(JPEG)(Filename:TFilename);
Var
 GIF(JPEG):TGIF(TJPeg);
begin
 GIF(JPEG) := TGIF(JPEG).Create;
 GIF(JPEG).LoadFromClipboardFormat(CF_BitMap, Clipboard.GetAsHandle(CF_Bitmap), 0);
 Image1.Picture.Bitmap.Assign(Bmp)
 Bmp.SaveToFile(FileName);
 Bmp.Free;
end;

ou seria algo diferente?

Você poderia me dizer como fazer?

Outra coisa é em relação a como foi salvo em BITMAP.

Existe BMP 256 e BMP TRUE, como mando salvar de uma maneira e de outra?

O código que voce forneceu foi para 256 ou TRUE?

Link para o comentário
Compartilhar em outros sites

  • 0

Você poderia me dizer se para salvar em formato GIF e JPEG...
O que sei que dá para fazer é assinalar um jpeg para um bitmap, o que reduz em muito o tamanho do arquivo: JPEG.Assign(Bitmap);

Já o formato GIF, nunca testei.

Outra coisa é em relação a como foi salvo em BITMAP.

Existe BMP 256 e BMP TRUE, como mando salvar de uma maneira e de outra?

O código que voce forneceu foi para 256 ou TRUE?

Também nunca me aprofundei nisso, mas acho que a imagem Bitmap no Clipboard fica conforme está sua resolução de tela.
Link para o comentário
Compartilhar em outros sites

  • 0

A procedure adaptada da anterior e esta para jpeg só que dá erro

Procedure TfrmPrincipal.CapturarTelaTodaSalvarJPEG(Filename:TFilename);
Var
  JPEG:TJPEGImage;
begin
  JPEG := TJPEGImage.Create;
  JPEG.LoadFromClipboardFormat(CF_BitMap,Clipboard.GetAsHandle(CF_BitMap),0);
  Image1.Picture.Assign(JPEG);//o erro está aqui.
  JPEG.SaveToFile(FileName);
  JPEG.Free;
end;

dá erro mesmo colocando Image1.Picture.Bitmap.Assign(JPEG);

não encontrei parametros como cf_jPeg

quero salvar como jpeg.

Será que tem que converter primeiro de bitmap para jpeg par depois entrar com

a procedure?

Link para o comentário
Compartilhar em outros sites

  • 0

Primeiro você cria o JPEG:

JPEG := TJPEGImage.Create;

Depois você carrega o bitmap do Image pelo Clipboard:

Image1.Picture.Bitmap.LoadFromClipboardFormat(CF_BitMap,Clipboard.GetAsHandle(CF_BitMap),0);

Depois você assinala o JPEG a partir do Bitmap:

JPEG.Assign(Image1.Picture.Bitmap);

Depois você salva o JPEG:

JPEG.SaveToFile(FileName);

JPEG.Free;

Link para o comentário
Compartilhar em outros sites

  • 0

Alguém sabe como fazer para capturar apenas uma parte do desktop.

Vi num programa o seguinte:

O usuário clicava em printscreen, o ponteiro do mouse mudava para uma cruz,

clicava num ponto do desktop, deslocava o mouse abria-se um retângulo pontilhado(tipo programas de desenho onde você desenha um retângulo), clicava-se num outro ponto e a região compreendida dentro do retângulo era capturada.

Não tenho a mínima idéia. Pesquisei na rede e não encontrei nada.

Alguém já fez?

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152k
    • Posts
      651,7k
×
×
  • Criar Novo...