liberar um form mdi shield da memória e chamá-lo novamente.

18/11/2008

tenho um botão no form mdi shield e utilizo o comando "self.relesead" para remover o form da memória. Mas não consigo chamar a tela novamente. Simplesmente não aparece nada e não nenhuma mensagem de erro.

Alterei para o modelo abaixo, já que o Delphi 2007 não aceitou o comando "action = caFree;" para ser executado no onclik do botão.

  private
    { private declarations }
    vPodeFechar : Boolean;
   

procedure TForm940.FormCreate(Sender: TObject);
begin
  vPodeFechar := False;
end;

procedure TForm940.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if vPodeFechar then
    Action := caFree;
end;

procedure TForm940.BotaoFecharClick(Sender: TObject);
begin
  vPodeFechar := True;
  Close;
end;


Desse modo funcionou perfeitamente, mas não achei nada elegante.

Teria alguma outra solução ?
Nirlan Fundao

Nirlan Fundao

Curtidas 0

Respostas

Guinther Pauli

Guinther Pauli

18/11/2008

Olá Nirlan, Self é um ponteiro que aponta para outro o ponteiro real. Junta isso ao novo gerenciador de memoria FAST MMI que entrou no delphi 2006 e temos um comportamento diferente agora.   Bem, usando MDI isso fica mais claro ainda por isso que vc esta usando self.released e não funciona. Assim, para liberar um objeto efetivamente da memória a partir do Delphi 2006 use freeandnil().    Bem no seu caso no onclose do formulário onde esta Action := caFree;   Faça:      FreeAnNil(SeuForm). Não use self pelo motivo exposto acima use sempre a variavel do formulário mesmo.   Aguardamos seu retorno,    abs  
GOSTEI 0
Guinther Pauli

Guinther Pauli

18/11/2008

Nirlan, Bom dia !   Mais alguma dúvida sobre este chamado ou podemos encerrá-lo?   abs
GOSTEI 0
Nirlan Fundao

Nirlan Fundao

18/11/2008

usando o FreeAndNil eu consigo reabrir o form.

Mas ao fecha-lo recebo a mensagem de erro:

control "" has no parent window


alguma sugestão do motivo dessa mensagem ?

abraços

Nirlan
GOSTEI 0
Guinther Pauli

Guinther Pauli

18/11/2008

Nirlan,     Existe mais algum codigo sendo executado no onClose ou no OnClose Query. Pois no exemplo que fiz e montei não deu este problema. Esta mensagem geralmente e dada quando tentamos por exemplo mover um foco a um controle não criado mas não ainda exibido, netre outras coisas. Teria como mandar o exemplo que vc fez para que eu possa analisar ??? Aguardo retorno, abs
GOSTEI 0
Nirlan Fundao

Nirlan Fundao

18/11/2008

Form Padrão:


var
  Form940: TForm940;

implementation

uses DataModu;

{$R *.DFM}


procedure TForm940.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = Vk_Escape then Close;
end;

procedure TForm940.FormResize(Sender: TObject);
begin
  GroupBox1.Left  := (Panel3.ClientWidth  div 2) - (GroupBox1.Width  div 2);
  GroupBox1.Top   := (Panel3.ClientHeight div 2) - (GroupBox1.Height div 2);
  PanelBotao.Left := (Panel1.ClientWidth  div 2) - (PanelBotao.Width div 2);
end;

procedure TForm940.BotaoFecharClick(Sender: TObject);
begin
  Close;
end;

procedure TForm940.Query1AfterOpen(DataSet: TDataSet);
var
  k: Integer;
begin
  for k := 0 to Query1.Fields.Count - 1 do
    Query1.Fields.Fields[k].ProviderFlags := [pfInUpdate];

  Query1.FieldByName( DM.vCampoChave ).ProviderFlags := [pfInUpdate,pfInKey];
end;


==================

O Form de inclusao do registro aonde ocorre a mensagem de erro, quando se clica no botão "fechar":


type
  TForm100 = class(TForm940)
    procedure BotaoCancelaClick(Sender: TObject);
    procedure BotaoOKClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure BotaoAlteracaoClick(Sender: TObject);
    procedure BotaoExclusaoClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure ConfiguraNovoRegistro;
  public
    { Public declarations }
  end;

var
  Form100: TForm100;

implementation

uses DataModu, Prog102, Prog104;

{$R *.dfm}


procedure TForm100.BotaoAlteracaoClick(Sender: TObject);
begin
  DM.OpenForm(TForm102, TForm(Form102));
end;

procedure TForm100.BotaoExclusaoClick(Sender: TObject);
begin
  DM.OpenForm(TForm104, TForm(Form104));
end;

procedure TForm100.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   FreeAndNil(Form100);
end;

procedure TForm100.FormActivate(Sender: TObject);
var
  vSQL : String;

begin
  if not ClientDS1.Active then
    begin
      vSQL := Select * From T06_GRUP   +
              Where                     +
              T06_Exclusao is Null and +
              T06_NumGrupo = -1         ;

      if not DM.AbreTabela( ClientDS1, vSQL , T06_NumGrupo , True ) then
        begin
          Application.MessageBox(Ocorreu um erro na leitura dos dados. Tente novamente.,
                                 Atenção, mb_ok + mb_IconError );
          PostMessage(Handle, wm_Close, 0, 0);
        end;

      ConfiguraNovoRegistro;
    end;
end;

procedure TForm100.ConfiguraNovoRegistro;
begin
  ClientDS1.Append;
  frNome.SetFocus;
end;

procedure TForm100.BotaoCancelaClick(Sender: TObject);
begin
  if Application.MessageBox( Confirma o cancelamento da inclusão ?,
                             Atenção, mb_YesNo + mb_IconQuestion ) = idYes then
    begin
      ClientDS1.Cancel;
      ConfiguraNovoRegistro;
    end
  else
    frNome.SetFocus;
end;

procedure TForm100.BotaoOKClick(Sender: TObject);
begin
  //  Verifica a validade do nome do grupo
  //  ====================================
  if StrAlltrim(frNome.Text) = then
    begin
      Application.MessageBox(O nome do grupo precisa ser informado.,
                             Atenção, mb_ok + mb_IconError );
      frNome.SetFocus;
      Exit;
    end;

  // Verifica existencia do nome
  // ===========================
  Query0.Close;
  Query0.SQL.Clear;
  Query0.SQL.Add( Select * From T06_GRUP   );
  Query0.SQL.Add( Where );
  Query0.SQL.Add( T06_Exclusao is Null and );
  Query0.SQL.Add( T06_NomeGrupo      = :P0 );
  Query0.Params[00].AsString := frNome.Text;
  Query0.Open;

  if not Query0.EOF then
     begin
       Application.MessageBox( Este grupo já foi cadastrada anteriormente. + #10#13 +
                               A gravação dos dados não pode ser efetuada.,
                               Atenção, mb_ok + mb_IconError );
       frNome.SetFocus;
       Exit;
     end;

  //  Efetua a gravacao dos dados
  //  ===========================
  try
    ClientDS1.Post;
  except
  end;

  if ClientDS1.ApplyUpdates(0) > 0 then
    Application.MessageBox(Ocorreu um erro na gravação dos dados. Tente novamente.,
                           Atenção, mb_ok + mb_IconError )
  else
    begin
      ClientDS1.Refresh;
      ConfiguraNovoRegistro;
    end;
end;

GOSTEI 0
Guinther Pauli

Guinther Pauli

18/11/2008

Nirlan,   Retire o codigo FreeAndNil(Form100); do OnCLose e coloque no evento OnDestroy do formulario isso irá resolver o seu problema.   Aguardo seu retorno,   abs
GOSTEI 0
Nirlan Fundao

Nirlan Fundao

18/11/2008

Fazendo isso o form é somente minimizado, pois ao clicar no botão Fechar, existe o comando Close, que apenas minimiza o form mdishield. Neste caso o evento onDestroy nunca é executado. abraços Nirlan
GOSTEI 0
Guinther Pauli

Guinther Pauli

18/11/2008

Nirlan, Segue link com vídeo e fonte do projeto que foi feito para você. http://video.devmedia.com.br/naoexclusivos/RodrigoMourao/Consultoria/Chamado596.zip     Aguardamos seu retorno,   abs
GOSTEI 0
Nirlan Fundao

Nirlan Fundao

18/11/2008

muito obrigado. Problema resolvido.
GOSTEI 0
POSTAR