Devolver TApplication para DLL ao fecha Form MDI
Salve pessoal,
Lendo alguns topicos aqui no Forum eu estou abrindo um Form do tipo MDI que esta dentro de uma DLL, de acordo com as informações que encontrei aqui no Forum quando fazemos isso temos que passar o TApplication do EXE para a DLL e depois quando finalizamos nosso EXE temos que devolver o TApplication antigo da DLL para a mesma. Pois bem eu fiz tudo isso e esta tudo funcionando sem problemas, o que eu gostaria é de deixar o codigo da minha DLL para que possa ser analizado e ver se existe alguma falha mesmo estando funcionando. Segue o codigo:
Código da DLL
Código do aplicativo que chama a mesma:
Para falar a verdade eu estou com uma pulga atraz da orelha referente estra procedure que eu exportei e coloquei no Destroy do form que chama a DLL.
Bom se alguem puder opinar ...
Valew
Lendo alguns topicos aqui no Forum eu estou abrindo um Form do tipo MDI que esta dentro de uma DLL, de acordo com as informações que encontrei aqui no Forum quando fazemos isso temos que passar o TApplication do EXE para a DLL e depois quando finalizamos nosso EXE temos que devolver o TApplication antigo da DLL para a mesma. Pois bem eu fiz tudo isso e esta tudo funcionando sem problemas, o que eu gostaria é de deixar o codigo da minha DLL para que possa ser analizado e ver se existe alguma falha mesmo estando funcionando. Segue o codigo:
Código da DLL
library FormMDI;
uses
SysUtils, Classes, Windows, Forms,
uMDIChild in ´uMDIChild.pas´ ;
{$R *.res}
var
OldApplication : TApplication;
OldScrean : TScreen;
procedure AbreForm( Ap : TApplication; Sc : TScreen ); stdcall;
var
Form : TMDIChild;
begin
if (OldApplication = nil) and (OldScrean = nil) then begin
OldApplication := Application;
OldScrean := Screen;
Application := Ap;
Screen := Sc;
end;
Form := TMDIChild.Create(Application);
Form.Show;
end;
procedure RetornaTudo; stdcall;
begin
Application := OldApplication;
Screen := OldScrean;
end;
Exports
AbreForm,
RetornaTudo;
begin
end.
Código do aplicativo que chama a mesma:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
Menu1: TMenuItem;
Abre1: TMenuItem;
procedure Abre1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
procedure AbreForm( Ap : TApplication; Sc : TScreen ); stdcall; external ´FormMDI.dll´;
procedure RetornaTudo; stdcall; External ´FormMDI.dll´;
implementation
{$R *.dfm}
procedure TForm1.Abre1Click(Sender: TObject);
begin
AbreForm(Application, Screen);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RetornaTudo;
end;
end.
Para falar a verdade eu estou com uma pulga atraz da orelha referente estra procedure que eu exportei e coloquei no Destroy do form que chama a DLL.
Bom se alguem puder opinar ...
Valew
Mmoreira
Curtidas 0
Respostas
Mmoreira
28/11/2006
Depois que eu adicionei um DBGrid no meu Form ... quando eu finalizo meu sistema é gerado o seguinte erro:
Detalhe se eu volto na DLL retiro o DBGrid ai o sistema fecha normal sem erro algum ... coloco o DBGrid ... o erro volta. E a mesma coisa acontece quando eu coloco um TSpeedButton ... coloco da erro na hora de fechar .. tiro ele ... nada de erro ... Alguem sabe como resolver isso?
Valeww
A instrção no ´0x00f4536´ fez referencia a memoria no ´0x018f1f90´. A memoria nao pode ser ´read´.
Clique em ´OK´ para encerrar o programa
Dai clico em OK e vem outro erro:
Runtime error 216 at 00F43536
Detalhe se eu volto na DLL retiro o DBGrid ai o sistema fecha normal sem erro algum ... coloco o DBGrid ... o erro volta. E a mesma coisa acontece quando eu coloco um TSpeedButton ... coloco da erro na hora de fechar .. tiro ele ... nada de erro ... Alguem sabe como resolver isso?
Valeww
GOSTEI 0
Mmoreira
28/11/2006
Bom ainda estou garimpando aqui para ver se consigo solucionar o problema ...
Referente ao erro que mencionei acima este ai eu ja resolvi da seguinte maneira ... Eu tinha no sistema que chamava a DLL declarado no USES a unit:
Foi só remover que parou de dar a mensagem de erro ao fechar o sistema ... mas gostaria de contornar este problema ... pois gosto da aparencia que ela da para a aplicação.
Agora estou com outro problema ...
Adicionei um DataModulo na minha DLL, entao agora minha DLL esta assim:
No meu DataModulo eu tenho:
Um SoapConnection e um ClientDataSet ... tudo configurado como deve ser. Adicionei o DataModule no USES do meu Form .. tudo tranquilo.
Tenho um botao no meu Form com este codigo:
O registro de codigo numero 1 existe no meu banco de dados .. mas quando executo este botao simplesmente nao acontece nada ... o ClientDataSet nao abre o registro ... mas eu sei que a conexao esta funcionando porque no meu DataModule eu tenho um outro ClientDataSet onde eu posso passar comandos SQL atravez dele ... entao eu faço assim em outro botao:
Ai o registro é inserido normalmente no banco de dados ... ou seja o ClientDataSet nao da um Open mas executa o SQL. Um detalhe como descrevi aqui tudo isso dentro da DLL mas uma coisa muito importante é que fiz todo este procedimento em um aplicação normal .. sem usar a DLL .. fui la criei uma nova aplicacao ... adicionei um SoapConnection ... o ClientDataSet ... Configurei tudo e mandei abrir o registro de codigo 1 ... Funcionou perfeitamente ... ou seja ... o problema esta na DLL.
Estou usando o Delphi 7 + DBExpress + ClientDataSet ... Fiz isso tudo usando um Servidor SOAP e meu banco de dados é Firebird.
Referente ao erro que mencionei acima este ai eu ja resolvi da seguinte maneira ... Eu tinha no sistema que chamava a DLL declarado no USES a unit:
XPMan
Foi só remover que parou de dar a mensagem de erro ao fechar o sistema ... mas gostaria de contornar este problema ... pois gosto da aparencia que ela da para a aplicação.
Agora estou com outro problema ...
Adicionei um DataModulo na minha DLL, entao agora minha DLL esta assim:
library IntegraSistema;
uses
SysUtils,
Classes,
Forms,
ufrmPrincipal in ´ufrmPrincipal.pas´ ,
udmCadastro in ´udmCadastro.pas´ {dmCadastro: TDataModule},
XPMan;
{$R *.res}
var
OldApplication : TApplication;
OldScreen : TScreen;
procedure IntegraSistemaPadrao; stdcall;
begin
Application := OldApplication;
Screen := OldScreen;
// Destruir o DataModule dmCadastro caso o mesmo tenha sido criado em algum momento
if dmCadastro <> nil then dmCadastro.Destroy;
end;
procedure AbreIntegraSistema( aApplication : TApplication; sScreen : TScreen ); stdcall;
begin
if (OldApplication = nil) and (OldScreen = nil) then begin
OldApplication := Application;
OldScreen := Screen;
Application := aApplication;
Screen := sScreen;
end;
if dmCadastro = nil then begin
dmCadastro := TdmCadastro.Create(Application);
end;
if frmPrincipal = nil then begin
frmPrincipal := TfrmPrincipal.Create(Application);
frmPrincipal.Show;
end;
end;
Exports
IntegraSistemaPadrao,
AbreIntegraSistema;
begin
end.
No meu DataModulo eu tenho:
Um SoapConnection e um ClientDataSet ... tudo configurado como deve ser. Adicionei o DataModule no USES do meu Form .. tudo tranquilo.
Tenho um botao no meu Form com este codigo:
with dmCadastro.cdsEvento do begin Close; Params[0].AsInteger := 1; try Open; except on e : Exception do ShowMessage( ´erro ´ + e.Message); end; end;
O registro de codigo numero 1 existe no meu banco de dados .. mas quando executo este botao simplesmente nao acontece nada ... o ClientDataSet nao abre o registro ... mas eu sei que a conexao esta funcionando porque no meu DataModule eu tenho um outro ClientDataSet onde eu posso passar comandos SQL atravez dele ... entao eu faço assim em outro botao:
procedure TfrmPrincipal.Button2Click(Sender: TObject); begin with dmCadastro.cdsExecSql do begin Close; CommandText := ´insert into EVENTO (IDEVENTO) values (:idevento)´; Params.ParamByName( ´idevento´ ).AsInteger := 2; try Execute; except on e : Exception do ShowMessage( ´´ + e.Message); end; Close; end; end;
Ai o registro é inserido normalmente no banco de dados ... ou seja o ClientDataSet nao da um Open mas executa o SQL. Um detalhe como descrevi aqui tudo isso dentro da DLL mas uma coisa muito importante é que fiz todo este procedimento em um aplicação normal .. sem usar a DLL .. fui la criei uma nova aplicacao ... adicionei um SoapConnection ... o ClientDataSet ... Configurei tudo e mandei abrir o registro de codigo 1 ... Funcionou perfeitamente ... ou seja ... o problema esta na DLL.
Estou usando o Delphi 7 + DBExpress + ClientDataSet ... Fiz isso tudo usando um Servidor SOAP e meu banco de dados é Firebird.
GOSTEI 0
Mmoreira
28/11/2006
Quando eu coloco o SoapConnection direto no meu Form ... ai o sistema funciona perfeitamente ... mas quando volto com o SoapConnection para o DataModule ... para de funcionar.
Nossa isso ja esta me deixando maluco.
Nossa isso ja esta me deixando maluco.
GOSTEI 0