问题
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