Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

CListCtrl: при добавлении 32-го элемента вылетает

321
22 января 2004 года
Doomych
124 / / 20.01.2000
Код такой (место вылета обозначено "/*!!*/"):
Код:
// *.h
CListCtrl m_listView; // окно списка "Сертификаты"
LV_ITEM *m_lvItem; // структура класса CListCtrl - просмотровое окно списка "Сертификаты"

// *.cpp
void COttsView::CreateCertificatesLV()
{
    .........
    // Координаты и размеры просмотрового окна списка
    m_listView.Create(WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER |
        LBS_NOTIFY | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS,
        CRect(0, 0, appRect.Width() - 4, appRect.Height() - 4), this, IDC_MAIN_LV); // просмотровое окно списка

    // Формируем колонки
    LV_COLUMN lvColumn;
    lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
    lvColumn.fmt = LVCFMT_LEFT;
    lvColumn.cx = 150;
    lvColumn.iSubItem = 0;
    lvColumn.pszText = "№ сертификата";
    m_listView.InsertColumn(0, &lvColumn);

    lvColumn.cx = 110;  lvColumn.iSubItem = 1;  lvColumn.pszText = "Объект";
    m_listView.InsertColumn(1, &lvColumn);
   
    lvColumn.cx = 100;  lvColumn.iSubItem = 2;  lvColumn.pszText = "Шасси";
    m_listView.InsertColumn(2, &lvColumn);
   
    lvColumn.cx = 80;   lvColumn.iSubItem = 3;  lvColumn.pszText = "Срок действия";
    m_listView.InsertColumn(3, &lvColumn);

    lvColumn.cx = 75;   lvColumn.iSubItem = 4;  lvColumn.pszText = "Тип";
    m_listView.InsertColumn(4, &lvColumn);

    lvColumn.cx = 150;  lvColumn.iSubItem = 5;  lvColumn.pszText = "Примечание";
    m_listView.InsertColumn(5, &lvColumn);

    FillListView(); // заполняем список строками
    .........
}

void COttsView::FillListView()
{
    m_lvItem->mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE;
    m_lvItem->state = 0;
    m_lvItem->stateMask = 0;
    m_listView.SetItemCount(m_pSet->GetRecordCount() + 1); // для лучшего перераспределения памяти

    int i = 0;
    while ( !m_pSet->IsEOF() )
    {
        AddOrChangeItem(TRUE, i); // добавляем в таблицу строку и заполняем ее
        m_pSet->MoveNext();
        i++;
    }
    .........
}

void COttsView::AddOrChangeItem(BOOL bIsAdd, int itemNum)
{
    .........
    // ID
    m_lvItem->iItem = itemNum;
    m_lvItem->iSubItem = 0;
    m_lvItem->pszText = "000";
    m_listView.SetItem(m_lvItem);
/*!!*/  m_listView.InsertItem(m_lvItem); // !!!!!! вылетает здесь на 32-м цикле !!!!!!
    // Объект сертификации
    m_listView.SetItemText(itemNum, 1, "111");
    // Шасси
    m_listView.SetItemText(itemNum, 2, "222");
    // Срок действия
    m_listView.SetItemText(itemNum, 3, "333");
    // Тип сертификата (ОТТС/ сертификат)
    m_listView.SetItemText(itemNum, 4, "444");
    // Примечание
    m_listView.SetItemText(itemNum, 5, "555");
    .........
}

Спасибо всем, кто поможет!
527
22 января 2004 года
pavor
275 / / 28.09.2003
БД как я понимаю. В коде особо не разбирался, привожу свой.

class CCoaDlg
{
...
CMyDoc *m_pDocument;
CListCtrl CoaList;
bool Filling;
...
};

BOOL CCoaDlg::OnInitDialog()
{
CDialog::OnInitDialog();

Filling = true;

CoaList.InsertColumn(0, "ФИО", LVCFMT_LEFT, 192, 0);
CoaList.InsertColumn(1, "Звание", LVCFMT_LEFT, 224, 1);

if (!m_pDocument->CoaSet.IsEmpty())
{
m_pDocument->CoaSet.MoveFirst();

int i = 0;
do
{
CoaList.InsertItem(LVIF_TEXT | LVIF_STATE, i, m_pDocument->CoaSet.m_coaSurname + ' ' + m_pDocument->CoaSet.m_coaInitials,
m_pDocument->CoaSet.m_coaID == m_coaID ? LVIS_SELECTED : 0, LVIS_SELECTED, 0, 0);

CoaList.SetItemData(i, m_pDocument->CoaSet.m_coaID);

CoaList.SetItemText(i, 1, m_pDocument->CoaSet.m_coaTitle);
m_pDocument->CoaSet.MoveNext();
i++;
}
while (!m_pDocument->CoaSet.IsEOF());

m_pDocument->CoaSet.FindPrimary(m_coaID);
}

Filling = false;

return TRUE;
}
321
23 января 2004 года
Doomych
124 / / 20.01.2000
Попробовал. Все равно вылетает. И тоже на InsertItem(), и тоже на 32-й строке. Чудеса, типа.
Вообще, приведенный в моем вопросе код (вернее, его суть) я уже использовал в другом приложении, и там все работает...
527
23 января 2004 года
pavor
275 / / 28.09.2003
Цитата:
Originally posted by Doomych
Попробовал. Все равно вылетает. И тоже на InsertItem(), и тоже на 32-й строке. Чудеса, типа.
Вообще, приведенный в моем вопросе код (вернее, его суть) я уже использовал в другом приложении, и там все работает...


Значит причина не в коде, т.к. у меня все тоже великолепно работает. Попробуй создать заново проект -- бывают глюки. Или вирус у тебя. В общем причина где-то рядом.

321
27 января 2004 года
Doomych
124 / / 20.01.2000
Ну, ты, барин, задачку задал! Проект был почти готов!
Ладно, по-порядку. Создание проекта заново не помогло. Проблема оказалась в другом: Сообщения окну списка я обрабатывал в OnNotify().
Код:
BOOL COttsView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    if ( m_bIsDBOpen == false ) // если БД не была открыта
        return CFormView::OnNotify(wParam, lParam, pResult);

    LV_DISPINFO* lv_dispInfo = (LV_DISPINFO*) lParam;
    NMLVKEYDOWN* nmlvKeyDown = (NMLVKEYDOWN*) lParam; // для отлова нажатия клавиш

    ......

    // Двойной клик на строке или нажатие F2 или Пробела
    if ( lv_dispInfo->hdr.code == LVN_ITEMACTIVATE || nmlvKeyDown->wVKey == VK_F2 ||
        nmlvKeyDown->wVKey == VK_SPACE )
    {
        ......
    }
   
    // Нажатие Delete
    if ( nmlvKeyDown->wVKey == VK_DELETE )
    {
        ......
    }
    ......

    return CFormView::OnNotify(wParam, lParam, pResult);
}

Так вот. При числе записей более 32 нажатие пробела (VK_SPACE) обрабатывается не только при, собственно, нажатии, но и еще в каких-то неподходящих ситуациях. Кстати, аналогичная ситуация беда обнаружилась и с VK_DELETE (пришлось для него назначить акселератор).
Если кто-то может прокомментировать, пишите!
321
17 февраля 2004 года
Doomych
124 / / 20.01.2000
Все, я разобрался. Никаких глюков. Чисто моя вина.
В общем, я обрабатывал нажатия конкретных клавиш при каждом срабатывании OnNotify(), а надо - только при сообщении LVN_KEYDOWN.
Например, вместо
 
Код:
// Нажатие Delete
    if ( nmlvKeyDown->wVKey == VK_DELETE )
    {
        ......
    }

надо писать:
 
Код:
// Нажатие Delete
    if ( nmlvKeyDown->wVKey == LVN_KEYDOWN && nmlvKeyDown->wVKey == VK_DELETE )
    {
        ......
    }
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог