8

Ok, I'm sorry if this is a little bit confusing but I don't know how to explain it better. I have a chat form that is shown after the user has previously authenticated in TLoginForm.

User logged in then show the chatForm:

with TChatForm.Create(Application) do
begin
    Show;
end;

My problem is , how can I pass the username to the chatForm so I can use it as nickname in the chat, considering the fact that the form automatically connects to server OnShow, so I'll be needing the username sent already.

I'm new to delphi so if there's any mistake in my code, kindly excuse me.

Eduard
  • 3,395
  • 8
  • 37
  • 62

2 Answers2

12

If the username should be fixed during the entire lifetime of the object then it should be passed in to the constructor. The benefit is that it's not possible to misuse the class and forget to assign the username.

Declare a constructor that receives the extra information in parameters:

type
  TMyForm = class(TForm)
  private
    FUserName: string;
  public
    constructor Create(AOwner: TComponent; 
        const UserName: string);
  end;

constructor TMyForm.Create(AOwner: TComponent; 
        const UserName: string);
begin
  inherited Create(AOwner);
  FUserName := UserName;
end;

Create the form like this:

MyForm := TMyForm.Create(Application, UserName);
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I am trying to solve it your way, though, how should I set FormCreate procedure ? Setting it to procedure FormCreate(Sender: TObject; const username : string); returns an incompatibility if i try to link the procedure to the event OnCreate – Eduard Dec 25 '12 at 19:10
  • Don't set the `OnCreate` event at all. Use a `constructor` exactly as per the code in the answer. – David Heffernan Dec 25 '12 at 19:16
  • +1 IMHO this is the better approach based on the OP's question. –  Dec 25 '12 at 19:17
  • 1
    And add the `reintroduce` keyword at the end of the contructor line to suppress the hide of non virtual method warning. – Marus Gradinaru Mar 30 '22 at 12:46
4

Add a public method to your chatform.

with TChatForm.Create(Application) do
begin
  PassUserName(FUsername);
  Show;
end;

procedure TChatForm.PassUserName(const aUsername: string);
begin
  Caption := 'You can now chat: '+ aUsername;
end;

This allows you to pass whatever you want into your Chat Form without changing existing public methods by simply adding new ones.
Example without using "with" or FUsername to address concerns:

frmChat := TChatForm.Create(Application);
frmChat.Nickname := aUsername;
frmChat.Show;

TChatForm = class(TForm)
private
  FUsername : string;

  procedure SetNickName(const Value: string);
  function GetNickName: string;
public
  property NickName: string read GetNickName write SetNickName;
end;

procedure TChatForm.SetNickName(const Value: string);
begin
  FUsername := Value;
end;
function TChatForm.GetNickName: string;
begin
  Result := FUsername;
end;
SteB
  • 1,999
  • 4
  • 32
  • 57
  • Both answers solved my problem, but I marked this one as accepted because it opened my mind about how to use forms procedures more. – Eduard Dec 25 '12 at 18:55
  • 2
    The correct name for the function is SetUserName. And be careful of the with. That will cause you grief if your form has a field named FUserName. Also think what happens if that SetUserName method is called after the connection has been made. Do you support such usage? – David Heffernan Dec 25 '12 at 18:57
  • @DavidHeffernan, completely agree about the with (it was in the question), normally I'd have a public property called Username and SetUsername would be a private setter, I also wanted to keep the answer simple and demonstrate parameter passing (FUsername would be private by convention & so only belong to the calling form) – SteB Dec 25 '12 at 19:11
  • Changed the accepted answer due the clarifications made by David. But still many thanks for SteB too. – Eduard Dec 25 '12 at 19:23