コンポーネント配列にしたclientsocketのイベントを使うには?

解決


エトー  2005-02-18 09:53:53  No: 13291

チャットプログラムを作っています。
LAN内で特定のサーバに依存しない複数 対 複数とのやり取りをするため、clientsocketを以下の手順でコンポーネント配列にしてみました。
----------------------------------------------------------
var sck : array[0..99] of TClientSocket;
rocedure TForm1.FormCreate(Sender: TObject);
var i : integer;
begin
    serversocket1.port := 23451;//ポート番号は変更できるようにしています。
    serversocket1.open;
    for i:=0 to cc do
    begin
      sck[cc] := TClientSocket.Create(self);
    end;
//略
end;
----------------------------------------------------------
このようにした時、sck[n]のOnReadイベントをやOnConnectイベントを実行させる為にはどのようにしたら良いですか?
また、これでは、使わないソケット、あるいは、ソケットが足りなくなるという問題が残ります。動的に(OnConnectイベントでソケットを1つ生成してオープンさせるといった風な)ソケットを追加する方法はありますか?
長くなってしまいましたが、ご教授お願いします。


エトー  2005-02-18 09:56:47  No: 13292

プログラムの7行目間違いです。
ccではなくて、99です。
おねがいします。


エトー  2005-02-18 10:27:50  No: 13293

プログラムの9行目間違いです。
ccではなくて、iです。
おねがいします。


jok  2005-02-18 23:50:36  No: 13294

動的にコンポーネントをつくり、イベントハンドラを割り当て、インスタンスを
管理する例を TLabel について示します。参考にしてください。

  public
    LabelList:TList;
    procedure LblClick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  i,index:integer;
  Lbl:TLabel;
begin
  LabelList := TList.Create;
  for i := 1 to 3 do
  begin
    Lbl := TLabel.Create(self);
    index := LabelList.Add(Lbl);
    Lbl.Parent := self;
    Lbl.Left := 150*index + 10;
    Lbl.Top  := 10;
    Lbl.Color := clYellow;
    Lbl.Caption := 'Label '+IntToStr(index);
    Lbl.Tag := index;
    Lbl.OnClick := LblClick;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  LabelList.Free;
end;

procedure TForm1.LblClick(Sender: TObject);
var
  index:integer;
begin
  index := TComponent(Sender).Tag;
  TLabel(LabelList[index]).Caption := 'You Clicked Me!';
end;


エトー  2005-02-19 00:45:34  No: 13295

ありがとうございます。
これは、フォーム生成時に無条件に3つのコンポーネントを生成していますね。
チャットをする場合、相手の数だけソケットを用意する必要があり、未知の数のソケットが必要になります。しかも、無駄にソケットがあるのは好ましくありません。
何か、イベントが起こる毎にコンポーネントを1つずつ追加するようなことは出来ないでしょうか。
これだと、相手が何人であろうが、ソケットは相手の数+1で済みます。
ご教授おねがいします。


jok  2005-02-19 01:04:20  No: 13296

いくつでもコンストラクタで生成していけばいいんでは?
OnCreate イベントハンドラのコードはその一例にすぎません


jok  2005-02-19 01:38:46  No: 13297

Button1Click でラベルのインスタンスをつくり、そのラベルのクリックで
削除できるようにしました。参考にしてください。

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    LabelList:TList;
    CountHistory:integer;
    procedure LblClick(Sender: TObject);
    procedure WMApp(var Msg:TMessage);message WM_APP;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  LabelList := TList.Create;
  CountHistory := 0;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  LabelList.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Lbl:TLabel;
begin
  Lbl := TLabel.Create(self);
  LabelList.Add(Lbl);
  Lbl.Parent := self;
  Lbl.Left := 150*(CountHistory mod 4) + 10;
  Lbl.Top  := 50*(CountHistory div 4)+ 10;
  Lbl.Color := clYellow;
  Lbl.Caption := 'Label '+IntToStr(CountHistory);
  Lbl.Tag := CountHistory;
  Lbl.OnClick := LblClick;
  Inc(CountHistory);
end;

procedure TForm1.LblClick(Sender: TObject);
var
  Lbl:TLabel;
  index:integer;
begin
  Lbl := TLabel(Sender);
  Lbl.Color := clLime;
  Lbl.Caption := 'This is '+IntToStr(Lbl.Tag);
  if MessageDlg('このラベルを削除しますか?',mtInformation,
                       [mbYes,mbNo],0) = mrYes then
  begin
    index := LabelList.IndexOf(pointer(Lbl));
    PostMessage(Handle,WM_APP,index,0);
  end;
end;

procedure TForm1.WMApp(var Msg:TMessage);
begin
  if Msg.WParam >= 0 then
  begin
    TLabel(LabelList[Msg.WParam]).Free;
    LabelList.Delete(Msg.WParam);
  end;
end;

end.


エトー  2005-02-19 02:51:32  No: 13298

このように出来るのでしたか、グローバル変数をうまく使えば出来そうです。
freeはコンポーネント配列を作ったときは必ずしなければなりませんか?


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

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






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