Delphi Application.CreateForm является ли дескриптор уникальным для каждой формы? - PullRequest
0 голосов
/ 29 октября 2019

У меня есть TreeList, с множеством предметов, каждый предмет имеет свой уникальный идентификатор. Я разрешаю пользователю открывать несколько идентификаторов одновременно. Но я хотел бы запретить пользователю открывать один и тот же идентификатор дважды.

Поэтому я подумал о создании простого динамического массива, в котором я сохраняю, какой идентификатор TreeList связан с какой формой HWND. Если я нахожу идентификатор в моем списке с соответствующим HWND, то я просто переношу форму, которая уже создана, на передний план.

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

Так я создаю форму. Это просто «базовый» пример. Я просто хотел убедиться, что дескриптор уникален, я открыл несколько форм, числа всегда были разными. Но я хочу убедиться.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 29 октября 2019

Если вы хотите сохранить свой собственный поиск, TDictionary будет иметь больше смысла, чем динамический массив. Но в любом случае вы должны сопоставить идентификатор с действительным TForm объектом, а не с HWND. HWND гарантированно будет уникальным, но не постоянным, поскольку он может меняться в течение срока действия формы. Это также избавит вас от лишнего шага, связанного с получением объекта TForm от HWND.

Например:

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);
0 голосов
/ 29 октября 2019

Спасибо вам обоим. Я воспользовался советом SilverWariors из-за своей простоты:)

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