Question

Je travaille sur un projet Win32 / MFC. J'ai un contrôle CLISTCTRL personnalisé que je dois ajouter, de temps en temps, des chaînes de caractères. J'ai absolument besoin d'effectuer certaines manipulations sur des articles ajoutés de manière dynamique à mon clistctrl.

ultra-fondamentalement, j'ai besoin de:

  1. détecte l'ajout d'éléments simples;
  2. récupérez _Single items_ immédiatement après (idéalement, après l'invocation insertItem ();
  3. Store valeurs d'éléments simples sur une carte, que je vais utiliser pour effectuer d'autres manipulations.

    J'ai pensé à faire cela primordial la méthode drawitem (). Mais l'événement de l'ONDRAW semble ne pas être disponible pour mon clistCtrl.

    événement n'est jamais généré.

    IMPORTANT: Veuillez noter que myCustomClistCtrl avez " sur dessiner fixe " Propriété définie sur true , mais "< Voir "La propriété est pas définie comme un rapport .

    Alors, j'ai décidé de gérer l'événement NW_CUSTOMDRAW, écrit mon gestionnaire personnalisé, comme expliqué ici et ici :

    ici Vous pouvez afficher un autre exemple de code.

    Ensuite, j'ai besoin d'un moyen de récupérer des chiffres simples de mon clistctrl.
    Plus précisément, j'ai besoin d'un moyen d'obtenir ID mono-élément à partir de la structure NMHDR .

    Comment puis-je faire cela? Je ne peux obtenir que l'identifiant de l'élément dernier que j'ai ajouté. Je suis sûr que c'est une simple erreur que je ne trouve pas.

    Un exemple de code ci-dessous:

    Source de la boîte de dialogue contenant Clist Ctrl:

    /* file MyDlg.cpp */
    
    #include "stdafx.h"
    #include "MyDlg.h"
    
    // MyDlg dialog
    
    IMPLEMENT_DYNAMIC(MyDlg, CDialog)
    
    MyDlg::MyDlg(CWnd* pParent)
        : CDialog(MyDlg::IDD, pParent)
    {
    }
    
    MyDlg::~MyDlg()
    {
    }
    
    void MyDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_LIST1, listView); /* listView is a MyCustomCListCtrl object */
    }
    
    BEGIN_MESSAGE_MAP(MyDlg, CDialog)
        ON_BN_CLICKED(IDC_BUTTON1, &MyDlg::OnBnClickedButton1) 
    END_MESSAGE_MAP()
    
    BOOL MyDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();
        return TRUE;
    }
    
    /* OnBnClickedButton1 handler add new strings to MyCustomCListCtrl object */
    
    void MyDlg::OnBnClickedButton1()
    {
        listView.InsertItem(0, "Hello,");
        listView.InsertItem(1, "World!");
    }
    

    Mon clist personnalisé Ctrl Source:

    /* file MyCustomCListCtrl.cpp */
    
    #include "stdafx.h"
    #include "MyCustomCListCtrl.h"
    
    MyCustomCListCtrl::MyCustomCListCtrl()
    {
    }
    
    MyCustomCListCtrl::~MyCustomCListCtrl()
    {
    }
    
    BEGIN_MESSAGE_MAP(MyCustomCListCtrl, CListCtrl)
        //{{AFX_MSG_MAP(MyCustomCListCtrl)
        //}}AFX_MSG_MAP
        // ON_WM_DRAWITEM()                             /* WM_DRAWITEM NON-AVAILABLE */
        ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
    END_MESSAGE_MAP()
    
    // 'Owner Draw Fixed' property is already TRUE
    /*  void CTranslatedCListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
        bool inside = true; /* Member function removed: I never enter here... */
    }  */
    
    void MyCustomCListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
        /* Here, I must retrieve single strings added to my MyCustomCListCtrl object */
    
        LPNMLISTVIEW plvInfo = (LPNMLISTVIEW)pNMHDR;
        LVITEM lvItem;
    
        lvItem.iItem = plvInfo->iItem;          /* Here I always get _the same_ ID: ID of last element...*/
        lvItem.iSubItem = plvInfo->iSubItem;    // subItem not used, for now...
    
        int MyID = 0;
    
        this->GetItem(&lvItem); // There mai be something error here?
        MyID = lvItem.iItem;
    
        CString str = this->GetItemText(MyID, 0); /* ...due to previous error, here I will always get the last string I have added("World!") */
    
        // Immediately after obtaining ALL IDS, I can Do My Work
    
        *pResult = 0;
    }
    

    Toute aide est appréciée!

    P.s. S'il vous plaît ne me donnez pas de conseils comme:

    1. Définissez votre propriété "propre dessin fixe" sur true;
    2. Vérifiez que vous avez inséré la ligne "On_wmdrawitem ()"
    3. Convertissez votre clistctrl en tant que rapport;

      J'ai déjà tout essayé ...: -)

      Merci à tous!

      IT

Était-ce utile?

La solution 2

first of all... Thank you wasted your precious time with this stupid question. I never found anything about LVN_INSERT event. I write scientific software(most on Linux platform); I am not a long-time Win32 developer, so I don't know Win32 APIs in depth. I have modified source file of MyCustomCListCtrl class, as you have suggested. Code below seems to be the best( and faster )way to achieve what I want:

    /* file MyCustomCListCtrl.cpp */

    #include "stdafx.h"
    #include "MyCustomCListCtrl.h"

    MyCustomCListCtrl::MyCustomCListCtrl()
    {
    }

    MyCustomCListCtrl::~MyCustomCListCtrl()
    {
    }

    BEGIN_MESSAGE_MAP(MyCustomCListCtrl, CListCtrl)
        //{{AFX_MSG_MAP(MyCustomCListCtrl)
        //}}AFX_MSG_MAP
        ON_NOTIFY_REFLECT(LVN_INSERTITEM, OnLvnInsertItem)
    END_MESSAGE_MAP()

    ...

    afx_msg void CTranslatedListCtrl::OnLvnInsertItem(NMHDR* pNMHDR, LRESULT* pResult)
    {
        LPNMLISTVIEW plvInfo = (LPNMLISTVIEW)pNMHDR;
        CString str = this->GetItemText(plvInfo->iItem, 0);

        // Add Some Logic

        *pResult = 0;
    }

Can You confirm? From what I can see, it seems to work. :-) Thanks again!

IT

Autres conseils

First, if you need to detect adding of single items, why don't you handle the LVN_INSERTITEM message? I mean, that's what that message is for. Handling NM_CUSTOMDRAW instead is the wrong way, since you won't necessarily get that notification if the control is hidden, your window minimized, ...

In your OnCustomDraw() you always get the same ID: that's because the list control always draws all visible items, so you get the ID of the first visible item. If you set a breakpoint there, then on the next run the control gets refreshed and the drawing starts again from the first visible item.

Note: since you're handling NM_CUSTOMDRAW, you won't get any notification of added items that are not inserted into the visible part of the control! So as I mentioned, you should handle LVN_INSERTITEM instead.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top