0

にデータ ポインタを追加したいのですが、 にも追加しTIdTCPServerたいと考えていTIdCustomTCPServerます。私はオーバーライドなどが苦手なので、これまでのところ:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdContext, IdBaseComponent, IdComponent,
  IdCustomTCPServer, IdTCPServer, Vcl.StdCtrls;

type
  TIdTcpServer = class(IdTcpServer.TIdTcpServer)
  public
    Data : Pointer;
end;

type
  TForm1 = class(TForm)
    IdTCPServer1: TIdTCPServer;
    Button1: TButton;
    procedure IdTCPServer1Connect(AContext: TIdContext);
    procedure IdTCPServer1Disconnect(AContext: TIdContext);
    procedure IdTCPServer1Execute(AContext: TIdContext);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  IdTCPServer1.Data := TObject (12345); // Just a test to fill the Data Pointer;
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
var
  ParentServer  : TIdCustomTCPServer;
  MyData        : Integer;
begin
 //
 ParentServer   := TIdServerContext(AContext).Server;
 // MyData      := Integer(ParentServer.Data);
end;

procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
begin
 //
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
 //
end;

end.

Data Pointer を OnConnect/OnDisconnect/etc のいずれかに戻すにはどうすればよいですか?

4

1 に答える 1

1

http://www.indyproject.org/docsite/html/!!MEMBEROVERVIEW_TIdTCPServer.htmlDataにはプロパティがありません- コードがコンパイルされて動作することを確認していますか?

そのようなプロパティがある場合は、変数をキャストして戻します。

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
var
  ParentServer  : TIdCustomTCPServer;
  MyData        : Integer;
begin
 //
 ParentServer   := TIdServerContext(AContext).Server;
 MyData      := Integer( (ParentServer as TIdTcpServer).Data);
end;

そうでない場合は、2 つのオプションがあります。1 つはサブクラス化です。つまり、クラスにプロパティを追加します。2 つ目は、外部データ ストレージを追加することです。

Unit IDWithData;
interface uses IdTCPServer;

type TIdTcpServer = class( IdTCPServer.TIdTcpServer )
      public
        var Data: Integer;
     end;
implementation
end.

このユニットをTForm1のユニット INTERFACE/USES リストの最後の位置に追加すると、出来上がりです! サーバーは、IDE からは見えなくなり、新しいフィールドを持つサブクラス化されたサーバーに置き換えられました。Dataしたがって、上記の型キャストは、この新しいが意図的に同じ名前の型を使用して機能します。

もちろん、必要に応じてフル スロットルにすることもできます。新しいクラスに独自の名前を追加し、新しいランタイム パッケージとデザインタイム パッケージを作成し、新しいサーバーを IDE VCL パレットに追加してインストールし、すべてのフォームでそれらを置き換えます。別の「適切な」解決策は、INDY ソースをフォークし、DATA 変数をごく普通のTIdCustomTCPServer型に追加してから、INDY のフォークされた独自のブランチを維持し続けることです。

より保守的なアプローチは、タイプのグローバル変数を作成するだけですTDictionary< TIdCustomTCPServer,Integer >- http://docwiki.embarcadero.com/CodeExamples/XE4/en/Generics_Collections_TDictionary_(Delphi)

次に、次のようになります。

procedure TForm1.Button1Click(Sender: TObject);
begin
  GlobalServerDictionary.AddOrSetValue( IdTCPServer1, 12345 ); 
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
var
  ParentServer  : TIdCustomTCPServer;
  MyData        : Integer;
begin
 ParentServer   := TIdServerContext(AContext).Server;
 MyData         := GlobalServerDictionary.Items[ ParentServer ];
end;   
于 2013-07-19T23:36:25.977 に答える