Tela de Logon - Erro ao cancelar

Delphi

26/12/2006

Salve pessoal!

Tenho uma tela de Logon no sistema que é criada assim:

  Application.Initialize;
  Application.CreateForm(TDmPrincipal, DmPrincipal);
  FrmLogon := TFrmLogon.Create(nil);

  if FrmLogon.ShowModal = mrOk then begin

    Application.CreateForm( TfrmPrincipal, frmPrincipal );
    frmPrincipal.ID_Usuario := FrmLogon.ID_Usuario;

    // Destruir FrmLogon
    FreeAndNil( FrmLogon );

    Application.Run;
  end else begin
    Application.Terminate;
  end;


Se eu retorno mrOk para o ShowModal entao blz o sistema entra agora tenho um fotao cancelar no FrmLogon com o seguinte código:

 FrmLogon.Close;


Quando executo o botao a aplicação nao abre mesmo e da aquela caixa de erro:

O Project1.exe encontrou um problema e precisa ser fechado.



Alguem sabe onde estou errando no codigo acima?


Mmoreira

Mmoreira

Curtidas 0

Respostas

Massuda

Massuda

26/12/2006

Não precisa do Application.Terminate. Ao sair do if, imaginando que esse código seja do seu DPR, o programa terminará.


GOSTEI 0
Mmoreira

Mmoreira

26/12/2006

Massuda,

Sim este é o codigo do meu DPR.

Eu fiz como voce sugeriu:

begin

  Application.Initialize;
  Application.CreateForm(TDmPrincipal, DmPrincipal);
  FrmLogon := TFrmLogon.Create(nil);

  if FrmLogon.ShowModal = mrOk then begin

    Application.CreateForm( TfrmPrincipal, frmPrincipal );
    frmPrincipal.ID_Usuario := FrmLogon.ID_Usuario;

    try
      Application.CreateForm( TFrmSplash, FrmSplash );
      FrmSplash.ShowModal;
    finally
      FrmSplash.Release;
    end;

    // Destruir FrmLogon
    FreeAndNil( FrmLogon );

    Application.Run;
  end else begin
//    Application.Terminate;
  end;

end.



E mesmo assim continuo tendo erro ao fechar o FrmLogon clicando no botao cancelar. Voce teria mais alguma sugestao.
Uma vez que este projeto esta no inicio nao tenho nada no OnCreate do DmPrincipal.


GOSTEI 0
Massuda

Massuda

26/12/2006

O que seu form de login/logon faz exatamente?

Outra coisa... seu form de splash está sendo exibido com ShowModal, o que significa que ele ficará visível até o usuário fechar o form e irá parar o programa até que isso aconteça. Normalmente o programa que usa form de splash usa Show para exibir o form e o programa fecha/destroi o form de splash quando não precisa mais dele.


GOSTEI 0
Mmoreira

Mmoreira

26/12/2006

Massuda,
O meu FrmLogon tem apenas dois botoes, uma Cancelar e eoutro Logar. Vou deixar o codigo para que voce possa acompanhar:

unit UntFrmLogon;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons;

type
  TFrmLogon = class(TForm)
    btnLogar: TSpeedButton;
    btnCancelar: TSpeedButton;
    procedure FormDestroy(Sender: TObject);
    procedure btnCancelarClick(Sender: TObject);
    procedure btnLogarClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    ID_Usuario : integer;
  end;

var
  FrmLogon: TFrmLogon;

implementation

uses UntFrmPrincipal;

{$R *.dfm}

procedure TFrmLogon.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TFrmLogon.FormDestroy(Sender: TObject);
begin
  FrmLogon := nil;
end;

procedure TFrmLogon.btnLogarClick(Sender: TObject);
begin
  ID_Usuario := 1;
  ModalResult := mrOk;
end;

procedure TFrmLogon.btnCancelarClick(Sender: TObject);
begin
  ModalResult := mrNo;
end;

end.



Como informer o problema so ocorre quando eu nao logo no sistema ou seja quando eu uso o botao: btnCancelar ou simplesmente fecho o FrmLogon.
Em Relação ao meu FrmSplash ainda estou fazendo alguns testes e a propria aplicação vai se encarregar de destruilo, entao para resolver primeiro este problema simplesmente comentei o codigo que chama o FrmSplash:

begin

  Application.Initialize;
  Application.CreateForm(TDmPrincipal, DmPrincipal);
  FrmLogon := TFrmLogon.Create(nil);

  if FrmLogon.ShowModal = mrOk then begin

    Application.CreateForm( TfrmPrincipal, frmPrincipal );
    frmPrincipal.ID_Usuario := FrmLogon.ID_Usuario;

    {
    try
      Application.CreateForm( TFrmSplash, FrmSplash );
      FrmSplash.ShowModal;
    finally
      FrmSplash.Release;
    end;
    }

    // Destruir FrmLogon
    FreeAndNil( FrmLogon );

    Application.Run;
  end else begin
//    Application.Terminate;
  end;

end.



GOSTEI 0
Tnaires

Tnaires

26/12/2006

Olá
Tente o seguinte:
- Deixe o Application.Run fora do if, pois independentemente do método Terminate ter sido chamado ou não, a aplicação precisa executar;
- Após chamar Application.Terminate, execute um Application.ProcessMessages pra garantir que a mensagem de término tenha sido processada.
Vou te dar um exemplo:
  // Efetuando login do usuário
  if not Application.Terminated then
    with TFrmLogin.Create(Application) do
      try
        if ShowModal = mrCancel then
          Application.Terminate;
      finally
        Release;
        Application.ProcessMessages;
      end;

  // Criando form principal
  if not Application.Terminated then
    Application.CreateForm(TFrmPrincipal, FrmPrincipal);
    
  Application.Run;

Abraços


GOSTEI 0
Massuda

Massuda

26/12/2006

Você não precisa de TFrmLogon.FormClose.

Como o form é exibido com ShowModal (que mantem o form visível e para o programa até o usuário dar Ok ou Cancel) e você precisa pegar o resultado depois de voltar do ShowModal, você não pode mandar o form se destruir ao ser fechado.

Note que você precisa destruir o form de login tanto no caso do usuário sair com Ok como no caso de sair com Cancel.


GOSTEI 0
Tnaires

Tnaires

26/12/2006

Massuda, respondemos ao mesmo tempo 8)


GOSTEI 0
Mmoreira

Mmoreira

26/12/2006

Pessoal
Agora fazendo as devidas alterações sugeridas esta tudo funcionando porem agora me deparei com outro problema. Vou deixar o codigo e depois digo qual minha dificuldade:

begin

  Application.Initialize;
  Application.CreateForm(TDmPrincipal, DmPrincipal);

  try
    Application.CreateForm( TFrmLogon, FrmLogon );
    if FrmLogon.ShowModal = mrCancel then Application.Terminate;
  finally
    FrmLogon.Release;
    Application.ProcessMessages;
  end;

  if not Application.Terminated then begin

    Application.CreateForm( TfrmPrincipal, frmPrincipal );
    //frmPrincipal.ID_Usuario := FrmLogon.ID_Usuario;


    try
      Application.CreateForm( TFrmSplash, FrmSplash );
      FrmSplash.ShowModal;
    finally
      FrmSplash.Release;
    end;


  end;

  Application.Run;

end.


Tenho no meu FrmLogon uma variavel: Id_Usuario e eu preciso passar o valor dela para o FrmPrincipal. Uma vez que o FrmLogon ja foi destruido qual seria a maneira correta de tranportar o valor para a variavel do FrmPrincipal?


GOSTEI 0
Massuda

Massuda

26/12/2006

Sinceramente, isto é muito mais simples e fácil de entender...
begin 
  Application.Initialize; 
  Application.CreateForm(TDmPrincipal, DmPrincipal); 

  FrmLogon := TFrmLogon.Create(nil);
  if FrmLogon.ShowModal = mrOk then begin
    
    FrmSplash := TFrmSplash.Create(nil); 
    FrmSplash.Show; 

    Application.CreateForm( TfrmPrincipal, frmPrincipal ); 
    frmPrincipal.ID_Usuario := FrmLogon.ID_Usuario; 

    FrmLogon.Free;

    // faz alguma coisa aqui

    FrmSplash.Free; 

    Application.Run; 
  end
  else begin
    FrmLogon.Free;
  end;
end.



GOSTEI 0
Mmoreira

Mmoreira

26/12/2006

Voce tem toda razao Massuda ... nem sei porque perguntei uma besteira dessa .... :roll:
Final de ano ja viu né ... os neuronios nao estao em sintonia.

Fica ai meu agradecimento ao Massuda e Tnaires pela atenção.

Valew mesmo!!!!


GOSTEI 0
POSTAR