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

廉价感情. 提交于 2020-01-25 09:13:11

问题


I have a TreeList , with many Items , each item has it's own unique ID . I allow the user to open multiple IDs at once . But I would like to prevent the user from opening the same ID twice .

So I thought about creating a simple Dynamic Array where I store which TreeList ID is connected to which Form HWND . If I find a ID on my list with a Matching HWND, then I simply bring the Form which is already Created to Foreground.

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

This is how I create a Form . This is just a "basic" example . I just wanted to make sure that the Handle is Unique , I opened Multiple Forms the Numbers were always different. But I want to make sure.

Thank you!


回答1:


If you want to maintain your own lookup, a TDictionary would make more sense than a dynamic array. But either way, you should map the ID to the actual TForm object rather than to its HWND. The HWND is guaranteed to be unique, but not persistent, as it can change during the Form's lifetime. It would also save you from the extra step of having to get the TForm object from the HWND.

For example:

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);



回答2:


Thank you for both of you. I took SilverWariors advice , because of the simplicity :)

  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;


来源:https://stackoverflow.com/questions/58608595/delphi-application-createform-is-the-handle-unique-for-each-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!