TrackPopupMenu ListView et thread [Résolu]

cs_chris91 54 Messages postés jeudi 20 novembre 2003Date d'inscription 4 avril 2007 Dernière intervention - 31 juil. 2006 à 17:02 - Dernière réponse : cs_chris91 54 Messages postés jeudi 20 novembre 2003Date d'inscription 4 avril 2007 Dernière intervention
- 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
cs_chris91 54 Messages postés jeudi 20 novembre 2003Date d'inscription 4 avril 2007 Dernière intervention - 1 août 2006 à 16:19
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.

Merci cs_chris91 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 98 internautes ce mois-ci

Commenter la réponse de cs_chris91
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 31 juil. 2006 à 17:26
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
cs_chris91 54 Messages postés jeudi 20 novembre 2003Date d'inscription 4 avril 2007 Dernière intervention - 31 juil. 2006 à 18:54
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
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 31 juil. 2006 à 19:19
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
cs_chris91 54 Messages postés jeudi 20 novembre 2003Date d'inscription 4 avril 2007 Dernière intervention - 31 juil. 2006 à 21:41
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
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 1 août 2006 à 02:43
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.