Проблема с ListView и DialogBox (WinAPI)

Тема в разделе "WASM.WIN32", создана пользователем Roger, 10 май 2006.

Статус темы:
Закрыта.
  1. Roger

    Roger New Member

    Публикаций:
    0
    Регистрация:
    10 май 2006
    Сообщения:
    6
    Здравствуйте!

    Прошу помочь разобраться с такой проблемой: не изменяется количество записей ListView(не добавляются и не удаляются в процессе работы приложения), а если изменить запись, то она меняется только после щелчка на ListView.

    Список создаю так:

    В Main:

    []

    <font color="red]большой код</font><!--color-->



    Если GetListData вызвать при запуске приложения, то все работает нормально (все значения заполняются нормально). Если же, в процессе работы добавить/удалить элемент, количество элементов не изменяется! Если удалить, может появиться 2 последних элемента списка, если добавить — новый не отображается. После перезапуска программы — все нормально, все видит. Если просто изменить элемент — он обновляется только после щелчка.



    Второй вопрос.

    Вывожу диалог такой командой:

    DialogBox(g_hInst, MAKEINTRESOURCE(IDD_PASS), hWnd, PasswordDlgProc);

    Вопрос: как вывести его поверх всех окон. Пробовал SetWindowPos(hDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE) в WM_INITDIALOG, но окно вообще не появилось (у диалога в свойствах стоит выравнивание по центру)!

    Помогите, пожалуйста, мне все это побороть.

    Заранее благодарен за ответы.
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    А где break?







    А где код, который удаляет/добавляет?



    ЗЫ: Такой большой код нужно было аттачить.
     
  3. Roger

    Roger New Member

    Публикаций:
    0
    Регистрация:
    10 май 2006
    Сообщения:
    6
    А где код, который удаляет/добавляет?

    Большой код удалил Большой брат :derisive:.

    Шучу.

    Вот аттач.

    [​IMG] _41412430__code.txt
     
  4. Roger

    Roger New Member

    Публикаций:
    0
    Регистрация:
    10 май 2006
    Сообщения:
    6
    А break ниже по коду.

    Здесь не указан.
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Видел я этот код ещё до того как его удалили. Не нашёл я в нём участок, который отвечает за удаление/добавление итемов в списке. Аттачте полный код, чтоб можно было скомпилировать и нормально отладить.
     
  6. Roger

    Roger New Member

    Публикаций:
    0
    Регистрация:
    10 май 2006
    Сообщения:
    6
    М-м-м. К сожалению, полный не могу. Так что извините, я бы с радостью, но...

    Там, похоже, эти строки не отрабатывают:

    ListView_InsertItem(hwndListView, &lvi);

    ListView_Update(hwndListView,i);

    В принципе, при работе с ListView там почти все есть.

    В PSDK, MSDN я нашел либо без поддержки иконок в списке, либо с использованием SetItemsCount, что мне не подходит, так как там опять же не меняется количество записей в ходе работы.

    За основу я взял пример vlist32 (вроде так) из msdn, если у Вас его нет, я могу завтра принести (на работе у меня нет msdn). Вот его я пытался переделать под свои нужды. Пока безуспешно :-(
     
  7. ISM

    ISM Серега

    Публикаций:
    0
    Регистрация:
    20 мар 2006
    Сообщения:
    23
    Адрес:
    Transnistria


    Используй SetForegroundWindow. Эта функция часто используется в самом начале кода приложения для предотвращения запуска второго экземпляра приложения (см. макросы, прилагаемые к пакету MASM32)
     
  8. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    Кроме SWP_NOMOVE нужен ещё и SWP_NOSIZE:
    Код (Text):
    1. SetWindowPos(hDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);


    В GetListData() нет инициализации lvi.mask:
    Код (Text):
    1. lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE | LVIF_PARAM;


    Нет необходимости сразу после создания лист-вью вызывать ListView_DeleteAllItems, т.к. список на старте и так пустой.



    Обработчик LVN_ODFINDITEM у вас возвращает 0, хотя должен возвращать -1, раз он на самом деле не используется:
    Код (Text):
    1. case LVN_ODFINDITEM:
    2. return -1;
     
  9. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    То, что Вам не отвечают на этот же вопрос на RSDN, стоит принять как сигнал: просто внимательнее читать MSDN, не пропуская Remarks и возможный Example, никто за Вас это не сделает.
     
  10. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    ListView_InsertItem предназначена для обычных лист-вью и в виртуальных (со стилем LVS_OWNERDATA) не имеет особого смысла, т.к. данные всё равно не будут храниться в контроле. Так что используйте просто SetItemsCount и всю логику перекладывайте на обработчик LVN_GETDISPINFO. Или не используйте этот виртуальный стиль.





    Похоже, что я так и не узнаю каким способом удаляются или изменяются эти значения. Может они вообще не в лист-вью изменяются, а в какой-то внешней базе данных?!





    Что значит "изменить"? Где и как? После щелчка, очевидно, провоцируется LVN_GETDISPINFO.
     
  11. Roger

    Roger New Member

    Публикаций:
    0
    Регистрация:
    10 май 2006
    Сообщения:
    6
    Доброе утро!

    Спасибо за ответы!

    С диалогом я разобрался.

    Насчет ListView.

    По поводу инициализации lvi - действительно, попробую.

    Не использовать стиль - не желательно, так как нужны иконки в списке.

    Изменяются данные действительно во внешней базе, потом заполняется массив (до тех пор, пока не закончатся данные), затем необходимо данные из этого массива перенести в ListView.

    Правильно ли я Вас понимаю, что, если переделать логику по Вашему совету, то получится следующее (при добавлении/удалении элемента):

    1. GetListData сначала удаляет все элементы (ListView_DeleteAllItems), затем заполняет ТОЛЬКО массив (со списком вообще не работает).

    2. Функция, вызвавшая GetListData, после завершения последней, вызывает SetItemsCount по количеству заполненных элементов массива.

    3. Обработчик LVN_GETDISPINFO рисует элементы в списке (также, как в аттаче, только в аттаче нет работы с массивом)

    Если же изменяется запись (опять же, во внешней базе), то посылаем сообщение LVN_GETDISPINFO списку.



    Правильно ли я Вас понял?

    Аттач с vlist, про который я вчера говорил, не выкладываю, я думаю, он у Вас есть. Если это не так, напишите, обязательно приложу.

    Спасибо еще раз за Ваши ответы.
     
  12. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine


    Виртуальный листвью предназначен для работы с очень большим обьёмом данных. К примеру, если вы планируете отображать в списке миллионы данных. Иначе использовать LVS_OWNERDATA нецелесообразно. Иконки отображаются и в обычном лист-вью в стиле report. Если убрать этот LVS_OWNERDATA, не надо будет обрабатывать LVN_GETDISPINFO, что значительно упростит код.
     
  13. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




    посылается

    SendMessage( hList, LVM_REDRAWITEMS, iFirst, iLast )

    а уже сам лист после этого пришлет родителю листа getdispinfo
     
  14. Roger

    Roger New Member

    Публикаций:
    0
    Регистрация:
    10 май 2006
    Сообщения:
    6
    Всем спасибо за ответы.

    Разобрался, тему закрываю.
     
Статус темы:
Закрыта.