TrackPopupMenu ListView et thread [Résolu]

Messages postés
54
Date d'inscription
jeudi 20 novembre 2003
Dernière intervention
4 avril 2007
- - Dernière réponse : cs_chris91
Messages postés
54
Date d'inscription
jeudi 20 novembre 2003
Dernière intervention
4 avril 2007
- 1 août 2006 à 16:19
bonjour,

j'utilise TrackPopupMenu sur notification de clic droit avec une listview...
cela fonctionne parfaitement si aucun message n'arrive à la listview pendant l'affichage
du menu, puisque TrackPopupMenu bloque le retour de la notification.

seulement j'ai un thread qui met à jour cette listview... alors le menu s'affiche vide et plus rien, l'application ne répond plus.

j'ai donc mis TrackPopupMenu dans un thread et à chaque notification je fais un SetEvent
pour le débloquer.

le problème, c'est que le menu ne s'affiche plus.
le handle du menu (menu en ressource) qui est récupéré avec LoadMenu et GetSubMenu est valide.

TrackPopupMenu retourne de suite la valeur 0, et GetLastError renvoie 0.

j'ai mis les flags TPM_NONOTIFY | TPM_RETURNCMD, et pour le hwnd c'est le handle de la fenêtre principale.

avec NULL pour hwnd, il y a bien une erreur handle invalide...

j'ai aussi testé le handle du thread, mais le retour est toujours 0 et GetLastError renvoie aussi 0

la seule chose trouvée sur le net, c'est d'ajouter
SetForegroundWindow(hwnd);
avant et
PostMessage(hwnd, WM_NULL, 0, 0);
après TrackPopupMenu.

mais cela ne change rien... jai même ajouté une boucle de message :

DWORD WINAPI ThreadMenu(LPVOID lpParam)
{
    int iRet;
    DWORD dwErr;

    sg_tabEvents[0] = g_hExitEvent;  // event EXIT
    sg_tabEvents[1] = g_hMenuEvent;  // event MENU

    sg_hmenu = LoadMenu(g_hinst,"MENURES");  // chargement menu en ressource
    sg_hsub = GetSubMenu(sg_hmenu, 0);

    while (1)  // MSDN -> Waiting in a Message Loop
    {
        DWORD result ;
        MSG msg ;

        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT) return 1;

            DispatchMessage(&msg);
        }

        result = MsgWaitForMultipleObjects(2, sg_tabEvents, FALSE, INFINITE, QS_ALLINPUT);

        if (result == (WAIT_OBJECT_0 + 2)) continue;
        else
        {
            if(!(result - WAIT_OBJECT_0)) return 0;  // sortie sur event EXIT

            ResetEvent(g_hMenuEvent);  // reset event MENU

            iRet = TrackPopupMenu(sg_hsub, TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
                                        g_x + g_stNotify.x, g_y + g_stNotify.y, 0, g_hwnd, NULL);

            if(!iRet){ dwErr = GetLastError(); AffErrMess(dwErr); continue; }  // affichage message erreur

            // ici traitement retour TrackPopupMenu

            continue;

        }
    }
}

même avec un menu créer dans le thread, TrackPopupMenu renvoie 0, et GetLastError
infique toujours aucune erreur
peut-être que je fais fausse route :(
vraiment merci si quelqu'un a une solution, ou même une idée pour faire autrement.
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
Messages postés
54
Date d'inscription
jeudi 20 novembre 2003
Dernière intervention
4 avril 2007
3
Merci
bonjour,
c'est bon, j'ai la solution...

sans le traitement du message WM_NOTIFY, il y a un return DefWndProc et la listview envoie un message WM_CONTEXTMENU.

MSDN : The WM_CONTEXTMENU message is generated when an application's window procedure passes the WM_RBUTTONUP or WM_NCRBUTTONUP message to the DefWindowProc function.

c'est pas le code NM_RCLICK mais ça fonctionne de la même façon.

j'utilise TrackPopupMenu sans les flags TPM_NONOTIFY et TPM_RETURNCMD.
les messages du menu sont gérés normalement dans WM_COMMAND et TrackPopupMenu retourne de suite 1 ou 0.

bye.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 98 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_chris91
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
0
Merci
Salut,
TrackPopupMenu() ne devrait pas empecher la listview de
traiter ses messages, donc a mon avis faudrait plutot voir le code de
la listview et du thread qui la met à jour.
Commenter la réponse de cs_aardman
Messages postés
54
Date d'inscription
jeudi 20 novembre 2003
Dernière intervention
4 avril 2007
0
Merci
merci pour ta réponse,
le problème c'est que TrackPopupMenu est dans le message WM_NOTIFY code NM_RCLICK et il faut retourner quelque chose.
MSDN : Return nonzero to not allow the default processing, or zero to allow the default processing

tant que TrackPopuMenu ne retourne pas, comment la listview pourrait-elle recevoir des messages?
c'est pour ça que j'ai mis TrackPopupMenu dans un thread.
comment faire autrement ?
Commenter la réponse de cs_chris91
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
0
Merci
Salut,

TrackPopupMenu() contient sa propre boucle de message (comme
MessageBox() par exemple), justement pour ne pas bloquer l'affichage
des autres fenetres.
Commenter la réponse de cs_aardman
Messages postés
54
Date d'inscription
jeudi 20 novembre 2003
Dernière intervention
4 avril 2007
0
Merci
ok, mais alors je fais comment ?
dans la notification NM_RCLICK de la listeview , ça bloque si un message arrive avant un return 0

dans un thread, TrackPopupMenu ne s'affiche pas et ne renvoie pas d'erreur ?!

quand au code de la listview et du thread, c'est pas compliqué,
création de la listview
g_hlv = CreateWindowEx(0, WC_LISTVIEW, NULL,
                            WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS,
                            0, 0, 0, 0, hwnd, NULL, g_hinst, NULL);

ensuite dans le thread, quand il y a un résultat à afficher :
SendMessage(g_hlv, LVM_SETITEM, 0, (LPARAM) &lvi);
Commenter la réponse de cs_chris91
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Dernière intervention
17 septembre 2012
0
Merci
Salut,

Normalement il devrait pas y avoir de probleme quand tu appeles TrackPopupMenu() depuis NM_RCLICK.

Montre le code *complet* du thread et de la listview.
Commenter la réponse de cs_aardman

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.