他のプログラムにデータを渡したい


ジャイアントボンビー  2005-09-06 19:48:21  No: 17427

WindowsXP,Delphi7 でアプリケーションを作成しています。

A,B2つのプログラムを作成します。
Aを起動し、AからBのプログラムを起動する場合と
Bを直接起動する場合があります。

Bを起動する場合はデフォルト状態でフォームが起動し、
Aから起動させる場合はデフォルトのデータを書き換えて
起動したいのです。

Aから、Bを起動する場合に引き渡したいデータは主に
Aの内部で使用している文字列の Record です。

Aから起動する場合に ShellExecute を使用して
コマンドラインで渡すといった手法しか思いつかないのですが、
データが複数あるのと文字列リストなどもあり、
しかも、コマンドラインで大量のデータを遅れなかったような
記憶があり、渡せるのかどうかわからなかったので、
まず最初にみなさんに、質問させていただきました。
(実行もせずに質問してどうもすみません)

複数のしかも改行コードなどが入った文字列をコマンドライン用に
一連の文字列として変換して渡すにしても、変換方法が
ちょっとよくわからない部分があり、
もっと、わかりやすい方法などがありましたら教えてください


deldel  2005-09-06 20:06:36  No: 17428

ATOM  とか、メールスロットがいいかも。
http://www.kumei.ne.jp/c_lang/sdk2/sdk_157.htm
http://hp.vector.co.jp/authors/VA007941/program/no2146.html


にしの  2005-09-06 20:12:34  No: 17429

WM_COPYDATAメッセージを使うか、共有メモリでデータをやりとりすればよいかと思います。
http://www.wwlnk.com/boheme/delphi/tips/tec1630.htm
http://forum.nifty.com/fdelphi/faq/00233.htm


ジャイアントボンビー  2005-09-06 21:31:35  No: 17430

deldel さん  にしのさん
どうもありがとうございます。

現在、にしのさんの複数のプロセスでメモリを共有する方法
http://forum.nifty.com/fdelphi/faq/00233.htm
を作ってみました。
以下のエラーが発生します。
引数に間違いがあるのでしょうが、
修正方法がわかりません。

コンポーネントの中身のソースを見てみると
Create(ResStringRec: PResStringRec; const FileName: string);
となっているので、[ResStringRec]が足りないのでしょうが
何を入れればよいのかわかりません?
ソース内にはこれに該当する変数らしきものもみあたりませんし、
どうすればよいのでしょうか?

[エラー] ComMem.pas(36): 'String' と 'PResStringRec' には互換性がありません


deldel  2005-09-06 21:54:17  No: 17431

しつこいですが^^;、資料が見つかりましたので、載せますね。

アトムを使用したアプリ間の通信の例です。

サーバーアプリ上のボタンをクリックすると、エディットボックスの内容が
クライアントアプリに送信されます。

クライアントアプリのフォームのキャプションを

クライアント

として下さい。

サーバーアプリのソースコード========================================

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  WM_MYMSG = WM_USER + 100;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  H: THandle;
  A: TAtom;
begin
  H := FindWindow(nil, 'クライアント');
  A := GlobalAddAtom(PChar(Edit1.Text));
  SendMessage(H, WM_MYMSG, A, 0);
  GlobalDeleteAtom(A);
end;

end.

クライアントアプリのソースコード====================================

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  WM_MYMSG = WM_USER + 100;

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private 宣言 }
    procedure WMUserMessage(var Msg: TMessage); message WM_MYMSG;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMUserMessage(var Msg: TMessage);
var
  s: PChar;
begin
  s := StrAlloc(255);
  GlobalGetAtomName(Msg.wParam, PChar(s), 255);
  Label1.Caption := s;
  StrDispose(s);
end;

end.


pdot  2005-09-06 22:49:05  No: 17432

引き渡すのがBの起動時だけでよいのなら
外部ファイルを使用すれば簡単だと思うけど・・・
そうでなければこのレス無視してください。


ジャイアントボンビー  2005-09-06 23:05:49  No: 17433

通常はBのみで起動して使用しますが、
Aアプリケーションの中からもBを起動して利用できるものを
作成しています。

通常A、Bのアプリケーションを作成し、
DLLでCを作成し、
AからもB(DLL呼び出しのみ)からも
DLLを呼び出すようにしてもよかったのですが、
ひとつのアプリケーション(B)を起動するのに複数のファイルを
インストールするのを避けたかったのです。
(もちろん、BがインストールされていなければAからBは
起動できないというのは仕様になります。)

つまり、外部ファイルと言う概念も最初から
候補からはずしました。
ある程度PCのわかるレベルのユーザーであればよいのですが、
エラーメッセージに「外部ファイルがありません」とか
「DLLがありません」と表示しても理解されないからです。
ただ、プログラムがあるか、ないかは判断してくれます。
構造上シンプルにするため、実行ファイルひとつでなるべく
起動できるようにしたかったのです。


pdot  2005-09-07 03:22:58  No: 17434

>ある程度PCのわかるレベルのユーザーであればよいのですが、
>エラーメッセージに「外部ファイルがありません」とか
>「DLLがありません」と表示しても理解されないからです。

AからBを起動する時にAで外部ファイル(一時ファイル)を作成してからBを起動すれば「外部ファイルがありません」とはならないと思いますが。


pdot  2005-09-07 03:28:22  No: 17435

ついでに
>「DLLがありません」

これもDLLそのものをプログラムのリソースに格納しておいて
プログラムが必要な特に自分のリソースから書き出してDLLをダイナミックロードするようにすれば「ある程度PCのわからないレベルのユーザー」でも問題はでません。


ママん  2005-09-07 05:32:07  No: 17436

>pdot
通信手段というのは色々あって、それぞれメリットデメリットがあります。
ファイル経由を例に取ると、
デメリット:
高速な通信に向かない、書込み禁止メディア上では使えない、ハードディスクがカリカリ言う
メリット:強制終了に強い、巨大なデータが扱える
なんてのがぱっとあります。
まぁ質問者が欲しがってる転送方式じゃないみたいですね。

DLLについても同じ、DLLでしかできないこと+ファイルの移動や削除が行われる可能性がある+ファイル数を減らしたいとき位じゃないとなかなか、リソースに含めていちいち吐き出したりなんてしないと思いますよ。
しかも配布する場合、かってに実行ファイルが不明なファイルを出し入れするのを極端に嫌う人は結構います。


Mr.XRAY  URL  2005-09-07 07:15:53  No: 17437

既に多くのサンプルのリンクが紹介されていますが,私も...
ちょっと情報過多になってしまうかもしれませんね.

http://homepage2.nifty.com/Mr_XRAY/Halbow/Notes/N012.html
http://homepage2.nifty.com/Mr_XRAY/Delphi/plSamples/T_SendText.htm

AからBを起動するときは,まずBを起動を検出してからデータを送れば
いいのではないか思います.Recordなら,Record体のポインタを使用します.


pdot  2005-09-07 09:21:05  No: 17438

>ママん
話の流れを読みましょうよ・・・

>通信手段というのは色々あって、それぞれメリットデメリットがあります。
>ファイル経由を例に取ると、
>デメリット:
>高速な通信に向かない、書込み禁止メディア上では使えない、ハードディスがカリカリ言う
>メリット:強制終了に強い、巨大なデータが扱える

その他のやり方についてのメリット・デメリットも記述していただけたらよかったのですが
「引き渡すのがBの起動時だけで」という前提なら高速な通信とかは関係ないと思いますが。
「書込み禁止メディア・・・」普通のWindowsは書き込み禁止のメディアだけでは動作しません。必ず読み書き可能なディスクは存在します。
しかし無理やりな反論ですね。

>DLLについても同じ・・・
DLLが良いとはいっていません。質問者がDLLの話を持ち出したのでそれについてのエラーの回避方法を例に示したに過ぎません。

「Bの起動時だけ」というのを限定すればファイルでのやり取りは簡便でよいと思います。
そうでなければ、他の方のやり方のほうが応用がききますね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加