Pregunta

Estoy trabajando en un proyecto Win32 / MFC. Tengo un control de clistctrl personalizado que debo agregar, de vez en cuando, algunas cadenas de caracteres. Absolutamente necesito realizar algunas manipulaciones en los artículos agregados dinámicamente a mi Clistctrl.

Ultra-Básicamente, necesito:

  1. detectar agregando elementos individuales;
  2. recuperar _single artículos_ Inmediatamente después (idealmente, poco después de la invocación de inserción ();
  3. tienda valores de artículos individuales en un mapa, que usaré para realizar otras manipulaciones.

    Pensé en hacer esto anulando el método DRAWITEMEM (). Pero Ondraw Event parece para no estar disponible para mi clistctrl.

    evento nunca se genera.

    IMPORTANTE: Tenga en cuenta que MyCustomClistCtrl tiene la propiedad " On Draw Fixed " se establece en True , pero " Ver "La propiedad es no establecida como un informe .

    Entonces, he decidido manejar el evento NW_CustomDRAW, escribiendo mi Handler de CustomDraw, como se explica aquí y AQUÍ :

    aquí Puede ver otro ejemplo de código.

    Entonces, necesito una forma de recuperar un solo Úticamente de mi Clistctrl.
    Más precisamente, necesito una manera de obtener ID de artículo único de NMHDR STRUM .

    ¿Cómo puedo hacer esto? Solo puedo obtener la ID del artículo Último que he agregado. Estoy seguro de que es un simple error que no puedo encontrar.

    Una pieza de muestra de código a continuación:

    Fuente de diálogo que contiene 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!");
    }
    

    Mi fuente CTRL personalizada:

    /* 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;
    }
    

    ¡Se aprecia cualquier ayuda!

    P.s. Por favor, no me des consejos como:

    1. Configure su propiedad "PROPIO DE DRABAJO FIJO" a VERDADERO;
    2. Compruebe que ha insertado la línea "on_wmdrawitem ()"
    3. Convierte su clistctrl como un informe;

      Ya lo he probado todo ...: -)

      ¡Gracias a todos!

      it

¿Fue útil?

Solución 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

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top