在Delphi SDI中创建新表单时传递参数

8

抱歉如果我的表述有点混乱,我不知道该如何更好地解释。在TLoginForm中用户进行身份验证后,将显示聊天表单。

用户登录后显示聊天表单:

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

我的问题是,我如何将用户名传递给聊天表单,以便在聊天中使用它作为昵称,考虑到表单在OnShow时自动连接到服务器,所以我需要提前发送用户名。

我是Delphi的新手,如果我的代码有任何错误,请多多包涵。

2个回答

12

如果用户名在对象整个生命周期中都应该保持不变,则应在构造函数中传递它。好处是可以避免误用类并忘记分配用户名。

声明一个构造函数,通过参数接收额外的信息:

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;
创建表单的方法如下所示:
MyForm := TMyForm.Create(Application, UserName);

我正在尝试按照您的方式解决它,但是我应该如何设置FormCreate过程?将其设置为procedure FormCreate(Sender: TObject; const username: string);如果我尝试将该过程链接到OnCreate事件,则会返回不兼容性。 - Eduard
不要设置OnCreate事件。使用与答案中代码完全相同的构造函数 - David Heffernan
在我看来,这是基于OP的问题更好的方法。 - user497849
1
在构造函数行末添加 reintroduce 关键字以抑制非虚方法警告的隐藏。 - Marus Gradinaru

4
在您的聊天表单中添加一个公共方法。
with TChatForm.Create(Application) do
begin
  PassUserName(FUsername);
  Show;
end;

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

这使得你可以通过添加新的方法而不是更改现有的公共方法来在聊天表单中传递任何想要的内容。 例如,不使用“with”或FUsername来解决问题的示例:
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;

两个答案都解决了我的问题,但我选择标记这个答案是因为它让我对如何更好地使用表单程序有了更深入的理解。 - Eduard
2
函数的正确名称为SetUserName。并且要小心使用with关键字。如果表单中有一个名为FUserName的字段,那么这将会给你带来麻烦。同时,请考虑一下如果在连接建立之后调用了该SetUserName方法,会发生什么。你支持这种用法吗? - David Heffernan
@DavidHeffernan,完全同意关于with的问题(它在问题中被提到)。通常我会有一个名为Username的公共属性,SetUsername将是私有setter。我也想保持答案简单并演示参数传递(按约定,FUsername应该是私有的,因此只属于调用窗体)。 - SteB
由于David提供的澄清,我已更改了接受的答案。但仍然非常感谢SteB。 - Eduard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接