Bueno Menu.dll no deberias implementarlo de esa forma. Lo que deberias hacer es crear un objeto en board.dll con propiedades y metodos para enumerar los dispositivos, y que este objeto (por ejemplo podria llamarse UserClass) contenga una coleccion con todos los dispositivos, sus propiedades y metodos.
La estructura seria algo asi:
BOARDS.DLL
* Clase UserClass *
- Este modulo de clase seria la interfaz entre el usuario y todos los dispositivos de hardware -
Property Get Devices(Indice) As DeviceClass
'Esta propiedad devolveria el objeto DeviceClass que contiene las propiedades y metodos para comunicarse con el dispositivo especificado en Indice. Indice puede ser un numero que identifica al dispositivo o podrias crear una funcion para buscarlo por el nombre -
End Property
Property Get DevCount() As Long
' Esta propiedad devuelve la cantidad de dispositivos de hardware -
End Property
Function EnumDeviceNames(outNames() As String) As Integer
' Esta funcion enumeraria los nombres de los dispositivos, podrias identificarlos con los nombres de las DLL o mejor, usar polimorfismo para implementar en las DLL de los dispositivos, y asi crear un objeto dinamicamente para comunicarte con ese dispositivo (mas adelante explico esto) -
End Function
Function FindDevice(Spec) As DeviceClass
' Podrias escribir una funcion que busque un dispositivo por el nombre o alguna otra propiedad -
End Function
Ahora el problema que se presenta es como comunicarse con los otros dispositivos ya que cada uno esta un una DLL diferente.
La solucion a esto es el polimorfismo, que es un concepto de la programacion orientada a objetos que permite la reutilizacion de codigo. Esto significa que yo puedo usar el mismo codigo para varias DLLs sin tener que copiarlo, lo que nos permite ampliarlo luego y uniformar un sistema.
La idea del polimorfismo para este proyecto es la siguiente:
1. Se crea una clase con todas las propiedades y metodos que tienen que tener todos los dispositivos, pero sin el codigo, solo las declaraciones (se dice que se crea la interfaz). Por ejemplo llamemosle IDevice. Entonces esta clase tendria por ejemplo las siguientes propiedades y metodos:
* Clase IDevice *
Property Get DeviceName() As String
End Property
Sub Reset()
End Sub
Sub SendVols(pin)
End Sub
Sub StopVol(pin)
End Sub
Sub SendData(pin)
End Sub
Sub GetData(pin)
End Sub
2. Creas una DLL con este modulo de clase (ninguna cosa mas a menos que se te ocurra) llamada devices.dll.
3. Cada DLL para un dispositivo tiene que incluir como referencia a devices.dll, y tener una clase predeterminada llamada DevMain que implemente al modulo IDevice (mas adelante explico como implementarlo).
Ahora supongamos que tenemos un motor paso a paso y tenemos que crear la DLL stepengine.dll para este dispositivo. Entonces creamos el proyecto DLL ActiveX y hariamos lo siguente:
1. Agregar como referencia al proyecto el archivo devices.dll
2. Crear el modulo de clase predeterminado DevMain
3. Implementar el modulo IDevice que esta en devices.dll. Para esto existe la palabra clave
Implements. Se puede usar solo a nivel de modulo en modulos de clase. En la parte de declaraciones ponemos:
Vas a notar que en la lista de objetos donde solo te aparecia Class, ahora te aparece IDevice, entonces hay que implementar cada funcion y propiedad.
En el modulo de clase quedaria algo como esto:
Private Property Get IDevice_DeviceName() As String
End Property
Private Sub IDevice_GetData(pin As Variant)
End Sub
Private Sub IDevice_Reset()
End Sub
Private Sub IDevice_SendData(pin As Variant)
End Sub
Private Sub IDevice_SendVols(pin As Variant)
End Sub
Private Sub IDevice_StopVol(pin As Variant)
End Sub
Eso significa que implementaste el modulo IDevice en DevMain de engine.dll. Ahora solo queda escribir el codigo que queramos que se ejecute para cada metodo, y crear los metodos propios de la clase.
¿esto para que sirve?, bueno antes habia dicho "unificacion", y esto quiere decir que, por ejemplo, no importa el codigo que haya que escribir en el metodo Reset de un motor paso a paso o de una licuadora (por decir algo
), siempre van a ser lo mismo para el programa. Es decir que la clase DevMain de cualquier dispositivo va a ser la misma, esto se llama polimorfismo
.
Bueno continuo con la idea. Una vez que escribis el codigo para cada metodo, y propiedad, creas las mismas propiedades y metodos para la clase, ya que cuando se implementa un modulo no forma parte de la interfaz de la clase donde se implementa.
Esta parte es sencilla porque solo llamamos a los metodos de la clase implementada:
Property Get DeviceName() As String
DeviceName = IDevice_DeviceName
End Property
Sub GetData(pin As Variant)
Call IDevice_GetData(pin)
End Sub
Sub Reset()
Call IDevice_Reset
End Sub
Sub SendData(pin As Variant)
Call IDevice_SendData(pin)
End Sub
Sub SendVol(pin As Variant)
Call IDevice_SendVol(pin)
End Sub
Sub StopVol(pin As Variant)
Call IDevice_StopVol(pin)
End Sub
Luego se le pueden agregar mas clases al dispositivo, pero esta clase tiene que ser la misma para que todos los dispositivos tengan algo en comun.
Una vez hecha la parte de dispositivos hay que enumerarlos y poder llamar a sus metodos, y esta es la parte mas sencilla.
Para enumerarlos simplemente se pueden enumerar los nombres de las DLLs, y para comprobar si son validos crear los objetos predeterminados usando la funcion GetObject.
Entonces primero se agrega como referencia a Boards.dll el archivo drivers.dll, luego en la funcion EnumDeviceNames enumeras los nombres de los archivos y los guardas en una matriz de Strings, creas una variable de tipo IDevice.
'Modulo UserClass de boards.dll
Property Get Devices(Indice) As DeviceClass
Dim csDevice As IDevice
Set csDevice = GetObject(sDriver(Indice), "DevMain")
Set Devices = csDevices
End Property
DeviceClass es una clase que se encuentra en boards.dll y tambien implementa IDevice, pero se le puede agregar mas propiedades y metodos.
Bueno espero que te haya servido.
Saludos.