Fórum Datamodule #343692
25/07/2007
0
Ahlex10100
Curtir tópico
+ 0Posts
26/07/2007
Rodfernandes
Uso no DataModule, prefiro centralizar tudo em um só lugar.
Por exemplo, se você for utilizar uma mesma consulta em varios forms, basta refenciar o DM e usar suas propriedades. :D
Abraço
Gostei + 0
26/07/2007
Adriano Santos
Com certeza, acho mais prático também além de ter forms mais organizados e ´sepaados´ das rotinas de acesso a dados e etc.
Gostei + 0
26/07/2007
Yakazuma1
Gostei + 0
26/07/2007
Adriano Santos
Qual o problema?
Normalmente eu crio o Data Module em run-time, ou seja, no momento que preciso usá-lo. Um exemplo disso: quando meu usuário abre a tela de Clientes no onCreate do form mando criar o Data Module.
procedure TForm1.FormCreate(Sender: TObject); begin dmClientes := TdmClientes.Create(Self); //abre queries e etc end;
e no onDestroy do mesmo form o Data Module é destruído junto.
procedure TForm1.FormDestroy(Sender: TObject); begin dmClientes.Free; end;
Você deve estar se perguntando: E se outra tela também usa o Data Module dmClientes? Vou criar novamente o dmClientes?
Sim, claro. É uma nova instância do dmClientes em memória em, provavelmente, outra estação da rede. Sem crise. ;)
Gostei + 0
26/07/2007
Yakazuma1
Fiz assim: no evento onDeactivate do próprio form escrevi form.Destroy;
tentei fazer o mesmo no OnClose, e deu Abstract Error. Alguém sabe o por que disso, e como destruir um form quando ele for fechado?
Gostei + 0
26/07/2007
Adriano Santos
Cara, primeira dica: NUNCA use o método Destroy do objeto. O Destroy só é aconselhável usar quando se tem certeza absoluta que o objeto esteja carregado em memória como por exemplo no desenvolvimento de componentes. Do contrário um Access Violation será acionado. Por que? O Destroy elimina a instância do componente, mas não testa antes se o mesmo é NIL. Já o Free testa antes de o objeto é NIL e então chama o método Destroy. Veja a declaração na unit System do Delphi:
procedure TObject.Free; begin if Self <> nil then Destroy; end;
Já uma das formas de fazer a ´eliminação´ do form seria no onDestroy atribuir o valor nil ao form.
procedure TForm1.FormDestroy(Sender: TObject); begin Form1 := nil; end;
e no onClose atribuir caFree a ação:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;
Porém, há aqueles que usam diretamente o método FreeAndNil que já faz as duas coisas.
procedure TForm1.FormDestroy(Sender: TObject); begin FreeAndNil(Form1); end;
Gostei + 0
27/07/2007
Felipeiw
Abs
Gostei + 0
27/07/2007
Adriano Santos
Boa pergunta :). Não utilizo MDI, não vejo nenhuma forte razão para usá-los. É mais complicado pra controlar, obsoleto (na minha opnião) e, também na minha opnião, fica com uma má aparência. Sempre usei SDI. Contudo, acredito que não tenha nenhum problema já que cada form cria uma nova instância do Data Module.
Alguém que trabalha com MDI poderia nos tirar dúvidas a respeito disso?
Gostei + 0
27/07/2007
Yakazuma1
Cara, primeira dica: NUNCA use o método Destroy do objeto. O Destroy só é aconselhável usar quando se tem certeza absoluta que o objeto esteja carregado em memória como por exemplo no desenvolvimento de componentes. Do contrário um Access Violation será acionado. Por que? O Destroy elimina a instância do componente, mas não testa antes se o mesmo é NIL. Já o Free testa antes de o objeto é NIL e então chama o método Destroy. Veja a declaração na unit System do Delphi:
procedure TObject.Free; begin if Self <> nil then Destroy; end;
Já uma das formas de fazer a ´eliminação´ do form seria no onDestroy atribuir o valor nil ao form.
procedure TForm1.FormDestroy(Sender: TObject); begin Form1 := nil; end;
e no onClose atribuir caFree a ação:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;
Porém, há aqueles que usam diretamente o método FreeAndNil que já faz as duas coisas.
procedure TForm1.FormDestroy(Sender: TObject); begin FreeAndNil(Form1); end;
Mas Adriano, se eu crio uma instância, não é necessário q eu a destrua?
Tenho outra dúvida também: criei um form q estava como Available. Usei
Application.CreateForm(TForm,Form);
Form.Show;
Eu posso deixar sem função alguma pra liberar ele, ou destruir? Por exemplo, se eu vou ter q colocar Free no Close, ou algo assim.
Gostei + 0
27/07/2007
Yakazuma1
Gostei + 0
27/07/2007
Adriano Santos
Sim, é necessário. Do contrário você estará com seu Data Module em memória o tempo todo durante a execução de sua aplicação. É simples: se seu usuário está com todas as janelas fechadas e permanece somente na tela inicial do programa, por que deixar o Data Module carregado na memória? Por isso é aconselhável você destruir o objeto, no caso o DM, depois de fechar a tela que o usava.
Me corrijam se eu estiver errado, mas é o seguinte: o CreateForm é o método de criação de forms do objeto TApplication. Criando o componente (form) a partir deste método você está dando a responsabilidade de gerenciamento do objeto ao TApplication, sua aplicação. Ou seja, a própria aplicação fará a criação e destruição do objeto.
O Form1.Create é o método de criação do próprio objeto. E nele você indica quem será responsável por gerenciar sua instância...Self, ele mesmo, ou Application, sua aplicação.
caFree é uma atribuição a variável Action no segundo parâmetro do evento onClose. Atribuindo caFree você está informando ao form que ele deve ser liberado de memória. As opções possíveis são:
TCloseAction = (caNone, caHide, caFree, caMinimize);
caNone = não faz nada;
caHide = esconde;
caFree = libera de memória;
caMinimize = minimiza a janela;
A classe TCloseAction está declarada na unit Forms do Delphi.
O FreeAndNil tem um papél diferente. Quando chamado libera de memória e esvazia, deixa nulo o ponteiro de memória que era apontado para a instância do form. Novamente peço que me corrijam se falei besteira.
Não há problema nenhum em usar de um jeito ou de outro.
Gostei + 0
09/09/2007
Rodolfo.pirolo
Estou tentando utilizar essa sua dica para criar o data module em tempo de excecução, mas esta dando o seguinte erro ´Access violation at address 00582BB3 in module ´ConsultorioMedico.exe´. Read of address 00000060´.
Isto acontece quando tento executar a seguinte linha: tmpDM_Cadastro.cds_Pessoa.Open;
Segui os seus passos da seguinte maneira:
-[b:717b1f6eec]crio as variaveis assim:[/b:717b1f6eec]
implementation
uses uDM_Cadastro, uDM_Consulta;
var
tmpDM_Cadastro : TdmCadastro;
tmpDM_Consulta : TDMConsulta;
-[b:717b1f6eec]no Create do formulario:[/b:717b1f6eec]
procedure TformCadastroPessoa.FormCreate(Sender: TObject);
begin
inherited;
tmpDM_Cadastro := TdmCadastro.Create( Self );
tmpDM_Consulta := TDMConsulta.Create( Self );
end;
Deixei os DM principais ( DMCadastro e DMConsulta ) no auto-create forms, tentei deixa-los no available forms mas o erro continua.
Uso Delphi 2005.
Abraços
Rodolfo
Gostei + 0
10/09/2007
Adriano Santos
Não entendi muito bem o que está fazendo, mas vamos lá.
Coloquei no meu ftp um exemplo básico de criação do DataModule em runtime. Dá uma olhada em www.doiscliques.com/pub/dm.zip veja se te ajuda a entender melhor.
Gostei + 0
10/09/2007
Rodolfo.pirolo
Não sei o que estava fazendo de errado, pois comparei seu exemplo com o que já tinha feito, aparentemente esta tudo certo.
Pelo menos não deu mais erro de acces violation.
Muito obrigado pela dica e pelo exemplo.
Abraços
Rodolfo
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)