transmettre une connexion DAO à un activeX
Bonjour tout le monde, je suis nouveau z'ici. J'espère que des âmes charitables auront la grâce de se pencher sur mon épineux problème. Y'en a un peu long, désolé.
Je n'arrive pas à faire passer des informations à des composants activeX "maison". Voilà la situation actuelle (qui fonctionne).
Plusieurs composants activeX ont été créés, avec Visual Basic 6.0. Ils implémentent tous une même interface, qui comprend, entre autres, la fonction suivante :
Code:
1 2 3 4 5 6 7 8
|
Public Sub InterfaceActiveX_SetNomDatabaseData(NomDatabase As String)
m_NomDatabaseData = NomDatabase
If m_ConnectData.State = adStateClosed Then
m_ConnectData.ConnectionString = NomDatabase
m_ConnectData.Open
End If
End Sub |
m_ConnectData est un objet de type Connection. Le but de chaque activeX, en gros, c'est d'aller chercher des infos dans une base de donnée et de les afficher. En théorie, c'est peut-être pas à ça que doivent servir les activeX, mais le logiciel a été fait comme ça, tout chambouler serait un peu long et fastidieux.
Après j'ai le projet principal, codé en C++ avec Visual C++ 6.0. Ce projet s'occupe d'instancier les activeX et de leur passer les bonnes informations. J'ai donc une fonction de ce genre dans ce projet :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
void CInterfaceActiveX::SetNomDatabaseData(CString sNomDatabase)
{
OLECHAR FAR* szMember = L"InterfaceActiveX_SetNomDatabaseData";
static BYTE parms[] = VTS_BSTR;
CString strChaineConnexion;
/* ici il y a du code permettant de donner la bonne valeur
à strChaineConnexion, quelque chose de ce genre :
"DRIVER={SQL Server};SERVER=machin;database=bidule;UID=truc;PWD=tralala"
*/
InvokeHelper(__GetDispID(szMember), DISPATCH_METHOD,
VT_EMPTY, NULL, parms, strChaineConnexion);
} |
Dans cette situation, tout se passe bien. Le projet principal crée un ou plusieurs activeX, il donne la chaîne de connexion, et chaque activeX va gentiment se connecter dans son coin, pour récupèrer des données et les afficher. C'est très youpi.
Le problème c'est que les activeX sont créés, puis détruits puis recréés, assez souvent durant l'exécution du logiciel. Donc on se retrouve avec des connexions de bases de données qui s'ouvrent et se ferment à chaque fois. Et la pauvre base de données a du mal. Au début on avait un gentil fichier Access en local, ça ne le dérangeait pas d'avoir des dizaines de connexion qui durent très peu de temps chacune. Mais là on va passer à une grosse base SQL sur un serveur, donc il faudrait essayer de se limiter. Une exécution du logiciel = une seule connexion.
L'idéal serait que le projet principal se connecte à la base de données (en fait il le fait déjà, car il a lui aussi besoin d'y récupérer des infos) et qu'ensuite cette connexion soit donnée aux différents activeX. La tâche d'établir la connexion doit être transférée au module de niveau supérieur. Donc mon code devrait ressembler à ça :
dans les activeX :
Code:
1 2 3 4
|
Public Sub InterfaceActiveX_SetConnectionData(ConnectData As Connection)
m_ConnectData = ConnectData
End Sub |
et dans mon projet principal :
Code:
1 2 3 4 5 6 7 8 9 10
|
void CInterfaceActiveX::SetNomDatabaseData(CString sNomDatabase)
{
OLECHAR FAR* szMember = L"InterfaceActiveX_SetConnectionData";
static BYTE parms[] = VTS_CONNECTION; //sauf que ce nom n'existe pas.
InvokeHelper(__GetDispID(szMember), DISPATCH_METHOD,
VT_EMPTY, NULL, parms, theApp.m_DatabaseData);
} |
theApp.m_DatabaseData est un objet de type CDaoDatabase. Au moment où la fonction SetNomDatabaseData est exécutée, la connexion de m_DatabaseData est déjà ouverte. Il y a d'autres parties du code qui l'utilisent avant, et ça marche très bien.
D'après ce que j'ai compris, la variable parms sert à spécifier les types de paramètres que l'on passe à la fonction exécutée par l'activeX. Dans la situation précédente, je devais passer la string de connection, donc il fallait indiquer : VTS_BSTR. On peut utiliser d'autres types assez simple, du genre VTS_I4 ou VTS_I2 pour des entiers, VTS_BOOL pour des booléens, etc... Mais je n'ai pas trouvé de nom du style VTS_CONNECTION ou VTS_DAO_CONNECTION.
J'ai essayé avec VTS_VARIANT
J'ai un message d'erreur à l'exécution, au moment où le logiciel essaie de transmettre la connexion :
"Types non correspondant"
avec VTS_UNKNOWN
message d'erreur : "L'instruction à "0x51ec8b55" emploie l'adresse mémoire "0x51ec8b55". La mémoire ne peut pas être "read". Appuyez sur OK pour fermer, sur Annuler pour déboguer."
avec VTS_PVARIANT, et en mettant comme paramètre &(theApp.m_DatabaseData) au lieu de theApp.m_DatabaseData
message d'erreur : "Types non correspondant"
Et j'ai essayé aussi en changeant la fonction InterfaceActiveX_SetConnectionData. Au lieu de déclarer le paramètre ConnectData comme une Connection, je la déclare comme un Variant.
Dans ce cas, avec VTS_VARIANT et VTS_PVARIANT, j'ai ce message d'erreur :
"La variable utilise un type Automation non géré par Visual Basic"
avec VTS_UNKNOWN
message d'erreur : "L'instruction à "0xb8fc4d89" emploie l'adresse mémoire "0xb8fc4d89". La mémoire ne peut pas être "read". Appuyez sur OK pour fermer, sur Annuler pour déboguer."
Voili voilà. Ma question est donc : puis-je transmettre à un activeX un objet représentant une connexion Dao ouverte ? Si oui comment ?
Merci d'avance pour vos réponses.