GustavoMurias
08-10-2010, 02:32:30
Hola gente, no encontré un hilo relacionado con el uso de dlls así que me lanzo a consultar en uno nuevo...
estoy trabajando en una aplicación MDI que se conecta a traves de un puerto serie a varios dispositivos de adquisición, cada uno con una dirección diferente. ningún problema con esto.
Para ver éstas terminales hice una interfaz gráfica dentro de una dll, que se carga en un MDIChild creado al clickear en un botón, en ese momento le asigno algunos parámetros llamando a un procedimiento exportado, al que le paso como argumento un record. el trabajo del procedimiento (dentro de la dll) es solo tomar el argumento y copiarlo en una variable global del mismo tipo, definida dentro de la dll.
El asunto que no puedo resolver es que cuando abro mas de una ventana y le paso el parámetro, se modifica la variable global en todas las ventanas hijas que haya abiertas, y por lo tanto no consigo la dependencia una ventana-una termianl.
les comento lo que hice: en la dll, dentro de la unit correspondiente al form que se mostrarà:
// declaro como una función el Form que se va a exportar
TMainFormClass = class of TMainController;
function MainFormClass: TFormClass; stdcall; export;
// declaro un procedimiento para modificar la variable y una funcion para leerla
procedure SetDvcProperties(DeviceProperties: TDvcProperties); stdcall; export;
function GetDvcProperties: TDvcProperties; stdcall; export;
// las variables globales
EditingDvc : TDvcProperties;
MainDvcDescriptor : TMainDvcDescriptor;
// luego implemento el procedimiento
procedure SetDvcProperties(DeviceProperties: TDvcProperties); stdcall;
begin
EditingDvc:= DeviceProperties;
end;
y luego en el documento library los exporto
exports MainFormClass;
exports SetDvcProperties;
exports GetDvcProperties;
Transcribo el procedimiento completo del programa principal, desde donde se llama a la dll y se coloca el form en la ventana hija
procedure THardwareLink.OpenGUI(Net, Addr: byte);
type
TMainFormClass = function: TFormClass; stdcall;
var
lMainFormClass: TMainFormClass;
Dvc: TDvcProperties;
GUIModule : string;
Wdw: byte;
begin
Wdw:= HardwareGUIOpen(Net, Addr);
if Wdw = 255 then
begin
Dvc:= FilesModule.ReadDvcProperties(Net, Addr);
GUIModule:= Dvc.GUIFile + '.dll';
FLibHandle:= LoadLibrary(PChar(GUIModule));
HardwareModule:= THardwareModule.Create(Application);
HardwareModule.Caption:= '[' + IntToStr(Dvc.Network) + '.' +
IntToStr(Dvc.Address) + '] ' +
Dvc.ZoneName + ' - ' + Dvc.PlantName;
HardwareModuleUnit.SetDvcProperties(Dvc);
lMainFormClass := GetProcAddress(FLibHandle, 'MainFormClass');
if @lMainFormClass <> nil then
begin // Create a TMainForm instance (not visible)
FLoadedForm := lMainFormClass.Create(nil); // Place the Panel from TMyForm in Panel1
FLoadedForm.Controls[0].Parent := HardwareModule.Panel1;
HardwareModule.ClientWidth:= FLoadedForm.ClientWidth;
HardwareModule.ClientHeight:= FLoadedForm.ClientHeight;
SetDvcProperties(Dvc); // acá le paso el record
end;
HardwareModule.Show;
end
else
Main.MDIChildren[Wdw].BringToFront;
end;
toda la parte que carga el form de la dll en el panel de mi form hija la tomé de un foro y funcionó bien, aunque no se a ciencia cierta que es lo que hace.
espero no haberme excedido demasiado, intento ser explícito para que resulte mas facil la solución.
muchas gracias,
Gustavo.
estoy trabajando en una aplicación MDI que se conecta a traves de un puerto serie a varios dispositivos de adquisición, cada uno con una dirección diferente. ningún problema con esto.
Para ver éstas terminales hice una interfaz gráfica dentro de una dll, que se carga en un MDIChild creado al clickear en un botón, en ese momento le asigno algunos parámetros llamando a un procedimiento exportado, al que le paso como argumento un record. el trabajo del procedimiento (dentro de la dll) es solo tomar el argumento y copiarlo en una variable global del mismo tipo, definida dentro de la dll.
El asunto que no puedo resolver es que cuando abro mas de una ventana y le paso el parámetro, se modifica la variable global en todas las ventanas hijas que haya abiertas, y por lo tanto no consigo la dependencia una ventana-una termianl.
les comento lo que hice: en la dll, dentro de la unit correspondiente al form que se mostrarà:
// declaro como una función el Form que se va a exportar
TMainFormClass = class of TMainController;
function MainFormClass: TFormClass; stdcall; export;
// declaro un procedimiento para modificar la variable y una funcion para leerla
procedure SetDvcProperties(DeviceProperties: TDvcProperties); stdcall; export;
function GetDvcProperties: TDvcProperties; stdcall; export;
// las variables globales
EditingDvc : TDvcProperties;
MainDvcDescriptor : TMainDvcDescriptor;
// luego implemento el procedimiento
procedure SetDvcProperties(DeviceProperties: TDvcProperties); stdcall;
begin
EditingDvc:= DeviceProperties;
end;
y luego en el documento library los exporto
exports MainFormClass;
exports SetDvcProperties;
exports GetDvcProperties;
Transcribo el procedimiento completo del programa principal, desde donde se llama a la dll y se coloca el form en la ventana hija
procedure THardwareLink.OpenGUI(Net, Addr: byte);
type
TMainFormClass = function: TFormClass; stdcall;
var
lMainFormClass: TMainFormClass;
Dvc: TDvcProperties;
GUIModule : string;
Wdw: byte;
begin
Wdw:= HardwareGUIOpen(Net, Addr);
if Wdw = 255 then
begin
Dvc:= FilesModule.ReadDvcProperties(Net, Addr);
GUIModule:= Dvc.GUIFile + '.dll';
FLibHandle:= LoadLibrary(PChar(GUIModule));
HardwareModule:= THardwareModule.Create(Application);
HardwareModule.Caption:= '[' + IntToStr(Dvc.Network) + '.' +
IntToStr(Dvc.Address) + '] ' +
Dvc.ZoneName + ' - ' + Dvc.PlantName;
HardwareModuleUnit.SetDvcProperties(Dvc);
lMainFormClass := GetProcAddress(FLibHandle, 'MainFormClass');
if @lMainFormClass <> nil then
begin // Create a TMainForm instance (not visible)
FLoadedForm := lMainFormClass.Create(nil); // Place the Panel from TMyForm in Panel1
FLoadedForm.Controls[0].Parent := HardwareModule.Panel1;
HardwareModule.ClientWidth:= FLoadedForm.ClientWidth;
HardwareModule.ClientHeight:= FLoadedForm.ClientHeight;
SetDvcProperties(Dvc); // acá le paso el record
end;
HardwareModule.Show;
end
else
Main.MDIChildren[Wdw].BringToFront;
end;
toda la parte que carga el form de la dll en el panel de mi form hija la tomé de un foro y funcionó bien, aunque no se a ciencia cierta que es lo que hace.
espero no haberme excedido demasiado, intento ser explícito para que resulte mas facil la solución.
muchas gracias,
Gustavo.