PDA

Ver la Versión Completa : Problema al cerrar ventana de login


steelha
01-06-2012, 20:01:31
Buenas tardes, tenia la necesidad de hacer un login que abriese primero que la ventana principal. Vi unos ejemplos de caral y trate de implementarlo pero el problema viene cuando encuentro al usuario y debe presentarse la ventana principal obtengo el siguiente error y no he podido solucionarlo. Por favor necesito de su ayuda:

Application.Initialize;

LoginForm := TfrmLogin.Create(Application);
if LoginForm.ShowModal = ID_OK then
begin
LoginForm.Free; // o LoginForm.Hide
Application.CreateForm(Tfrmprincipal, frmprincipal);
end;

Application.Run;

Este es el error justamente en la linea del if loginform:
Project prIglesia.exe raised exception class EAccessViolation with message 'Access violation at address 0045C04D in module 'prIglesia.exe'. Read of address 000002F4'. Process stopped. Use step or Run to continue.

Acontunuacion coloco el codigo del login form:
unit ufrmlogin;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls, RzForms, StdCtrls, IniFiles, DB, ADODB;

type
TfrmLogin = class(TForm)
RzFormShape1: TRzFormShape;
Label1: TLabel;
Label2: TLabel;
edUsuario: TEdit;
edClave: TEdit;
btEntrar: TButton;
btCerrar: TButton;
ADOConnection: TADOConnection;
qryUsuario: TADOQuery;
procedure btCerrarClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btEntrarClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
ini : TIniFile;
provider : string;
source : string;
security : string;
password : string;
jet : string;
rutadb : string;
rutapr : string;
user : string;
fechalg : string;
cadenacn : string;
end;

var
frmLogin: TfrmLogin;

implementation

{$R *.dfm}

procedure TfrmLogin.btCerrarClick(Sender: TObject);
begin
Application.Terminate;
end;

procedure TfrmLogin.FormCreate(Sender: TObject);
begin
provider:= '';
source := '';
security:= '';
password:= '';
jet := '';
rutadb := '';
user := '';
fechalg := '';
cadenacn:= '';

//Obtener Ruta donde se ejecuta la aplicacion
rutapr := ExtractFilePath(Application.ExeName);

//Verificar que exista el archivo de configuracion
If not FileExists('Iglesia.ini') then
Begin
ShowMessage('Error en la aplicación, no existe componente principal de configuracion');
Application.Terminate;
end;

//Crear o Abrir Archivo INI
ini := TIniFile.Create(rutapr+'Iglesia.ini');

//Leer Archivo INI
provider:= ini.ReadString('DB','provider','');
source := ini.ReadString('DB','source','');
security:= ini.ReadString('DB','security','');
password:= ini.ReadString('DB','password','');
jet := ini.ReadString('DB','jet','');
rutadb := ini.ReadString('DB','ruta','');
user := ini.ReadString('LOGIN','user','');
fechalg := ini.ReadString('LOGIN','fecha','');

edUsuario.Text := user;

//redireccionar la direccion de la DB
source := Trim(rutapr) + 'Data\' + Trim(source);

//Liberar recurso INI
FreeAndNil(ini);

//Conectar a DB con los datos obtenidos desde el ini
cadenacn:= 'Provider=Microsoft.Jet.OLEDB.4.0;'+
'Password='+password+';'+
'Data Source='+source+';'+
'Persist Security Info=False';

ADOConnection.Connected := False;
ADOConnection.ConnectionString := cadenacn;
ADOConnection.Connected := True;
end;

procedure TfrmLogin.btEntrarClick(Sender: TObject);
begin
qryUsuario.Close;
qryUsuario.SQL.Text := 'SELECT * FROM tblusuarios Where userid='+QuotedStr(Trim(edUsuario.Text))+' AND password='+QuotedStr(Trim(edClave.Text));
qryUsuario.Open;
If qryUsuario.RecordCount < 1 then
begin
ShowMessage('Usuario ó Clave erronea, intente de nuevo');
edUsuario.SetFocus;
end
else
frmLogin.Close;
end;

end.

Muchas gracias por cualquier ayuda

maeyanes
01-06-2012, 20:20:33
Hola...

¿Ya trataste de hacer un seguimiento del código usando puntos de roptura (Break Points) y la tecla F7?

Otro detalle que veo es que declaras muchas de las variables que usas dentro del constructor como campos públicos de la clase TfrmLogin y solo se usan dentro de este. Deberías declararlas dentro del constructor.


Saludos...

steelha
01-06-2012, 20:23:02
Muchas gracias por tu observacion :) es que soy poco novato .... verificare esto y luego publico que ha pasado

steelha
01-06-2012, 20:28:51
Te explico justamente aca es donde da el error en el form de login:
qryUsuario.Close;
qryUsuario.SQL.Text := 'SELECT * FROM tblusuarios Where userid='+QuotedStr(Trim(edUsuario.Text))+' AND password='+QuotedStr(Trim(edClave.Text));
qryUsuario.Open;
If qryUsuario.RecordCount < 1 then
begin
ShowMessage('Usuario ó Clave erronea, intente de nuevo');
edUsuario.SetFocus;
end
else
frmLogin.Close;

Sobre las variables publicas, es que luego de cerrar el login que solo tiene una conexion a la db para la desconectare y el form principal creara otra nueva conexion en base a estos datos ya recolectados. pero si dices que esta mal esta mal :) buscare otra forma

roman
01-06-2012, 20:33:14
Prueba poniendo Close en lugar de frmLogin.Close.

// Saludos

maeyanes
01-06-2012, 20:34:52
Hola...

No puedes hacer referencia a una variable del tipo de una clase (en este caso frmLogin) dentro del código del constructor o en tu caso en el código del evento FormCreate. Esto es por que no siempre hay seguridad de que esa variable ya esté referenciada. Si necesitas llamar a un metodo de la clase, usa solo el nombre del método o usa la refencia a Self.

Ahora, dentro del constructor de una clase que desciende de TForm o el evento FormCreate no se debe usar el método Close, ya se que para empezar el objecto aun se está creando y no se ha mostrado. En tu caso elimina la llamada a frmLogin.Close.


If qryUsuario.RecordCount < 1 then
begin
ShowMessage('Usuario ó Clave erronea, intente de nuevo');
edUsuario.SetFocus;
end
//else <-- eliminar
// frmLogin.Close; <-- eliminar


Saludos...

roman
01-06-2012, 20:37:14
Ahora, dentro del constructor de una clase que desciende de TForm o el evento FormCreate no se debe usar el método Close, ya se que para empezar el objecto aun se está creando y no se ha mostrado. En tu caso elimina la llamada a frmLogin.Close.

Mmm. No creo que ese código último que puso esté en el constructor.

// Saludos

maeyanes
01-06-2012, 20:39:01
Hola...

roman, si me di cuenta, es por eso que edité mi mensaje. Aun estándo el código dentro del evento FormCreate, el formulario aun no se ha mostrado por lo que llamar al método Close no tiene ningún efecto (no recuerdo si produce alguna excepción).


Saludos...

steelha
01-06-2012, 20:42:04
ps... parece que maeyane tenia razon :) gracias y tanto que pase por esa linea parece que la copie de otro lugar :P ... pero simplemente cierra y la ventana principal no se presenta... pero lo importante es que ya no me da el error

luisgutierrezb
01-06-2012, 21:46:47
nada mas para complementar la razón, en tu unidad, la forma se llama frmlogin, pero al crearla desde el programa principal le llamas LoginForm, entonces al darle frmlogin.close, te manda al error porque no existe frmLogin, sino LoginForm, como te dijeron arriba, usa el close solamente, debe funcionar bien puesto que ese código esta en un botón...

maeyanes
01-06-2012, 22:01:31
Hola...

Vaya, me acabo de dar cuenta de que el código en cuestión está dentro del evento OnClick de un botón y no en el código del FormCreate. Como bien indica roman y parte de lo que le comenté arriba, con solo usar Close o Self.Close se solucionaba el problema.

Eso me pasa por no fijarme bien en el código. Tienes razón roman, el código no es parte del evento FormCreate y por consiguiente, en este caso, lo que comenté al respecto no afecta.


Saludos...

steelha
01-06-2012, 22:16:32
Muchas gracias por los comentarios me ayudaron. Pero como soluciono el problema de desplegar la ventana del form principal ya que al hacer close se cierra todo y no se ejecuta la aplicacion ... por lo cual aun no entiendo esta parte :

program prIglesia;

uses
Forms,
Windows,
uPrincipal in 'uPrincipal.pas' {frmprincipal},
ufrmlogin in 'ufrmlogin.pas' {frmLogin};

var
loginform, pprincipal : TForm;

{$R *.res}

begin
Application.Initialize;

LoginForm := TfrmLogin.Create(Application);
if LoginForm.ShowModal = ID_OK then
begin
LoginForm.Free; // o LoginForm.Hide
Application.CreateForm(Tfrmprincipal, frmprincipal);
end;

Application.Run;
end.

se supone deberia abrir la form principal despues de logeada, pero no sucede eso simplemente se cierrar toda la aplicacion

maeyanes
01-06-2012, 22:18:58
Hola...

No estoy muy seguro y no tengo forma de comprobarlo ahora, pero el problema puede ser la forma en como comparas el resultado de ShowModal. Prueba con:


if LoginForm.ShowModal = mrOk then



Saludos...

roman
01-06-2012, 22:31:48
se supone deberia abrir la form principal despues de logeada, pero no sucede eso simplemente se cierrar toda la aplicacion

Posiblemente la condición

if LoginForm.ShowModal = ID_OK then

no se cumple y si eso es así es porque no estás poniendo ModalResult = mrOk en ningún lado. Usualmente esto se hace poniendo la correspondiente propiedad en el botón de Aceptar del LoginForm.

// Saludos

ecfisa
01-06-2012, 22:32:22
Hola.

Estaba mirando el código y el origen de la excepción es que en el proyecto, steela hace la creación sobre la variable LoginForm:

begin
Application.Initialize;
LoginForm := TfrmLogin.Create(Application);
...


Pero luego, y dentro de él libera a frmLogin:

...
else
frmLogin.Close;

Y como no existe una instancia de frmLogin de allí la excepción. Confusión esta que queda solapada si se llama directamente al método Close o a Self.Close ya que de ese modo se libera a la instancia correcta.

Saludos.

steelha
01-06-2012, 22:42:20
ok probare en unos minutos aca hay mucho trabajo hoy
y debo entregar esta aplicacion en 3 horas a mas tarda T_T espero terminar a tiempo gracias por la ayuda

roman
01-06-2012, 22:43:34
Creo que esto es lo que observó luisgutierrezb en el mensaje #10 (http://clubdelphi.com/foros/showpost.php?p=434101&postcount=10).

// Saludos

ecfisa
01-06-2012, 22:45:33
Creo que esto es lo que observó luisgutierrezb en el mensaje #10 (http://clubdelphi.com/foros/showpost.php?p=434101&postcount=10).

// Saludos
Tenes razón, no ví el mensaje o no le presté atención... mis disculpas Luis :o


Saludos.:)

steelha
01-06-2012, 23:07:05
Probe con colocar segun opiniones lo siguiente
if LoginForm.ShowModal = mrOk
pero consigo el siguiente mensaje
[Error] prIglesia.dpr(18): Undeclared identifier: 'mrOk'

Me imagino que es una variable la cual debo declarar pero:
1.- que tipo de variable debe ser
2.- que como desde el form de login le paso un valor x si se da la coincidencia de usuario
(si lo se como que pregunto mucho)

Gracias por su ayuda :)
Saludos :P

ecfisa
01-06-2012, 23:11:42
Hola steela.

pero consigo el siguiente mensaje
[Error] prIglesia.dpr(18): Undeclared identifier: 'mrOk'
Tenes que incluir la unidad Controls.

uses ..., Controls;


Y lo que te comentó roman es que cuando la contraseña sea correcta hagas:

ModalResult:= mrOk;

Edito: (No sé si te referías a eso en tu última pregunta).

Saludos.

steelha
02-06-2012, 01:28:42
Muchas gracias por la ayuda, al final tube que hacer una modificacion para que funcionara
program prIglesia;

uses
Forms,
Windows,
Controls,
uPrincipal in 'uPrincipal.pas' {frmprincipal},
ufrmlogin in 'ufrmlogin.pas' {frmLogin};

{$R *.res}

begin
Application.Initialize;

frmLogin := TfrmLogin.Create(Application);
frmLogin.ShowModal;
if mrOk = 1 then //anteriormente if frmlogin.showmodal = mrok
begin
frmLogin.Hide; // o LoginForm.Hide
Application.CreateForm(Tfrmprincipal, frmprincipal);
end;

Application.Run;
end.

Gracias, Gracias por toda la ayuda ... no sera la ultima :)
pero aprendi algo hoy ... una simple linea te puede costar todo un dia de malhumor
Gracias roman, ecfisa, maeyanes

licha
02-06-2012, 02:06:53
Hola.
Estoy haciendo una ventana de iniciar sesion. La puse como form principal, pero al ocultarla (visible en false) se desaparece la aplicacion de la barra de herramientes. Queria saber si pudieran explicarme como hacer para que no suceda eso.
Aclaro que el inicio de sesion, la persona se logea con dni y password; y, segun su rol (que esta en la base de datos), se desplega la ventana adecuada. Esto lo hice, pero al ocultar la ventana de login, se desaparece de la barra de herramientas y no resulta practico... jajaja.
Estoy buscando la solucion al problema

Gracias

roman
04-06-2012, 17:14:59
if mrOk = 1 then //anteriormente if frmlogin.showmodal = mrok



Esto no es correcto. mrOk es una constante cuyo valor es 1, de manera que la comparación siempe será cierta aún cuano el login no sea correcto.

// Saludos