Delphi Application.CreateForm 每个表格的句柄是唯一的吗?

Delphi Application.CreateForm is the Handle Unique for each Form?

我有一个 TreeList ,有很多项目,每个项目都有自己唯一的 ID。 我允许用户一次打开多个 ID。但是我想防止用户打开同一个ID两次。

所以我考虑创建一个简单的动态数组,在其中存储哪个 TreeList ID 连接到哪个 Form HWND 。如果我在我的列表中找到一个具有匹配 HWND 的 ID,那么我只需将已经创建的表单带到前台。

  Application.CreateForm(TChapter, Chapter);
  Chapter.PopupParent:=Main;
  Chapter.FID:=qryTreeID.Value;
  Chapter.Caption:=qryTreeName.Value+Cardinal(Chapter.Handle).ToString;
  Chapter.Show;

这就是我创建表单的方式。这只是一个 "basic" 示例。我只是想确保 Handle 是 Unique ,我打开了 Multiple Forms 数字总是不同的。但我想确定一下。

谢谢!

谢谢你们两位。我采纳了 SilverWariiors 的建议,因为它很简单 :)

  for i := 0 to Screen.FormCount-1 do
  begin
    if Screen.Forms[i] is TChapter then
      if (Screen.Forms[i] as TChapter).FID = qryTreeID.Value then
      begin
        (Screen.Forms[i] as TChapter).BringToFront;
        Exit;
      end;
  end;

如果您想维护自己的查找,TDictionary 比动态数组更有意义。但无论哪种方式,您都应该将 ID 映射到实际的 TForm 对象而不是它的 HWNDHWND 保证是唯一的,但不是持久的,因为它可以在表单的生命周期内发生变化。它还可以使您免于必须从 HWND.

获取 TForm 对象的额外步骤

例如:

var
  Chapters: TDictionary<Integer, TChapter> = nil;

procedure ChapterDestroyed(Self: Pointer; Sender: TObject);
begin
  if Chapters <> nil then
    Chapters.Remove(TChapter(Sender).FID);
end;

function FindChapterByID(ID: Integer): TChapter;
// var I: Integer;
begin
  {
  for I := 0 to Screen.FormCount-1 do
  begin
    if Screen.Forms[I] is TChapter then
    begin
      Result := TChapter(Screen.Forms[I]);
      if Result.FID = ID then Exit;
    end;
  end;
  Result := nil;
  }
  if not Chapters.TryGetValue(ID, Result) then
    Result := nil;
end;

function CreateChapter(ID: Integer): TChapter;
var
  Event: TNotifyEvent;
begin
  TMethod(Event).Data := nil;
  TMethod(Event).Code = @ChapterDestroyed;

  Result := TChapter.Create(Main);
  try
    Result.FID := ID;
    Result.PopupParent := Main;
    Result.Caption := qryTreeName.Value + ID.ToString;
    Result.OnDestroy := Event;
    Chapters.Add(ID, Result);
  except
    Result.Free;
    raise;
  end;
end;

function ShowChapterByID(ID: Integer): TChapter;
begin
  Result := FindChapterByID(ID);
  if Result = nil then Result := CreateChapter(ID);
  Result.Show;
end;

initialization
  Chapters := TDictionary<Integer, TChapter>.Create;
finalization
  FreeAndNil(Chapters);
Chapter := ShowChapterByID(qryTreeID.Value);