Implementando captura de tela remota usando Delphi
Centro CAD de Shandong Juli Co., Ltd.
Tan Geqin
---- No gerenciamento de rede, às vezes é necessário entender o uso de computadores online monitorando a tela do computador remoto. Embora existam muitos softwares no mercado que podem realizar esta função, e alguns podem até realizar o controle remoto, eles não têm flexibilidade de uso. Por exemplo, eles não podem especificar o tamanho e a posição da área da tela do computador remoto e, portanto, não podem monitorar vários. telas em uma tela ao mesmo tempo. Na verdade, você pode usar o Delphi para compilar uma ferramenta flexível de captura de tela remota, que é brevemente descrita a seguir.
---- 1. Requisitos de software e hardware.
---- Rede peer-to-peer Windows95/98, o computador usado para monitoramento (doravante denominado computador mestre) e o computador monitorado (doravante denominado computador controlado) devem estar equipados com TCP/ip protocolo e configurado corretamente. Se não houver rede, você também poderá depurar em um computador.
---- 2. Método de implementação.
---- Prepare dois aplicativos, um é VClient.exe, instalado na máquina controlada, e o outro é VServer.exe, instalado na máquina de controle principal. VServer.exe especifica o endereço IP da máquina controlada a ser monitorada e o tamanho e posição da área a ser capturada na tela da máquina controlada e emite uma instrução de captura de tela para VClient.exe Após receber a instrução, VClient. .exe Selecione uma área designada na tela do computador, gere um fluxo de dados, envie-o de volta ao computador host e exiba a imagem BMP da área capturada no computador host. Pode-se perceber pelo processo acima que existem duas chaves para este método: uma é como capturar a tela da máquina controlada e a outra é como transmitir dados entre os dois computadores através do protocolo TCP/IP.
---- UDP (User Datagram PROtocol, que significa User Message Protocol) é um dos protocolos de comunicação amplamente utilizados na Internet. Diferente do protocolo TCP, é um protocolo de transmissão sem conexão, sem mecanismo de confirmação e não é tão confiável quanto o TCP, mas é mais eficiente que o TCP e é mais adequado para monitoramento remoto de tela. Ao mesmo tempo, o controle UDP não distingue entre o servidor e o cliente, apenas a extremidade emissora e a extremidade receptora. A programação é relativamente simples, então o protocolo UDP é selecionado e o controle TNMUDP fornecido pelo Delphi 4.0 é usado.
---- 3. Crie um programa de demonstração.
----A primeira etapa é compilar o arquivo VClient.exe. Crie um novo projeto Delphi e defina a propriedade Name do formulário padrão como "Cliente". Adicione o controle TNMUDP, defina o atributo Name como "CUDP"; defina o atributo LocalPort como "1111", deixe o controle CUDP monitorar a porta 1111 da máquina controlada e, quando os dados forem enviados para a porta, acione o evento OnDataReceived de o controle CUDP; defina o atributo RemotePort como "2222", quando o controle CUDP envia dados, os dados são enviados para a porta 2222 do computador host.
---- Adicionar definição de variável após implementação
const BufSize=2048;{Tamanho do buffer para envio de cada dado}
var
BmpStream:TMemoryStream;
LeftSize:Longint;{O número de bytes restantes após o envio de cada dado}
Adicione o código para o evento OnCreate do cliente:
procedimento TClient.FormCreate(Remetente: TObject);
começar
BmpStream:=TMemoryStream.Create;
fim;
Adicione o código para o evento OnDestroy do Cliente:
procedimento TClient.FormDestroy(Remetente: TObject);
começar
BmpStream.Free;
fim;
Adicione o código para o evento OnDataReceived do controle CUDP:
procedimento TClient.CUDPDataReceived(Remetente: TComponent;
NúmeroBytes: Inteiro; FromIP: String);
var
CtrlCode:array[0..29] de char;
Buf:array[0..BufSize-1] de char;
TmpStr: string;
SendSize,LeftPos,TopPos,RightPos,BottomPos:inteiro;
começar
CUDP.ReadBuffer(CtrlCode,NumberBytes);{Ler código de controle}
se CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='mostrar' então
começar {Os primeiros 4 dígitos do código de controle são "show", indicando que o computador host emitiu um comando de captura de tela}
se BmpStream.Size=0 então {Nenhum dado pode ser enviado, capturas de tela devem ser feitas para gerar dados}
começar
TmpStr:=StrPas(CtrlCode);
TmpStr:=Copiar(TmpStr,5,Comprimento(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copiar(TmpStr,Pos(':',TmpStr)+1,Comprimento(TmpStr)
-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copiar(TmpStr,Pos(':',TmpStr)+1,Comprimento(TmpStr)-
Pos(':',TmpStr));
RightPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
BottomPos:=StrToInt(Copy(TmpStr,Pos(':',TmpStr
)+1,Comprimento(TmpStr)-Pos(':',TmpStr)));
ScreenCap(LeftPos,TopPos,RightPos,BottomPos);
Faça uma captura de tela}
fim;
se LeftSize>BufSize então SendSize:=BufSize
senão SendSize:=LeftSize;
BmpStream.ReadBuffer(Buf,SendSize);
LeftSize:=LeftSize-SendSize;
se LeftSize=0 então BmpStream.Clear;{limpar fluxo}
CUDP.RemoteHost:=FromIP; {FromIP é o endereço IP do host}
CUDP.SendBuffer(Buf,SendSize); {Envia dados para a porta 2222 do computador host}
fim;
fim;
ScreenCap é uma função personalizada que captura uma área específica da tela.
O código é o seguinte:
procedimento TClient.ScreenCap(LeftPos,TopPos,
RightPos,BottomPos:inteiro);
var
RectWidth,RectHeight:inteiro;
FonteDC,DestDC,Bhandle:inteiro;
Bitmap:TBitmap;
começar
RectWidth:=RightPos-LeftPos;
RectHeight:=BottomPos-TopPos;
SourceDC:=CreateDC('DISPLAY',',',nil);
DestDC:=CreateCompatibleDC(SourceDC);
Bhandle:=CreateCompatibleBitmap(SourceDC,
RectWidth,RetHeight);
SelectObject(DestDC,Bhandle);
BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC,
LeftPos,TopPos,SRCCOPY);
Bitmap:=TBitmap.Create;
Bitmap.Handle:=BHandle;
BitMap.SaveToStream(BmpStream);
BmpStream.Position:=0;
LeftSize:=BmpStream.Size;
Bitmap.Grátis;
ExcluirDC(DestDC);
ReleaseDC(Bhandle,FonteDC);
fim;
Salve como "C:VClientClnUnit.pas" e "C:VClientVClient.dpr",
e compilar.
----A segunda etapa é compilar o arquivo VServer.exe. Crie um novo projeto Delphi e defina a propriedade Name do formulário como “Servidor”. Adicione o controle TNMUDP, defina o atributo Name como "SUDP"; defina o atributo LocalPort como "2222", deixe o controle SUDP monitorar a porta 2222 do computador host e, quando os dados forem enviados para a porta, acione o evento OnDataReceived de o controle SUDP; defina o atributo RemotePort como "1111", quando o controle SUDP envia dados, os dados são enviados para a porta 1111 da máquina controlada. Adicione o controle Image1, defina a propriedade Align como "alClient"; adicione o controle Button1, defina a propriedade Caption como "Screenshot"; adicione o controle Label1, defina a propriedade Caption como "Left: Top: Right: Bottom"; Insira o controle Edit1 e defina a propriedade Text como "0:0:100:100"; adicione o controle Label2 e defina a propriedade Caption como "endereço IP da máquina controlada" e defina a propriedade Text como "127.0.0.1";
Adicionar definição de variável após implementação
const BufSize=2048;
var
RsltStream,TmpStream:TMemoryStream;
Adicione o código para o evento OnCreate do servidor:
procedimento TServer.FormCreate(Remetente: TObject);
começar
RsltStream:=TMemoryStream.Create;
TmpStream:=TMemoryStream.Create;
fim;
Adicione o código para o evento OnDestroy do Cliente:
procedimento TServer.FormDestroy(Remetente: TObject);
começar
RsltStream.Free;
TmpStream.Free;
fim;
Adicione o código para o evento OnClick do controle Button1:
procedimento TServer.Button1Click(Remetente: TObject);
var ReqCode:array[0..29] of char;ReqCodeStr:string;
começar
ReqCodeStr:='show'+Edit1.Text;
StrpCopy(ReqCode,ReqCodeStr);
TmpStream.Clear;
RsltStream.Clear;
SUDP.RemoteHost:=Edit2.Text;
SUDP.SendBuffer(ReqCode,30);
fim;
Adicione o código para o evento OnDataReceived do controle SUDP:
procedimento TServer.SUDPDataReceived(Remetente: TComponent;
NúmeroBytes: Inteiro; FromIP: String);
var ReqCode:array[0..29] of char;ReqCodeStr:string;
começar
ReqCodeStr:='show'+Edit1.text;
StrpCopy(ReqCode,ReqCodeStr);
SUDP.ReadStream(TmpStream);
RsltStream.CopyFrom(TmpStream,NumberBytes);
se NumberBytes<BufSize então {os dados foram lidos}
começar
RsltStream.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(RsltStream);
TmpStream.Clear;
RsltStream.Clear;
fim
outro
começar
TmpStream.Clear;
CódigoReq:='mostrar';
SUDP.RemoteHost:=Edit2.Text;
SUDP.SendBuffer(ReqCode,30);
fim;
fim;
Salve como "C:VServerSvrUnit.pas" e
"C:VServerVServer.dpr" e compile.
---- 4. Teste.
---- 1. Teste de máquina local: execute Vserver.exe e VClient.exe ao mesmo tempo na máquina local e use as configurações padrão do programa para fazer capturas de tela. Verifique "Painel de Controle" - "Rede" - "TCP/IP" - "Endereço IP", defina o "Endereço IP do Cliente" do programa para este endereço e ele funcionará normalmente.
---- 2. Teste remoto: Selecione uma máquina controlada, execute VClient.exe; selecione outra máquina mestre, execute VServer.exe e defina o "endereço IP da máquina controlada", ou seja, o conteúdo do Edit2, como controlado O Endereço IP da máquina e "fazer uma captura de tela". O texto acima apresenta brevemente o método de implementação de captura de tela remota. Quanto ao monitoramento de várias máquinas controladas ao mesmo tempo em uma tela na máquina de controle principal, os leitores podem melhorá-lo por conta própria. O programa acima foi depurado e passado na rede ponto a ponto do Windows98 e Delphi 4.0.