Да, вам нужно указать showFrame, какой класс создавать:
добавить
type
tfraFrameClass = class of TfraFrame;
сразу после объявления tfraFrame. И измените showFrame на:
function ShowFrame(Frame: TfraFrame; FrameClass: TfraFrameClass): TfraFrame;
begin
if Frame = nil then
begin
Result := FrameClass.Create(self);
Result.Init(Panel1);
end
else
Result := Frame;
Result.Show;
end;
Обратите внимание, что вы не можете передать Frame как параметр var, так как компилятор будет настаивать на том, чтобы объявленные и фактические типы переданного параметра были точно такими же.
Обновление
Обновлен пример отображения кадра, когда он уже был назначен.
Обновление
Я не упомянул, что присвоение результата вызова Create в коде OP для процедуры showFrame не будет работать. Если бы оно не было объявлено как var, присваивание не выходило бы за рамки процедуры showFrame, значение переменной, переданной в showFrame, не изменилось бы. Объявление его как var не будет работать, как указано выше. Решение состоит в том, чтобы сделать то, что предлагает @Andreas: использовать нетипизированный указатель; или сделайте это функцией, как я сделал. Конечно (с улыбкой) я предпочитаю мой, так как он немного лучше сохраняет безопасность типов.
Также, конечно, в моем примере предполагалось, что результат функции showFrame будет присвоен соответствующей переменной кадра, например:
fraUsers := showFrame(fraUsers, TfraUsers);
Обновление
Или, как указал Sertac, вы все равно можете использовать процедуру с параметром var, когда выполняете приведение к переменной, передаваемой в showForm.
procedure showFrame(var Frame: TfraFrame; FrameClasse: TfraFrameClass);
begin
if Frame = nil then
begin
Frame := FrameClass.Create(self);
Frame.Init(Panel1);
end;
Frame.Show;
end;
и назовите его так:
showFrame(TfraFrame(fraUsers), TFraUsers);