Как обрабатывать событие nm_customdraw, чтобы получить элементы списка

StackOverflow https://stackoverflow.com//questions/10649836

Вопрос

Я работаю над проектом Win32 / MFC. У меня есть пользовательский контроль CLISTCTRL, который я должен добавить, время от времени, некоторые строки персонажей. Я абсолютно необходимо выполнить некоторые манипуляции на предметы, динамически добавляемые в мой клистрл.

Ультра-в основном, мне нужно:

  1. определяет добавление одного элементов;
  2. Получение элементов _single_ сразу после (в идеале, вскоре после призыва () вызова);
  3. Store Значения одного элемента на карте, которые я буду использовать для выполнения других манипуляций.

    Я думал о том, чтобы сделать это переопределение метода DrawItem (). Но событие Ondraw кажется, что может быть доступен для моего клистрла.

    событие никогда не генерируется.

    Важно: Обратите внимание, что mycustomclistctcrl есть " на недвижимости" ", установленного на true , но" view «Свойство не установлено как отчет .

    Итак, я решил обрабатывать событие NW_CUSTOMDRAW, написав свой обработчик CustomDraw, как объяснил здесь и здесь :

    Здесь вы можете просмотреть другой код кода.

    Тогда мне нужен способ извлечения одиноких предметов из моего клистрла.

    Точнее, мне нужен способ получить один идентификаторы единичных элементов от NMHDR struct .

    Как я могу сделать это? Я могу получить только идентификатор элемента Last , который я добавил. Я уверен, что это простая ошибка, которую я не могу найти.

    Образец кода ниже:

    Источник диалога, который содержит CTRL 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!");
    }
    
    .

    Мой CTRL CTRL CTRL:

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

    Любая помощь приветствует!

    P.S. Пожалуйста, не дайте мне советы как:

    1. Установите свой «собственный розыгрыш фиксированным» свойством истина;
    2. Проверьте, вы вставили строку "on_wmdrawitem ()"
    3. Конвертировать свой клистрл в качестве отчета;

      Я уже пробовал все ...: -)

      Благодаря всем!

      Это

Это было полезно?

Решение 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

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top