Delphi를 사용하여 원격 화면 캡처 구현
Shandong Juli Co., Ltd. CAD 센터
탄 게친
---- 네트워크 관리에서는 원격 컴퓨터 화면을 모니터링하여 온라인 컴퓨터의 사용량을 파악해야 하는 경우가 있습니다. 시중에는 이 기능을 수행할 수 있는 소프트웨어가 많고 일부는 원격 제어도 가능하지만 사용 유연성이 부족합니다. 예를 들어 원격 컴퓨터 화면 영역의 크기와 위치를 지정할 수 없으므로 여러 개를 모니터링할 수 없습니다. 동시에 한 화면에 표시됩니다. 실제로 Delphi를 사용하여 유연한 원격 화면 캡처 도구를 컴파일할 수 있으며, 이에 대해 간략하게 설명하면 다음과 같습니다.
---- 1. 소프트웨어 및 하드웨어 요구 사항.
---- Windows95/98 P2P 네트워크, 모니터링에 사용되는 컴퓨터(이하 마스터 컴퓨터라고 함) 및 모니터링되는 컴퓨터(이하 제어되는 컴퓨터라고 함)에는 TCP/ip가 장착되어 있어야 합니다. 프로토콜을 사용하고 올바르게 구성되었습니다. 네트워크가 없으면 컴퓨터에서 디버깅할 수도 있습니다.
---- 2. 구현 방법.
---- 두 개의 응용 프로그램을 준비합니다. 하나는 제어되는 컴퓨터에 설치된 VClient.exe이고 다른 하나는 주 제어 컴퓨터에 설치된 VServer.exe입니다. VServer.exe는 모니터링할 제어되는 시스템의 IP 주소와 제어되는 시스템의 화면에서 캡처할 영역의 크기 및 위치를 지정하고 VClient.exe에 화면 캡처 명령을 내립니다. .exe 컴퓨터 화면에서 지정된 영역을 선택하고, 데이터 스트림을 생성하여 호스트 컴퓨터로 다시 보내고, 캡처된 영역의 BMP 이미지를 호스트 컴퓨터에 표시합니다. 위 프로세스에서 볼 수 있듯이 이 방법에는 두 가지 핵심이 있습니다. 하나는 제어되는 기계에서 화면을 캡처하는 방법이고, 다른 하나는 TCP/IP 프로토콜을 통해 두 컴퓨터 간에 데이터를 전송하는 방법입니다.
---- UDP(User Datagram PROtocol, 사용자 메시지 프로토콜을 의미)는 인터넷에서 널리 사용되는 통신 프로토콜 중 하나입니다. TCP 프로토콜과 달리 확인 메커니즘이 없는 비연결 전송 프로토콜이며 TCP만큼 안정적이지는 않지만 TCP보다 효율적이며 원격 화면 모니터링에 더 적합합니다. 동시에 UDP 제어는 서버와 클라이언트를 구분하지 않고 송신측과 수신측만 구분합니다. 프로그래밍이 비교적 간단하므로 UDP 프로토콜이 선택되고 Delphi 4.0에서 제공하는 TNMUDP 제어가 사용됩니다.
---- 3. 데모 프로그램을 작성합니다.
----첫 번째 단계는 VClient.exe 파일을 컴파일하는 것입니다. 새로운 Delphi 프로젝트를 생성하고 기본 폼의 Name 속성을 "Client"로 설정합니다. TNMUDP 컨트롤을 추가하고, Name 속성을 "CUDP"로 설정하고, LocalPort 속성을 "1111"로 설정하고, 컨트롤 CUDP가 제어되는 시스템의 1111 포트를 모니터링하도록 하고, 데이터가 포트로 전송되면 OnDataReceived 이벤트를 트리거합니다. 제어 CUDP는 RemotePort 속성을 "2222"로 설정합니다. 제어 CUDP가 데이터를 보낼 때 데이터는 호스트 컴퓨터의 2222 포트로 전송됩니다.
---- 구현 후 변수 정의 추가
const BufSize=2048;{각 데이터를 전송하기 위한 버퍼 크기}
var
BmpStream:TMemoryStream;
LeftSize:Longint;{각 데이터를 보낸 후 남은 바이트 수}
클라이언트의 OnCreate 이벤트에 대한 코드를 추가합니다.
절차 TClient.FormCreate(Sender: TObject);
시작하다
BmpStream:=TMemoryStream.Create;
끝;
클라이언트의 OnDestroy 이벤트에 대한 코드를 추가합니다.
절차 TClient.FormDestroy(Sender: TObject);
시작하다
BmpStream.Free;
끝;
컨트롤 CUDP의 OnDataReceived 이벤트에 대한 코드를 추가합니다.
절차 TClient.CUDPDataReceived(발신자: TComponent;
NumberBytes: 정수, FromIP: 문자열);
var
CtrlCode:문자의 배열[0..29];
Buf:array[0..BufSize-1] of char;
TmpStr: 문자열;
SendSize,LeftPos,TopPos,RightPos,BottomPos:integer;
시작하다
CUDP.ReadBuffer(CtrlCode,NumberBytes);{제어 코드 읽기}
if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='표시' 다음
start {제어 코드의 처음 4자리는 "show"이며 호스트 컴퓨터가 화면 캡처 명령을 실행했음을 나타냅니다.}
if BmpStream.Size=0 then {전송할 데이터가 없습니다. 데이터를 생성하려면 스크린샷을 찍어야 합니다.}
시작하다
TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,길이(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=복사(TmpStr,Pos(':',TmpStr)+1,길이(TmpStr)
-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=복사(TmpStr,Pos(':',TmpStr)+1,길이(TmpStr)-
Pos(':',TmpStr));
RightPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
BottomPos:=StrToInt(Copy(TmpStr,Pos(':',TmpStr
)+1,길이(TmpStr)-Pos(':',TmpStr)));
ScreenCap(LeftPos,TopPos,RightPos,BottomPos);
스크린샷 찍기}
끝;
LeftSize>BufSize이면 SendSize:=BufSize
그렇지 않으면 SendSize:=LeftSize;
BmpStream.ReadBuffer(Buf,SendSize);
LeftSize:=LeftSize-SendSize;
LeftSize=0이면 BmpStream.Clear;{스트림 지우기}
CUDP.RemoteHost:=FromIP; {FromIP는 호스트 IP 주소입니다.}
CUDP.SendBuffer(Buf,SendSize); {호스트 컴퓨터의 포트 2222로 데이터 보내기}
끝;
끝;
그 중 스크린캡(ScreenCap)은 화면의 특정 영역을 캡쳐하는 커스텀 기능이다.
코드는 다음과 같습니다:
절차 TClient.ScreenCap(LeftPos,TopPos,
오른쪽 위치, 아래쪽 위치:정수);
var
직사각형폭,직사각형 높이:정수;
SourceDC,DestDC,Bhandle:정수;
비트맵:TBitmap;
시작하다
RectWidth:=오른쪽 위치-왼쪽 위치;
RectHeight:=BottomPos-TopPos;
SourceDC:=CreateDC('DISPLAY',',',nil);
대상DC:=CreateCompatibleDC(SourceDC);
Bhandle:=CreateCompatibleBitmap(SourceDC,
직사각형폭, 직사각형높이);
SelectObject(DestDC,Bhandle);
BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC,
왼쪽위치,위쪽위치,SRCCOPY);
비트맵:=TBitmap.Create;
Bitmap.Handle:=B핸들;
BitMap.SaveToStream(BmpStream);
BmpStream.Position:=0;
LeftSize:=BmpStream.Size;
비트맵.무료;
삭제DC(대상DC);
ReleaseDC(밴드핸들,소스DC);
끝;
"C:VClientClnUnit.pas" 및 "C:VClientVClient.dpr"로 저장하고,
그리고 컴파일하세요.
----두 번째 단계는 VServer.exe 파일을 컴파일하는 것입니다. 새로운 Delphi 프로젝트를 생성하고 폼의 Name 속성을 "Server"로 설정합니다. TNMUDP 컨트롤을 추가하고, Name 특성을 "SUDP"로 설정하고, LocalPort 특성을 "2222"로 설정하고, 컨트롤 SUDP가 호스트 컴퓨터의 2222 포트를 모니터링하도록 하고, 데이터가 포트로 전송되면 OnDataReceived 이벤트를 트리거합니다. 제어 SUDP는 RemotePort 속성을 "1111"로 설정합니다. 제어 SUDP가 데이터를 보낼 때 데이터는 제어되는 시스템의 1111 포트로 전송됩니다. Image1 컨트롤을 추가하고 Align 속성을 "alClient"로 설정합니다. Control Button1을 추가하고 Caption 속성을 "Screenshot"으로 설정하고 Label1 컨트롤을 추가하고 Caption 속성을 "Left: Top: Right: Bottom"으로 설정합니다. 컨트롤 Edit1을 입력하고 Text 속성을 "0:0:100:100"으로 설정하고, 컨트롤 Label2를 추가하고, Caption 속성을 "제어된 컴퓨터 IP 주소"로 설정하고, Text 속성을 "127.0.0"으로 설정합니다. 0.1";
구현 후 변수 정의 추가
const BufSize=2048;
var
RsltStream,TmpStream:TMemoryStream;
서버의 OnCreate 이벤트에 대한 코드를 추가합니다.
절차 TServer.FormCreate(Sender: TObject);
시작하다
RsltStream:=TMemoryStream.Create;
TmpStream:=TMemoryStream.Create;
끝;
클라이언트의 OnDestroy 이벤트에 대한 코드를 추가합니다.
절차 TServer.FormDestroy(Sender: TObject);
시작하다
RsltStream.Free;
TmpStream.Free;
끝;
컨트롤 Button1의 OnClick 이벤트에 대한 코드를 추가합니다.
절차 TServer.Button1Click(Sender: TObject);
var ReqCode:array[0..29] of char;ReqCodeStr:string;
시작하다
ReqCodeStr:='표시'+Edit1.Text;
StrpCopy(ReqCode,ReqCodeStr);
TmpStream.Clear;
RsltStream.Clear;
SUDP.RemoteHost:=Edit2.Text;
SUDP.SendBuffer(ReqCode,30);
끝;
컨트롤 SUDP의 OnDataReceived 이벤트에 대한 코드를 추가합니다.
프로시저 TServer.SUDPDataReceived(보내는 사람: TComponent;
NumberBytes: 정수, FromIP: 문자열);
var ReqCode:array[0..29] of char;ReqCodeStr:string;
시작하다
ReqCodeStr:='show'+Edit1.text;
StrpCopy(ReqCode,ReqCodeStr);
SUDP.ReadStream(TmpStream);
RsltStream.CopyFrom(TmpStream,NumberBytes);
if NumberBytes< BufSize then {데이터를 읽었습니다.}
시작하다
RsltStream.Position:=0;
Image1.Picture.Bitmap.LoadFromStream(RsltStream);
TmpStream.Clear;
RsltStream.Clear;
끝
또 다른
시작하다
TmpStream.Clear;
ReqCode:='표시';
SUDP.RemoteHost:=Edit2.Text;
SUDP.SendBuffer(ReqCode,30);
끝;
끝;
"C:VServerSvrUnit.pas"로 저장하고
"C:VServerVServer.dpr"을 입력하고 컴파일합니다.
---- 4. 테스트.
---- 1. 로컬 컴퓨터 테스트: 로컬 컴퓨터에서 Vserver.exe와 VClient.exe를 동시에 실행하고 프로그램의 기본 설정을 사용하여 스크린샷을 찍습니다. "제어판" - "네트워크" - "TCP/IP" - "IP 주소"를 확인하고, 프로그램의 "고객 IP 주소"를 이 주소로 설정하면 정상적으로 실행됩니다.
---- 2. 원격 테스트: 제어되는 시스템을 선택하고, VClient.exe를 실행하고, 다른 마스터 시스템을 선택하고, VServer.exe를 실행하고, "제어되는 시스템 IP 주소", 즉 Edit2의 내용을 제어되는 대로 설정합니다. 기기의 IP 주소를 입력하고 "스크린샷 찍기"를 선택합니다. 위에서는 원격 화면 캡처의 구현 방법을 간략하게 소개합니다. 주 제어 기계의 한 화면에서 동시에 여러 제어 기계를 모니터링하는 경우 독자가 스스로 개선할 수 있습니다. 위 프로그램은 Windows98 P2P 네트워크 및 Delphi 4.0에서 디버깅 및 전달되었습니다.