TrackPopupMenu ListView et thread

Résolu
cs_chris91 Messages postés 54 Date d'inscription jeudi 20 novembre 2003 Statut Membre Dernière intervention 4 avril 2007 - 31 juil. 2006 à 17:02
cs_chris91 Messages postés 54 Date d'inscription jeudi 20 novembre 2003 Statut Membre 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.

6 réponses

cs_chris91 Messages postés 54 Date d'inscription jeudi 20 novembre 2003 Statut Membre Dernière intervention 4 avril 2007
1 août 2006 à 16:19
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.
3
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 juil. 2006 à 17:26
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.
0
cs_chris91 Messages postés 54 Date d'inscription jeudi 20 novembre 2003 Statut Membre Dernière intervention 4 avril 2007
31 juil. 2006 à 18:54
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 ?
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 juil. 2006 à 19:19
Salut,

TrackPopupMenu() contient sa propre boucle de message (comme
MessageBox() par exemple), justement pour ne pas bloquer l'affichage
des autres fenetres.
0

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

Posez votre question
cs_chris91 Messages postés 54 Date d'inscription jeudi 20 novembre 2003 Statut Membre Dernière intervention 4 avril 2007
31 juil. 2006 à 21:41
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);
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
1 août 2006 à 02:43
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.
0
Rejoignez-nous