Delphi を使用したリモート画面キャプチャの実装
山東ジュリ有限公司CADセンター
タン・ゲチン
---- ネットワーク管理では、リモート コンピュータの画面を監視してオンライン コンピュータの使用状況を把握する必要がある場合があります。この機能を実現するソフトウェアは数多く市販されており、遠隔操作が可能なソフトウェアもありますが、リモートコンピュータの画面領域のサイズや位置を指定できないため、複数の監視を行うことができないなど、柔軟性に欠けます。同時に 1 つの画面に表示されます。実際、Delphi を使用して柔軟なリモート画面キャプチャ ツールをコンパイルできます。これについては、次のように簡単に説明します。
---- 1. ソフトウェアおよびハードウェアの要件。
---- Windows95/98のピアツーピアネットワークでは、監視に使用するコンピュータ(以下、マスタコンピュータ)と監視されるコンピュータ(以下、被制御コンピュータ)にTCP/IPが搭載されている必要があります。プロトコルが正しく設定されています。ネットワークがない場合は、コンピューター上でデバッグすることもできます。
---- 2.実装方法。
---- 制御対象マシンにインストールされる VClient.exe と、主制御マシンにインストールされる VServer.exe の 2 つのアプリケーションを準備します。 VServer.exeは、監視対象となる被制御マシンのIPアドレスと、被制御マシンの画面上でキャプチャする領域のサイズと位置を指定し、VClient.exeに対して画面キャプチャ指示を発行します。 .exe コンピュータ画面上の指定された領域を選択し、データ ストリームを生成してホスト コンピュータに送り返し、キャプチャされた領域の BMP イメージをホスト コンピュータに表示します。上記のプロセスから、この方法には 2 つの鍵があることがわかります。1 つは制御対象マシンの画面をキャプチャする方法、もう 1 つは TCP/IP プロトコルを介して 2 台のコンピュータ間でデータを送信する方法です。
---- UDP(User Datagram PROtocol、ユーザー メッセージ プロトコルの意味)は、インターネットで広く使用されている通信プロトコルの 1 つです。 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;{各データ送信時のバッファサイズ}
変数
BmpStream:TMemoryStream;
LeftSize:Longint;{各データを送信した後に残っているバイト数}
クライアントの OnCreate イベントのコードを追加します。
プロシージャ TClient.FormCreate(送信者: TObject);
始める
BmpStream:=TMemoryStream.Create;
終わり;
クライアントの OnDestroy イベントのコードを追加します。
プロシージャ TClient.FormDestroy(送信者: TObject);
始める
BmpStream.無料。
終わり;
コントロール CUDP の OnDataReceived イベントのコードを追加します。
プロシージャ TClient.CUDPDataReceived(送信者: TComponent;
NumberBytes: 整数; FromIP: 文字列);
変数
CtrlCode:配列[0..29] の文字;
Buf:array[0..BufSize-1] の char;
TmpStr: 文字列;
SendSize、LeftPos、TopPos、RightPos、BottomPos:整数;
始める
CUDP.ReadBuffer(CtrlCode,NumberBytes);{制御コードの読み取り}
if CtrlCode[0]+CtrlCode[1]+CtrlCode[2]+CtrlCode[3]='表示' then
begin {制御コードの最初の 4 桁は「show」で、ホスト コンピュータが画面キャプチャ コマンドを発行したことを示します}
if BmpStream.Size=0 then {データを送信できません。データを生成するにはスクリーンショットを撮る必要があります}
始める
TmpStr:=StrPas(CtrlCode);
TmpStr:=Copy(TmpStr,5,Length(TmpStr)-4);
LeftPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)
-Pos(':',TmpStr));
TopPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
TmpStr:=Copy(TmpStr,Pos(':',TmpStr)+1,Length(TmpStr)-
Pos(':',TmpStr));
RightPos:=StrToInt(Copy(TmpStr,1,Pos(':',TmpStr)-1));
BottomPos:=StrToInt(Copy(TmpStr,Pos(':',TmpStr
)+1,Length(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,
RightPos、BottomPos:整数);
変数
RectWidth、RectHeight:整数;
ソースDC、DestDC、バンドル:整数;
ビットマップ:TBitmap;
始める
RectWidth:=RightPos-LeftPos;
RectHeight:=BottomPos-TopPos;
SourceDC:=CreateDC('DISPLAY',',',nil);
DestDC:=CreateCompatibilityDC(SourceDC);
Bhandle:=CreateCompatibilityBitmap(SourceDC,
RectWidth,RectHeight);
SelectObject(DestDC,Bhandle);
BitBlt(DestDC,0,0,RectWidth,RectHeight,SourceDC,
LeftPos、TopPos、SRCCOPY);
ビットマップ:=TBitmap.Create;
Bitmap.Handle:=BHandle;
BitMap.SaveToStream(BmpStream);
BmpStream.Position:=0;
LeftSize:=BmpStream.Size;
ビットマップ。無料。
削除DC(DestDC);
ReleaseDC(バンドル,ソースDC);
終わり;
「C:VClientClnUnit.pas」および「C:VClientVClient.dpr」として保存します。
そしてコンパイルします。
----2 番目のステップは、VServer.exe ファイルをコンパイルすることです。新しい Delphi プロジェクトを作成し、フォームの Name プロパティを「Server」に設定します。 TNMUDP コントロールを追加し、Name 属性を "SUDP" に設定し、LocalPort 属性を "2222" に設定します。コントロール SUDP がホスト コンピューターの 2222 ポートを監視し、データがポートに送信されると、次の OnDataReceived イベントをトリガーします。制御 SUDP が RemotePort 属性を「1111」に設定すると、制御 SUDP がデータを送信すると、データは被制御マシンの 1111 ポートに送信されます。 Image1 コントロールを追加し、Align プロパティを「alClient」に設定します。Button1 コントロールを追加し、Caption プロパティを「Screenshot」に設定します。Label1 コントロールを追加し、Caption プロパティを「Left: Top: Right: Bottom」に設定します。コントロール Edit1 を入力し、Text プロパティを「0:0:100:100」に設定します。コントロール Label2 を追加し、Caption プロパティを「制御対象マシンの IP アドレス」に設定します。コントロール Edit2 を追加し、Text プロパティを「127.0.0.1」に設定します。
実装後に変数定義を追加する
const BufSize=2048;
変数
RsltStream、TmpStream:TMemoryStream;
サーバーの OnCreate イベントのコードを追加します。
プロシージャ TServer.FormCreate(送信者: TObject);
始める
RsltStream:=TMemoryStream.Create;
TmpStream:=TMemoryStream.Create;
終わり;
クライアントの OnDestroy イベントのコードを追加します。
プロシージャ TServer.FormDestroy(送信者: TObject);
始める
RsltStream.Free;
TmpStream.Free;
終わり;
コントロール Button1 の OnClick イベントのコードを追加します。
プロシージャ TServer.Button1Click(送信者: TObject);
var ReqCode:array[0..29] of char;ReqCodeStr:string;
始める
ReqCodeStr:='show'+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 ピアツーピア ネットワークと Delphi 4.0 で渡されました。