Динамическое создание формы в DLL
Select messages from
# through # FAQ
[/[Print]\]

Total Commander -> Написание плагинов для Total Commander

#1: Динамическое создание формы в DLL Author: МоторокерLocation: г. Пермь (читается Перьмь) PostPosted: Wed Jun 06, 2007 09:55
    —
Подскажите, как надо правильно создавать модальную форму?
Раньше делал так:
Code:
var
  fmSetup: TfmSetup;
begin
  fmSetup:= TfmSetup.Create(nil);
  fmSetup.ShowModal;
  fmSetup.Free;

Сделал nil, т.к. на Delphi ругалась на незнание Self
Затем вычитал про необходимость использования Release вместо Free – якобы ждёт, когда все потоки отработают, вся память освободится:
Code:
var
  fmSetup: TfmSetup;
begin
  fmSetup:= TfmSetup.Create(nil);
  fmSetup.ShowModal;
  fmSetup.Release;

в Тотале всё работает, а PlugMan вылетает с ошибкой
Подключил модуль Forms, добавил Application в Create:
Code:
var
  fmSetup: TfmSetup;
begin
  fmSetup:= TfmSetup.Create(Application);
  fmSetup.ShowModal;
  fmSetup.Free;

Вроде бы работает.
Так как надо делать правильно?

#2:  Author: Dec PostPosted: Wed Jun 06, 2007 11:13
    —
Мой код, может быть пригодится
Code:

type
  TWinArray = array of THandle;

function TdecFSRoot.ExecuteProperties(AMainWin: Cardinal; ARemoteName: PAnsiChar): Integer;
var
  NotTC: boolean;
  Thr: THandle;
  WinArray: TWinArray;

  function DoDisableWindow(Window: HWnd; Data: Longint): Bool; stdcall;
  begin
    if IsWindowVisible(Window) and IsWindowEnabled(Window) then
    begin
      SetLength(WinArray, Length(WinArray) + 1);
      WinArray[Length(WinArray) - 1] := Window;
      EnableWindow(Window, False);
    end;
    Result := True;
  end;

  procedure EnableTaskWindows;
  var i: integer;
  begin
    for i := 0 to Length(WinArray) - 1 do
      if IsWindow(WinArray[i]) then EnableWindow(WinArray[i], True);
    SetLength(WinArray, 0);
  end;

  procedure DisableTaskWindows(AThread: THandle);
  begin
    try
      EnumThreadWindows(AThread, @DoDisableWindow, 0);
    except
      EnableTaskWindows;
      raise;
    end;
  end;

begin
  if not HaveProperties then
    begin
      Result := FS_EXEC_YOURSELF;
      exit;
    end;
  try
    if decGetClassName(AMainWin) <> 'TTOTAL_CMD' then
      begin
        NotTC := true;
        Thr := GetWindowThreadProcessId(AMainWin);
        SetLength(WinArray, 0);
        DisableTaskWindows(Thr);
      end
    else
      NotTC := false;
    try
      ShowProperties(AMainWin);
      Result := FS_EXEC_OK;
    finally
      if NotTC then
        EnableTaskWindows;
    end;
  except
    Result := FS_EXEC_ERROR;
  end;
end;

procedure TdecFSClipboardRoot.ShowProperties(AMainWin: Cardinal);
var AboutForm: TAboutForm2;
begin
  Application.Handle := AMainWin;
  AboutForm := TAboutForm2.Create(Application);
  try
    AboutForm.ShowModal(IniFile);
  finally
    AboutForm.Free;
    Application.Handle := 0;
  end;
end;

#3:  Author: МоторокерLocation: г. Пермь (читается Перьмь) PostPosted: Fri Jun 08, 2007 08:38
    —
Ответили здесь

Quote:
использовать Release рекомендуется для
корректного освобождения формы в случае, если ее необходимо освободить в одном из ее методов-обработчиков событий...
т.е. в этом случае использование Release вместо Free роли не играет, более того, если в обработчике формы OnClose выставить CloseAction := caFree, то и во Free после ShowModal необходимость так же отпадет.


Quote:
так что лучше имхо оставить первый способ:



Total Commander -> Написание плагинов для Total Commander


output generated using printer-friendly topic mod. All times are GMT + 4 Hours

Page 1 of 1

Powered by phpBB © 2001, 2005 phpBB Group