Automation Access : exécution de macro

Résolu
cs_nico_44 Messages postés 13 Date d'inscription vendredi 21 juillet 2006 Statut Membre Dernière intervention 6 mai 2013 - 12 mars 2008 à 11:53
cs_nico_44 Messages postés 13 Date d'inscription vendredi 21 juillet 2006 Statut Membre Dernière intervention 6 mai 2013 - 12 mars 2008 à 16:48
Bonjour à toutes et à tous,

Dans une application développée en VC++ 2005, je pilote une application
Access 2003 qui me gère essentiellement mes impressions.

Avant certaines impressions, j'ai besoin d'exécuter certaines fonctions de
traitement. J'ai donc tout regroupé dans des macros, qui appellent ces
fonctions et affichent ou impriment mes états. Depuis C++, je n'ai donc plus
qu'à appeler les différentes macros, par le biais de la commande suivante :

HRESULT hr = pAccess->DoCmd->RunMacro(szMacro);

Mon problème vient du fait que certaines fonctions appelées dans mes macros
Access peuvent mettre un temps assez long pour s'exécuter (plusieurs dizaines
de secondes).
Et quand C++ estime que le temps d'exécution de ma macro est trop long, il
m'affiche une boite de dialogue "Serveur Occupé" avec le message "Impossible
de terminer cette action car le programme "MaBaseAccess" ne répond pas.
Choisissez Basculer vers et corrigez le problème." avec comme bouton
"Basculer vers..." et "Réessayer".
En cliquant plusieurs fois sur le bouton réessayer, mon état fini par
s'afficher ou s'imprimer.

Voici donc ma question : comment faire pour empêcher l'apparition de cette
boite de dialogue. Y-a-t'il un timer à régler? Peut-on indiquer à C++
d'attendre indéfiniment la fin de l'exécution de la commande? Ou dois-je
carrément procéder autrement?

Merci d'avance pour vos réponses.

2 réponses

cs_nico_44 Messages postés 13 Date d'inscription vendredi 21 juillet 2006 Statut Membre Dernière intervention 6 mai 2013
12 mars 2008 à 16:48
J'ai trouvé une autre solution, j'empêche l'affiche de cette boite de dialogue !

Il suffit de mettre le code suivant dans la fonction InitInstance de l'application (juste après l'appel de la fonction AfxOleInit) :

COleMessageFilter* pOleMsgFilter = AfxOleGetMessageFilter();
if (pOleMsgFilter)
{
pOleMsgFilter->Revoke();
pOleMsgFilter->EnableBusyDialog(FALSE);
pOleMsgFilter->EnableNotRespondingDialog(FALSE);
pOleMsgFilter->Register();
}


J'avais déjà essayé la solution du thread, mais le message apparaissait quand même. En effet, celà est dû la méthode d'appel COM.
J'aurais aussi pû augmenter le délai d'affichage de la fenêtre en utilisant AfxOleGetMessageFilter()->SetMessagePendingDelay(nTimeout), mais dans mon cas, ça ne répondait au problème.

Pour ceux qui veulent plus de précision : http://support.microsoft.com/kb/248019/en-us

Merci quand même de t'être penché sur mon problème ;)
3
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
12 mars 2008 à 14:50
Essaye en lancant ta fonction dans un Thread (CreateThread) puis attd que ton thread s'arrete avec WaitForSingleObject

HANDLE hThread;
DWORD dwExitCode;
hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)pAccess->DoCmd->RunMacro, szMacro, 0, 0);
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwExitCode);
if(dwExitCode) //...
CloseHandle(hThread);

Neo_Fr
0
Rejoignez-nous