PostThreadMessage / GetMessage : perte de messages

swonder Messages postés 9 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 7 décembre 2009 - 18 janv. 2004 à 17:12
swonder Messages postés 9 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 7 décembre 2009 - 18 janv. 2004 à 20:30
Bonjour,

J'ai un problème de perte de messages dans la communication inter-thread, que je suppose dû au fait que GetMessage n'a pas de file d'attente des messages.

Voici le code qui créé le thread et lui envoie des messages thread :

hEventThreadClavierSouris = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread [1] = CreateThread (NULL, NULL, DemarrerThreadClavierSouris, NULL, NULL, &ThreadId);
WaitForSingleObject(hEventThreadClavierSouris,INFINITE);
PostThreadMessage (ThreadId, WM_CLAVIER, NULL, NULL);
PostThreadMessage (ThreadId, WM_CLAVIER, NULL, NULL);
PostThreadMessage (ThreadId, WM_TERMINER_THREAD_CLAVIER_SOURIS, NULL, NULL);

Voici le code du thread :

DWORD WINAPI DemarrerThreadClavierSouris (LPVOID lpParam)
{
MSG msg;
bool continuer = true;

SetEvent (hEventThreadClavierSouris);

while (continuer && GetMessage(&msg, NULL, 0, 0))
{
switch (msg.message)
{
case WM_CLAVIER :
MessageBox (NULL, TEXT("WM_CLAVIER"), TEXT("WM_CLAVIER"), NULL);
break;

case WM_TERMINER_THREAD_CLAVIER_SOURIS :
MessageBox (NULL, TEXT("WM_TERMINER_THREAD_CLAVIER_SOURIS"), TEXT("WM_TERMINER_THREAD_CLAVIER_SOURIS"), NULL);
continuer = false;
break;
}
}
return TRUE;
}

Quand j'exécute tout ca, seul le premier message envoyé au thread est traité, les 2 autres rien. En me renseignant, j'ai vu que GetMessage n'a pas de file d'attente. Le problème à été momentanément résolu en faisant des sleep mais cette solution ne me plait pas du tout.

En fouinant dans la MSDN et dans les forums du site, j'ai vu qu'on pouvait utiliser des Hook, alors j'ai testé avec le code suivant :

HHOOK m_hHook;
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode<0)
goto TheEnd;

if (nCode==HC_ACTION)
{
MSG *pMsg=(MSG*)lParam;
if(pMsg->message == WM_CLAVIER)
Beep(1000,200);
return 1;
}
TheEnd:
return CallNextHookEx(m_hHook,nCode,wParam,lParam);
}

DWORD WINAPI DemarrerThreadClavierSouris (LPVOID lpParam)
{
m_hHook=SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,
(HINSTANCE) NULL,GetCurrentThreadId ());
return TRUE;
}

en supprimant la synchronisation par évenement et j'ai testé, rien...

J'ai remis la synchronisation par évenement, toujours rien.

J'ai ensuite tenté de regardé s'il rentrait dans le hook mais il n'a pas l'air de faire grand chose.

Dans la MSDN ca a pourtant l'air facile (je regrette qu'il n'y ai pas de vrai exemple dans cette base).

Ma question est donc : comment peut-on faire pour qu'un thread traite TOUT les messages qu'on lui envoie ?

Je suppose que le hook est la solution, mais alors comment procéder ? j'ai l'impression que mon code est bon mais qu'il manque un petit qqchose.

Merci d'avance.

Steve

5 réponses

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 janv. 2004 à 19:58
Le second message est perdu du fait de l'etat du thread qui est en modal loop a cause du messagebox.
BruNews, ciao...
0
swonder Messages postés 9 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 7 décembre 2009
18 janv. 2004 à 20:05
Je me doutais un peu que c'était les message box qui posait problème. Elles ne sont là que pour tester, à terme il ne devrait plus y en avoir. Tu veux donc dire que si je les supprime et que je les remplaces par autre chose (genre un fprintf dans un fichier, ou un send dans un socket) mon problème devrait être résolu ?
Merci,
Steve
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 janv. 2004 à 20:08
on va dire que CETTE source de probleme disparait, ensuite a toi de bien penser ton prog avant de l'ecrire pour ne pas creer de nouveaux pieges.
BruNews, ciao...
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 janv. 2004 à 20:12
Autre chose, tu devrais consulter Richter, la reference absolue en matiere de prog systeme sur win32.

http://perso.wanadoo.fr/persans-brunews/
JR4.zip et JR4Sources.zip

BruNews, ciao...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
swonder Messages postés 9 Date d'inscription mercredi 5 février 2003 Statut Membre Dernière intervention 7 décembre 2009
18 janv. 2004 à 20:30
Voilà je viens de finir de tester et ca m'a l'air de fonctionner.
J'ai supprimé les MessageBox par un fprintf dans un fichier de debug, et j'ai supprimé le Sleep par une synchronisation avec un évenement et un PeekMessage(NOREMOVE) juste avant pour initialiser la file des messages.

Voici le code (ptêtre que cela pourra servir à qqun d'autres).

Appelant :

hEventThreadClavierSouris = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread [1] = CreateThread (NULL, NULL, DemarrerThreadClavierSouris, NULL, NULL, &ThreadId);
WaitForSingleObject(hEventThreadClavierSouris,INFINITE);

PostThreadMessage (ThreadId, WM_CLAVIER, NULL, NULL);
PostThreadMessage (ThreadId, WM_CLAVIER, NULL, NULL);
PostThreadMessage (ThreadId, WM_TERMINER_THREAD_CLAVIER_SOURIS, NULL, NULL);

Code du thread :

DWORD WINAPI DemarrerThreadClavierSouris (LPVOID lpParam)
{
// Ajout d'une information dans le fichier de debug
AddInfoDebugFile ("DemarrerThreadClavierSouris : début");

MSG msg;
bool continuer = true;

PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
SetEvent (hEventThreadClavierSouris);
while (continuer && GetMessage(&msg, NULL, 0, 0))
{
AddInfoDebugFile ("DemarrerThreadClavierSouris : message");
switch (msg.message)
{
case WM_CLAVIER :
AddInfoDebugFile ("DemarrerThreadClavierSouris : WM_CLAVIER");
break;

case WM_TERMINER_THREAD_CLAVIER_SOURIS :
AddInfoDebugFile ("DemarrerThreadClavierSouris : WM_TERMINER_THREAD_CLAVIER_SOURIS");
continuer = false;
break;
}
}
// Fin du thread
AddInfoDebugFile ("DemarrerThreadClavierSouris : fin");
return TRUE;
}

Dans le fichier de debug on obtient ca :

18/01/2004 20:20:42 : DemarrerThreadClavierSouris : début.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : message.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : WM_CLAVIER.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : message.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : WM_CLAVIER.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : message.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : WM_TERMINER_THREAD_CLAVIER_SOURIS.
18/01/2004 20:20:42 : DemarrerThreadClavierSouris : fin.

C PARFAIT :-)

J'ai téléchargé les docs sur ton site, je les ai feuilleté vite fait et ca me sera très utile.

Merci,
Steve
0
Rejoignez-nous