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 |
|