Delphi Programming / Object Pascal

[掲載 2022年06月17日] [更新 2022年06月17日] Delphi サンプルプログラム集 |
| 649_TTetheringManager を使用してアプリ間でデータを共有 |
| 動作確認等 |
Windows 10 ビルド 19043 Pro 64 bit + Delphi 10.4 Community VCL-32
Delphi XE6 以降用
|
 |
649_TTetheringManager.zip [7.1 MB] 2022年06月17日版 (EXE 同梱) |
| TTetheringManager を使用してアプリ間でデータを共有 |
|
他のアプリkへデータを送信したり、データを共有する方法として、WM_COPYDATA メッセージによる送信や、共有メモリを使用する方法があります。
本ページのサンプルは、テザリング用の TTetheringManager と TTetheringAppProfile コンポーネントを使用する方法です。これらのコンポーネントは、Delphi XE6 で実装されました。 |
|
TTetheringManager と TTetheringAppProfile コンポーネントを使用する方法では、これらのコンポーネントを、データを提供する側と受け取る側の両方のプロジェクトのフォームに配置して使用します。
これらのコンポーネントは、コンポーネントパレットの [Tethering] タブにあります。 |
| 01_共有リソースとしてデータを提供するプログラムを作成 |
共有データを提供する側のプログラムを作成します。このプログラムは、本ページの全てのサンプルの動作確認に使用します。
本プログラムでは、共有データとして、Integer 型の整数値と TMemoryStream を実装します。Integer 型の整数は、TPanel の背景色の設定に使用します。TMemroyStream には TBitmap の画像データを格納します。 |
 |
図1
設計時の画面 |
| フォーム上の TTetheringAppProfile コンポーネントを選択して、オブジェクトインスペクタでプロパティを設定します。下図の説明を参考にしてください。
Group の名前は任意です。この名前のプログラムだけが本プログラムが提供するデータを利用できます。Manager は、リストから TTetheringManager コンポを選択します。
Resouces はリソースのコレクションです。入力部分をダブルクリックするか、[...] をクリックして、リソースの編集ダイアログを表示します。
|
 |
図2
TTetheringAppProfile コンポーネントのオブジェクトインスペクタ
- Group (任意の文字列)
ここでは CommResTest
- Manager
TTetheringManager コンポをリストから選択
- Resouces
入力部をダブルクリック。
または、[...] をクリック
|
| リソースの編集ダイアログを表示したら、[新規追加] ボタンをクリックしてリソースを追加します。本サンプルではリソースを 2 つ使用しますから、2 回クリックします。
最初のリソースを選択してプロパティを下図のように設定します。
共有データとしてデータを提供する場合は Kind プロパティを Shared にします。
Name はリソース名です。この名前でリソースにアクセスします。
Integer 等の標準データの場合は、ResType を Data にします。 |
 |
図3
1 番目のリソースの設定
- Kind
Shared (デフォルト) をリストから選択
- Name (任意の文字列)
ここでは color
- ResTypea
リストから Data (デフォルト) を選択 |
| 2 番目のリソースを選択してプロパティを下図のように設定します。標準データ型(Boolean, Integer, Int64, Single, Double, String) 以外の場合は、ResType の値を Stream にします。 |
 |
図4
2 番目のリソースの設定
- Kind
Shared (デフォルト) をリストから選択
- Name (任意の文字列)
ここでは image
- ResTypea
リストから Stream を選択
|
| フォームのユニットのコードを以下のようにします。コンパイルして EXE を作成します。
本ページのサンプルでは、このプログラムを共有データの提供 (送信) 専用としています。データの提供 (送信) か受信かは、リソースの Kind プロパティで決まります。Kind プロパティの値を Mirror にすれは、他のアプリからのデータ受信用のリソースになります。提供 (送信) と受信用のリソースを実装すれば、同じ Group のアプリ間での双方向通信が可能になります。
同じリソース名のリソースを、提供 (送信) と受信兼用にはできません。 |
リスト1
共有リソースとしてデータを提供する側のプグラムのコード |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, IPPeerServer,
System.Tether.Manager, System.Tether.AppProfile, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
TetheringManager1: TTetheringManager;
TetheringAppProfile1: TTetheringAppProfile;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Panel1: TPanel;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// 接続処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
TetheringManager1.AutoConnect(3000);
end;
//=============================================================================
// [color 値のセット]
// リソースの型は Integer
// このボタンをクリックしてから他のアプリでデータを取得する
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LColor : Integer;
begin
LColor := RGB(Random(255), Random(255), Random(255));
Panel1.ParentBackground := False;
Panel1.Color := LColor;
TetheringAppProfile1.Resources.FindByName('color').Value := LColor;
end;
//=============================================================================
// [画像をセット]
// このボタンをクリックしてから他のアプリでデータを取得する
//
// 標準データ型(Boolean, Integer, Int64, Single, Double, String) 以外は
// メモリストリームを使用する
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LStream : TMemoryStream;
lBitmap : TBitmap;
begin
Image1.Picture.Assign(nil);
LStream := TMemoryStream.Create;
lBitmap := TBitmap.Create;
try
LStream.Clear;
lBitmap.LoadFromFile('HANDSHAK.BMP');
lBitmap.SaveToStream(LStream);
Image1.Canvas.Draw(0, 0, lBitmap);
TetheringAppProfile1.Resources.FindByName('image').Value := LStream;
finally
FreeAndNil(lBitmap);
FreeAndNil(LStream);
end;
end;
//=============================================================================
// [別画像をセット]
// このボタンをクリックしてから他のアプリでデータを取得する
//
// 標準データ型(Boolean, Integer, Int64, Single, Double, String) 以外は
// メモリストリームを使用する
//=============================================================================
procedure TForm1.Button3Click(Sender: TObject);
var
LStream : TMemoryStream;
lBitmap : TBitmap;
begin
Image1.Picture.Assign(nil);
LStream := TMemoryStream.Create;
lBitmap := TBitmap.Create;
try
LStream.Clear;
lBitmap.LoadFromFile('CHEMICAL.BMP');
lBitmap.SaveToStream(LStream);
Image1.Canvas.Draw(0, 0, lBitmap);
TetheringAppProfile1.Resources.FindByName('image').Value := LStream;
finally
FreeAndNil(lBitmap);
FreeAndNil(LStream);
end;
end;
end.
| 02_Integer 型の共有リソースデータを取得するプログラム |
|
Integer 型のリソースの値を受け取って処理するサンプルです。
本サンプルでは、Integer 型の値を TPanel の背景色の値として使用します。
フォームに TTetheringManager と TTetheringAppProfile を配置します。TTetheringAppProfile のプロパティを上のサンプルと同じにします。リソースを下図のように設定します。
共有データを受け取る側なので、Kind プロパティを Mirror にします。Name は、受け取るデータのリソース名です。 |
 |
図5
リソースの設定
- Kind
リストから Mirror を選択
- Name
リソース名。color にする
- ResType
リストから Data を選択
|
[備考]
データの提供側と受け取る側でリソースのプロパティの値が異なるのは Kind プロパティだけです。このことから、最初のサンプルのフォームから、TTetheringManager と TTetheringAppProfile コンポーネントをコピーして使用する方が手っ取り早いと言えます。そうすれば、Kind プロパティの値を変更するだけの操作となります。 |
図の下がサンプルのコードです。コンパイルして EXE を作成します。
最初のサンプルの EXE を起動して [color 値をセット] をクリックします。次に、本サンプルの EXE を起動します。接続には、わずかですが時間がかかるので、一呼吸おいて [color 値を取得] ボタンをクリックします。本プログラムの TPanel の背景色が、共有データ提供元の TPanel の背景色と同じになることが確認できます。 |
 |
図6
実行結果
- 以下の順でクリック
[color 値をセット]
[color 値を取得]
|
リスト2
Integer 型の共有リソースデータを取得する |
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, IPPeerServer,
System.Tether.Manager, System.Tether.AppProfile, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
TetheringManager1: TTetheringManager;
TetheringAppProfile1: TTetheringAppProfile;
Button1: TButton;
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// 接続処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
TetheringManager1.AutoConnect(3000);
end;
//=============================================================================
// [取得]
// リソースの型は Integer
// リソース提供側でリソースにデータをセットしてからこのボタンをクリックする
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LColor : Integer;
begin
if TetheringManager1.RemoteProfiles.Count = 0 then begin
// 接続されていない場合
Exit;
end;
LColor := TetheringAppProfile1.Resources.FindByName('color').Value.AsInteger;
Panel1.ParentBackground := False;
Panel1.Color := LColor;
end;
end.
| 03_画像の共有リソースデータを取得するプログラム |
|
TBitmap のデータを取得して処理するサンプルです。
共有データの提供側では、TBitmap のデータをメモリストリームに格納しています。このメモリストリームから TBitmap のデータを取り出します。
フォームに TTetheringManager と TTetheringAppProfile を配置します。TTetheringAppProfile のプロパティを最初のサンプルと同じにします。リソースを下図のように設定します。
共有データを受け取る側なので、Kind プロパティを Mirror にします。Name は、受け取るデータのリソース名です。 |
 |
図7
リソースの設定
- Kind
リストから Mirror を選択
- Name
リソース名。image にする
- ResType
リストから Stream を選択
|
|
図の下がサンプルのコードです。コンパイルして EXE を作成します。
最初のサンプルの EXE を起動して [画像をセット] をクリックします。次に、本サンプルの EXE を起動します。接続には、わずかですが時間がかかるので、一呼吸おいて [画像を取得] ボタンをクリックします。共有データ提供元の 画像と同じ画像が TImage に描画できることが確認できます。 |
 |
図8
実行画面
|
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, IPPeerServer,
System.Tether.Manager, System.Tether.AppProfile, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
TetheringManager1: TTetheringManager;
TetheringAppProfile1: TTetheringAppProfile;
Button1: TButton;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// 接続処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
TetheringManager1.AutoConnect(3000);
end;
//=============================================================================
// [取得]
// データはメモリストリーム
// リソース提供側でリソースにデータをセットしてからこのボタンをクリックする
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LStream : TMemoryStream;
lBitmap : TBitmap;
begin
Image1.Picture.Assign(nil);
if TetheringManager1.RemoteProfiles.Count = 0 then begin
// 接続されていない場合
Exit;
end;
LStream := TMemoryStream.Create;
lBitmap := TBitmap.Create;
try
if TetheringAppProfile1.Resources.FindByName('image').Value.AsStream = nil
then Exit;
LStream.LoadFromStream
(TetheringAppProfile1.Resources.FindByName('image').Value.AsStream);
LStream.Position := 0;
lBitmap.LoadFromStream(LStream);
Image1.Canvas.Draw(0, 0, lBitmap);
finally
FreeAndNil(lBitmap);
FreeAndNil(LStream)
end;
end;
end.
| 04_リソースのイベントを使用して共有データを自動受信 |
共有データの提供元でテータを設定したら、自動的にそのデータを受信するサンプルです。
ソースのイベントを利用します。
Integer 型のデータ取得のサンプルのリソースに以下のイベントを追加します。リソース名が color のリソースが対象です。ただし、本サンプルでは、元のサンプルから Button1 クリックのコードを削除しています。 |
 |
図9
リソースにイベントを追加 |
|
下図が実行結果です。
共有データの提供側で [color 値をセット] をクリックすると、本サンプルの TPanel の背景色も変わり、同じ色になります。 |
 |
図10
実行画面 |
リスト4
リソースのイベントを使用して共有データを自動受信 |
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IPPeerClient, IPPeerServer,
System.Tether.Manager, System.Tether.AppProfile, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm1 = class(TForm)
TetheringManager1: TTetheringManager;
TetheringAppProfile1: TTetheringAppProfile;
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure TetheringAppProfile1Resources0ResourceReceived(
const Sender: TObject; const AResource: TRemoteResource);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// 接続処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
TetheringManager1.AutoConnect(3000);
end;
//=============================================================================
// 共有リソースの提供側でリソースに値をセットすると発生するイベント
// ここでは、リソース名 color の値が変更された時を検出
//
// このイベントはリソース単位で発生する
// このイベントを各リソースで共有すればリソースごとの処理が可能
//=============================================================================
procedure TForm1.TetheringAppProfile1Resources0ResourceReceived(
const Sender: TObject; const AResource: TRemoteResource);
var
LColor : Integer;
begin
if AResource.Name = 'color' then begin
LColor := AResource.Value.AsInteger;
Panel1.ParentBackground := False;
Panel1.Color := LColor;
end;
end;
end.
| 05_[ Windows セキュリティの重要な警告 ] のダイアログ |
本ページのサンプルの EXE を起動すると、下図のセキュリティの重要な警告のダイアログが現れます。今回は、[プライベートネットワーク ...] だけをチェックしてアクセスを許可しました。
これでファイアウォールが無効になって、次回からは下図のダイアログは現れません。 |
 |
図11
|
添付の plSetAppFirewallState.exe を使用すると、ファイアウォールを有効にして、上のダイアログが現れるようにすることができます。
[EXE Path] の入力欄に EXE のフルパスを入力して、[Firewall ON] をクリックします。
[Application LIst] をクリックすると、ファイアウォールの設定ダイアログを表示します。そのダイアログで設定することもできます。[設定の変更] をクリックしてからプログラムを選択して [削除] ボタンをクリックします。EXE のフルパスは、[詳細] ボタンをクリックすると確認できます。
ファイアウォールを有効 (ON) にした EXE は、このリストから削除されています。 |
 |
図12
ファイアウォールの設定
|
下図の左のフォームは、最初のサンプルを起動して [別の画像をセット] しています。右のフォームは、バーチャルマシンの Windows 7 で、画像を取得するサンプルを起動して取得しています。
このように、上のダイアログでファイアウォールを無効にすれば、LAN 上の別のコンピュータのアプリにもデータを送信することができます。 |
 |
図13
|
本ページのサンプルのプロジェクトのコンパイルを開始すると、下図の Socket エラーが発生することがあります。これは、他のサンプルの EXE が起動している時に発生します。
この場合は、[継続] をクリックしてコンパイルをつ続けます。このダイアログは、複数回現れます。 |
 |
図14 |
|