![]() |
Property nur Lesen kann nicht zugewisen werden
Hallo,
vllt. eine vllt etwas dumme Frage aber warum funktioniert dieses nicht im nur lesen Modus?
Delphi-Quellcode:
type
TUserStatus = procedure(Sender: TObject; Const ConnectedClients, ConnectedUsers: Integer) of Object; type TServerPA = Class(TWinControl) private FUserStatus: TUserStatus; public constructor Create(AOwner: TComponent; Log: TStrings = Nil; DebugMode: TDebugmode = dmFull); destructor Destroy(); procedure Open; procedure Close; function Active: Boolean; property OnUserStatus: TUserStatus read FUserstatus;// write FUserStatus; end; [...] // Übergabe der verbundenen Clients und der angemeldeten Benutzer if Assigned(FUserstatus) then FUserstatus(Self, FActiveConnections, Users.Count); Auf meiner Main Form.
Delphi-Quellcode:
Als Fehlermeldung erhalte ich dann:
procedure GetUserstatus(Sender: TObject; const ConnectedClients, ConnectesUsers: Integer);
[...] ServerPA := TServerPA.Create(Self, Memo1.Lines); ServerPA.OnUserStatus := GetUserStatus; Zitat:
Weiß da jemand eine Lösung? Es soll ja nur eine Leseeigenschaft sein. |
Re: Property nur Lesen kann nicht zugewisen werden
Hier
Delphi-Quellcode:
setzt du ja die Property.
ServerPA.OnUserStatus := GetUserStatus;
So sollte es gehen: ...
Delphi-Quellcode:
constructor Create(AOwner: TComponent; Log: TStrings = Nil; DebugMode: TDebugmode = dmFull; UserStatus: TUserStatus = Nil);
... FUserstatus := GetUserStatus; |
Re: Property nur Lesen kann nicht zugewisen werden
Hi,
wenn du das Property ausserhalb der Klasse zuweisen willst (Schreiben), so darf das Property nicht ReadOnly sein. Frank |
Re: Property nur Lesen kann nicht zugewisen werden
Sprich ich habe keine andere Wahl, auch das schrieben zuzulassen?
Das eine soll eine Komponente werden. Sobald sich ein Client verbindet, soll eben per Property übergeben werden, wie viele leute verbunden sind und wie viele wirklich angemeldet. |
Re: Property nur Lesen kann nicht zugewisen werden
Willst du deinem Object TServerPA beim Connect eines Clients die Werte übergeben oder abfragen?
Es ist wirklich schwer zu verstehen, was du erreichen möchtest. Cu, Frank |
Re: Property nur Lesen kann nicht zugewisen werden
Wenn sich ein Client verbindet, möchte ich auf meiner Main Form sehen wie viele da sind.
In dem Fall, würde ich sagen ich will die Werte übergeben. |
Re: Property nur Lesen kann nicht zugewisen werden
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mal ein Miniprojekt gebaut.
Meinst du es etwa so? Frank |
Re: Property nur Lesen kann nicht zugewisen werden
Nein, so nicht. Ich poste einfach mal mehr Code, da ich ein wenig in Eile bin :/
Delphi-Quellcode:
Der ist natürlich noch nicht fertig. Bisher ist nur gegeben, das ich eben die Property testen kann / will.
type
TDebugMode = (dmFull, dmNormal, dmMessages); TCOnnectionStatus = (csConnecting, csConnected, csDisconnected); TUserStatus = procedure(Sender: TObject; Const ConnectedClients, ConnectedUsers: Integer) of Object; type TServerPA = Class(TWinControl) private FSocket: TServerSocket; // Server Socket FCommand: Integer; // Commando des Datensatzes FArg: TArgList; // Argumentenliste eines ankommenden Datensatzes zur Weiterverarbeitung FLog: TStrings; // Log FDebugMode: TDebugMode; // Debug Mode zur Anzeige im Log FPingDelay: TTimer; // Timer für das Ping Pong FActiveConnections: Integer; // Anzahl der angemeldeten Clients Users: TUsers; // Benutzerliste FUserStatus: TUserStatus; procedure FSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure FSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); procedure FSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure FSocketClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure WritetoLog(const S: String); procedure FPingDelayTimer(Sender: TObject); public constructor Create(AOwner: TComponent; Log: TStrings = Nil; DebugMode: TDebugmode = dmFull); destructor Destroy(); procedure Open; procedure Close; function Active: Boolean; property OnUserStatus: TUserStatus read FUserstatus write FUserStatus; end; implementation { TServerPA } function TServerPA.Active: Boolean; begin // Ist der Socket noch aktiv? Result := FSocket.Active; end; procedure TServerPA.Close; begin // Server schliessen // Socket schliessen FSocket.Close; // Ping Timer abschalten FPingDelay.Enabled := False; // Log schreiben WritetoLog('Server geschlossen'); end; constructor TServerPA.Create(AOwner: TComponent; Log: TStrings; DebugMode: TDebugMode); begin // Original Constructor aufrufen inherited Create(AOwner); // Server Socket erstellen; Eriegnisseprozeduren übergeben FSocket := TServerSocket.Create(AOwner); FSocket.Port := CONNECTION_PORT; FSocket.OnClientConnect := FSocketClientConnect; FSocket.OnClientDisconnect := FSocketClientDisconnect; FSocket.OnClientRead := FSocketClientRead; FSocket.OnClientError := FSocketClientError; // Timer erstellen für das Ping Pong FPingDelay := TTimer.Create(Nil); FPingDelay.OnTimer := FPingDelayTimer; FPingDelay.Interval := 1000 * 30; FPingDelay.Enabled := False; // Benutzerliste erstellen Users := TUsers.Create(TUser); // Log FLog := Log; // Debug Mode setzen FDebugMode := DebugMode; end; destructor TServerPA.Destroy; begin // Socket freigeben FSocket.Free; // Original Destructor aufrufen inherited Destroy; end; procedure TServerPA.FPingDelayTimer(Sender: TObject); begin // WritetoLog('Ping Zeit'); end; procedure TServerPA.FSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin // Ereignis, wenn sich ein Client verbindet FActiveConnections := FSocket.Socket.ActiveConnections; WritetoLog('Client angemeldet'); // Übergabe der verbundenen Clients und der angemeldeten Benutzer if Assigned(FUserstatus) then FUserstatus(Self, FActiveConnections, Users.Count); end; procedure TServerPA.FSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin // Ereignis, wenn sich ein Client trennt FActiveConnections := FSocket.Socket.ActiveConnections -1; WritetoLog('Client getrennt'); // Übergabe der verbundenen Clients und der angemeldeten Benutzer if Assigned(FUserstatus) then FUserstatus(Self, FActiveConnections, Users.Count); end; procedure TServerPA.FSocketClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin // Ereignis, wenn ein Fehler auftritt WritetoLog('Es trat ein Fehler auf'); end; procedure TServerPA.FSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); begin // Ereignis, wenn Daten eines Client ankommen WritetoLog('Daten kommen an'); WritetoLog(Socket.ReceiveText); end; procedure TServerPA.Open; begin // Server starten // Socket öffnen FSocket.Open; // Ping Timer einschalten FPingDelay.Enabled := True; // Log schreiben WritetoLog('Server gestartet'); // Übergabe der verbundenen Clients und der angemeldeten Benutzer if Assigned(FUserstatus) then FUserstatus(Self, FActiveConnections, Users.Count); end; procedure TServerPA.WritetoLog(const S: String); var FS: String; begin FS := Format('[%s] %s', [DatetimetoStr(Now), S]); if Assigned(FLog) then FLog.Add( FS ); end; |
Re: Property nur Lesen kann nicht zugewisen werden
Wenn du dem Read-Only-Event (wozu eigentlich dann public?) etwas zuweisen willst, dann mach es im Konstruktor.
Delphi-Quellcode:
Aber dann ist die Deklaration als Property überflüssig und irreführend.
Constructor Create(AOwner: TComponent; aEvent : TUserStatus; Log: TStrings = Nil; DebugMode: TDebugmode = dmFull);
Begin ... FUserStatus := aEvent; End; |
Re: Property nur Lesen kann nicht zugewisen werden
Ich glaube da ist was falsch vertanden worden, oder ich habe was falsch verstanden.
Die Property ist Public, damit in einer Anderen Klasse das Event eintritt. Wenn sich die Anzahl der Verbindungen oder Benutzer verändert, will ich in den Fall meiner haupt Form das mitbekommen.
Delphi-Quellcode:
type
TMain_Form = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; StatusBar1: TStatusBar; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure GetUserstatus(Sender: TObject; const ConnectedClients, ConnectesUsers: Integer); private { Private declarations } ServerPA: TServerPA; public { Public declarations } end; var Main_Form: TMain_Form; implementation {$R *.dfm} procedure TMain_Form.FormCreate(Sender: TObject); begin ServerPA := TServerPA.Create(Self, Memo1.Lines); ServerPA.OnUserStatus := GetUserStatus; end; procedure TMain_Form.Button1Click(Sender: TObject); begin ServerPA.Open; end; procedure TMain_Form.Button2Click(Sender: TObject); begin ServerPA.Close; end; procedure TMain_Form.GetUserstatus(Sender: TObject; Const ConnectedClients, ConnectesUsers: Integer); begin statusbar1.Panels[1].Text := inttostr(ConnectedClients); statusbar1.Panels[3].Text := inttostr(ConnectesUsers); end; |
Re: Property nur Lesen kann nicht zugewisen werden
Zitat:
Delphi-Quellcode:
Somit muss er schreibbar sein, wie willst du ihm sonst was zuweisen. Und warum darf das Ding nun nur lesen sein? Was willst du damit bezwecken?
procedure TMain_Form.FormCreate(Sender: TObject);
begin ServerPA := TServerPA.Create(Self, Memo1.Lines); ServerPA.OnUserStatus := GetUserStatus; end; |
Re: Property nur Lesen kann nicht zugewisen werden
Hallo,
irgendwie habe ich das Gefühl, dass Du das Konzept der Ereignisse in Delphi noch nicht ganz verstanden hast. Ein Ereignis ist ja nichts anderes als eine Variable, die auf eine Methode zeigt. Diese wird dann aufgerufen, wenn das Ereignis auftritt. Wenn Du also Ereignisse nutzen willst, bleibt Dir eigentlich nichts anderes übrig, als diese beschreibbar zu machen. Wie soll sonst die Klasse wissen, welche Methode sie aufrufen soll, wenn das Ereignis eintritt? Die einzige sinnvolle Alternative hat alzaimar ja schon genannt. Gruß xaromz |
Re: Property nur Lesen kann nicht zugewisen werden
Die Anzahl der Verbindungen wird ja vom Socket geliefert.
Ich darf sie also nicht verändern. Darum dachte ich eigentlich das das Read eben reicht. |
Re: Property nur Lesen kann nicht zugewisen werden
ich hab das gleiche Gefühl wie xaromz.
Wenn der Nutzer keine Event-Methode zuweisen kann bekommt er auch nie das Event augelöst. Folglich kannst du dann gleich das Event weglassen. Wenn du aber willst das dieses Event ausgelöst werden kann so musst du auch die Möglichkeit bieten das jemand auf das Event reagieren darf und somit auch eine Ereignisprocedure zuweisen kann. Was du vor hast wäre als wölltest du verbieten das mit dem Button eine OnClick-Methode zuweisen kann. Dann würde man genau so wenig mitbekommen wenn der Button geklickt wird. |
Re: Property nur Lesen kann nicht zugewisen werden
Zitat:
Wenn du einem Button das OnClick zuweist: kannst du dort irgendwo den Click so verändern dass er nicht auftritt oder vllt. zum Tastendruck wird? |
Re: Property nur Lesen kann nicht zugewisen werden
...
und es macht auch keinen Sinn, mit einem Ereignis Zustandsmeldungen zu versenden. Für dein Property OnUserStatus reicht TNotifyEvent. Damit übergibst du deinen Server im Parameter Sender (siehe mein Beispiel). Dann sollte dein TServerPA 2 ReadOnly Propertys ConnectedUserCount und ConnectionCount besitzen. Damit kann ich mir in meiner Ereignisbehandlungsmethode die Infos über TServerPA(Sender).ConnectionCount etc. zur Anzeige im Form holen. Das Ereignis sollte nur über die Zustandsänderung benachrichtigen. Frank |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz