IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Ownerdrax Listbox et focus


Sujet :

Windows

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut Ownerdrax Listbox et focus
    Bonjour,

    j'ai crée un owner draw listbox (WIN32 pas de MFC !), mais j'ai un problème au niveau du focus, il est affiché lorsque je clique sur un élément de ma listbox, je croyais pouvoir redessiner le focus avec le message WM_DRAWITEM et bien non.
    En fait le focus est lié (je pense) aux messages WM_FOCUS et WM_LBUTTONDOWN. Si j'intercepte ces deux messages je bloque effectivement le dessin de mon focus, mais je ne recois plus le message WM_DRAWITEM.

    alors comment faire pour que je puisse dessiner ou pas, moi même, le focus sur un élément de ma listbox ?

    Merci pour votre réponse.
    Laurent

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Hum, c'est bizarre.
    Normalement, les flags de WM_DRAWITEM te disent justement s'il y a le focus ou non...

    Je sais que ça marche pour les boutons, mais je n'ai jamais joué avec des ListBox en OwnerDraw...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    Bonjour medinoc,

    effectivement pour un bouton cela fonctionne, je redessinne moi même le focus, par contre pour une list box le dessin du focus ne se fait pas sur un WM_DRAWITEM.
    Il est vrais que si on programme avec les MFC il suffit de surcharger la classe clistbox, d'intercepter WM_DRAWITEM et cela fonctionne bien, mais en WIN32 il doit falloir intercepter un autre message pour dévalider le dessin du focus tout en laissant les informations dans la structure item pour pouvoir redessinner le focus avec le message WM_DRAWITEM.
    Je continue à chercher, si je trouve je mettrais un post.
    Merci.

    Laurent

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pourtant, la doc de DRAWITEMSTRUCT dit bien que c'est ce qui se passe pour les ListBox...
    Ils précisent même l'action ODA_SELECT...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    effectivement on a aussi le type ODA_FOCUS qui permet de savoir sir l'élément en question a la focus ou non. Le problème c'est que le focus se dessine après le message WM_DRAWITEM, et non dans le message WM_DRAWITEM (comme je voudrais !), et je n'arrive pas à savoir sur quel évènement windows dessine ce focus.
    C'est peu t être ma gestion des messages qui laisse à désirer, car le message WM_DRAWITEM est traité différement. En fait ce message est envoyé du contrôleur (listbox) vers la fenêtre parent, puis je le renvoie vers le contrôleur(listbox) pour y être traité, comme pour les MFC.

    laurent

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    je viens de trouver une parade, en fin de routine WM_DRAWITEM je rajoute la ligne :
    lpDrawItemStruct->itemAction &= ~ODA_FOCUS;
    cela empêche le focus de se redessiner !
    Pourquoi ? j'sais pas trop !

    Laurent

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Comment "Renvoies"-tu le message ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    bonjour,

    voila comment je traite les messages WM_DRAWITEM (et aussi WM_MEASUREINTEM) dans la fenetre parent :

    case WM_DRAWITEM :
    lpDrawItemStruct = (DRAWITEMSTRUCT*)lParam;
    pChild = lpDrawItemStruct->hwndItem;
    SendMessage(pChild, Msg, wParam, lParam);
    break;

    Pour eviter que le message ne revienne vers la fenêtre parent, je le bloque au niveau du contrôle après traitement.

    Laurent

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je pense que tu ne devrais pas repasser par le système de message pour "renvoyer" au fils. Ou du moins, ne pas repasser par ce message-là.

    Je te conseillerais plutôt soit d'appeler directement la fonction de ta classe, soit d'envoyer un message personalisé (pas un WM_USER parce que les ListBox les utilisent, mais un WM_APP ou un message Registered)...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    Affectivement, la méthode que j'utilise meme si elle fonctionne est assez dangereuse car faut surtout pas oublier de bloquer le message sinon on a un debordement de pile.
    Je vais donc créer pour chaque classes les fonctions DrawItem, MeasureItem etc... puis les appeler a partir de la fenêtre parent comme les MFC le font.

    Merci
    Laurent

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le problème pour ça est de retrouver l'objet en partant de son HWND ou id.

    C'est pourquoi je te conseille d'employer plutôt un message perso.

    Ou bien, tu peux faire une méthode hybride, avec juste UN message perso qui retourne l'adresse de l'objet, et un appel de méthode une fois que tu as le pointeur...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    on peut faire ce genre de chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CWin* pChild=reinterpret_cast<CWin*>((HWND)(HWND)GetWindowLong(lpDrawItemStruct->hwndItem, GWL_USERDATA);
    bResult=pChild->OnDrawItem((DRAWITEMSTRUCT*)lParam  );
    Cela implique de creér toutes les classes à partir d'une même classe parent type CWin qui contient les fonctions OnDrawItem,..etc de type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    virtual BOOL OnDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct  )
    	{
    		return FALSE;
    	}
    Puis dans la classe du contrôle on vient surcharger les fonctions OnDrawItem,..etc si cela est nécessaire

    Laurent

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut

    Qu'est-ce que c'est que ces casts bizarroïdes ?


    Et ça ne marchera pas si tu as un contrôle qui n'a pas de classe dérivée de CWin.
    Un message personnel est bien plus sûr.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class CWin
    {
    public:
    	static const UINT MSG_GET_ME;
    protected:
    	HWND m_hWnd;
    	virtual LRESULT WindowProc(UINT msg, WPARAM wParam, LPARAM lParam);
    };
     
    const UINT CWin::MSG_GET_ME = RegisterWindowMessage(TEXT("CWin_Message_Get_Me"));
     
    LRESULT CWin::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam);
    {
    	LRESULT lr = 0;
     
    	switch(msg)
    	{
    	case ... :
    		break;
    	...
     
    	default:
    		//Messages "Registered"
    		if(msg==MSG_GET_ME)
    		{
    			lr = GetWindowLongPtr(m_hWnd, GWL_USERDATA);
    		} else if (msg == ... ) {
    			... /*Autres messages Registered s'il y a*/
    		} else {
    			lr = DefWindowProc(m_hWnd, msg, wParam, lParam);
    		}
    	}
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    hoops, y a un HWND de trop...

  15. #15
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 9
    Points : 1
    Points
    1
    Par défaut
    ok,

    je vais voir dans ce sens alors.
    Merci

    Laurent

Discussions similaires

  1. Focus sur listbox
    Par Turtle_fr dans le forum 4D
    Réponses: 4
    Dernier message: 11/06/2012, 13h12
  2. ListBox Bug KeyboardSelection au focus
    Par Archeone dans le forum Silverlight
    Réponses: 0
    Dernier message: 03/03/2011, 15h18
  3. mettre le focus sur une ligne de listbox
    Par Nako_lito dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 23/06/2009, 10h46
  4. focus entre deux listbox
    Par krokmitaine dans le forum Delphi
    Réponses: 6
    Dernier message: 13/12/2006, 07h18
  5. [javascript][Listbox]Perdre le focus ?
    Par mavina dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 26/06/2006, 11h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo