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
对象而不是它的 HWND
。 HWND
保证是唯一的,但不是持久的,因为它可以在表单的生命周期内发生变化。它还可以使您免于必须从 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);
我有一个 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
对象而不是它的 HWND
。 HWND
保证是唯一的,但不是持久的,因为它可以在表单的生命周期内发生变化。它还可以使您免于必须从 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);