Здравствуйте! Прошу помочь разобраться с такой проблемой: не изменяется количество записей 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, но окно вообще не появилось (у диалога в свойствах стоит выравнивание по центру)! Помогите, пожалуйста, мне все это побороть. Заранее благодарен за ответы.
А где код, который удаляет/добавляет? Большой код удалил Большой брат . Шучу. Вот аттач. _41412430__code.txt
Видел я этот код ещё до того как его удалили. Не нашёл я в нём участок, который отвечает за удаление/добавление итемов в списке. Аттачте полный код, чтоб можно было скомпилировать и нормально отладить.
М-м-м. К сожалению, полный не могу. Так что извините, я бы с радостью, но... Там, похоже, эти строки не отрабатывают: ListView_InsertItem(hwndListView, &lvi); ListView_Update(hwndListView,i); В принципе, при работе с ListView там почти все есть. В PSDK, MSDN я нашел либо без поддержки иконок в списке, либо с использованием SetItemsCount, что мне не подходит, так как там опять же не меняется количество записей в ходе работы. За основу я взял пример vlist32 (вроде так) из msdn, если у Вас его нет, я могу завтра принести (на работе у меня нет msdn). Вот его я пытался переделать под свои нужды. Пока безуспешно :-(
Используй SetForegroundWindow. Эта функция часто используется в самом начале кода приложения для предотвращения запуска второго экземпляра приложения (см. макросы, прилагаемые к пакету MASM32)
Кроме SWP_NOMOVE нужен ещё и SWP_NOSIZE: Код (Text): SetWindowPos(hDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE); В GetListData() нет инициализации lvi.mask: Код (Text): lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE | LVIF_PARAM; Нет необходимости сразу после создания лист-вью вызывать ListView_DeleteAllItems, т.к. список на старте и так пустой. Обработчик LVN_ODFINDITEM у вас возвращает 0, хотя должен возвращать -1, раз он на самом деле не используется: Код (Text): case LVN_ODFINDITEM: return -1;
То, что Вам не отвечают на этот же вопрос на RSDN, стоит принять как сигнал: просто внимательнее читать MSDN, не пропуская Remarks и возможный Example, никто за Вас это не сделает.
ListView_InsertItem предназначена для обычных лист-вью и в виртуальных (со стилем LVS_OWNERDATA) не имеет особого смысла, т.к. данные всё равно не будут храниться в контроле. Так что используйте просто SetItemsCount и всю логику перекладывайте на обработчик LVN_GETDISPINFO. Или не используйте этот виртуальный стиль. Похоже, что я так и не узнаю каким способом удаляются или изменяются эти значения. Может они вообще не в лист-вью изменяются, а в какой-то внешней базе данных?! Что значит "изменить"? Где и как? После щелчка, очевидно, провоцируется LVN_GETDISPINFO.
Доброе утро! Спасибо за ответы! С диалогом я разобрался. Насчет ListView. По поводу инициализации lvi - действительно, попробую. Не использовать стиль - не желательно, так как нужны иконки в списке. Изменяются данные действительно во внешней базе, потом заполняется массив (до тех пор, пока не закончатся данные), затем необходимо данные из этого массива перенести в ListView. Правильно ли я Вас понимаю, что, если переделать логику по Вашему совету, то получится следующее (при добавлении/удалении элемента): 1. GetListData сначала удаляет все элементы (ListView_DeleteAllItems), затем заполняет ТОЛЬКО массив (со списком вообще не работает). 2. Функция, вызвавшая GetListData, после завершения последней, вызывает SetItemsCount по количеству заполненных элементов массива. 3. Обработчик LVN_GETDISPINFO рисует элементы в списке (также, как в аттаче, только в аттаче нет работы с массивом) Если же изменяется запись (опять же, во внешней базе), то посылаем сообщение LVN_GETDISPINFO списку. Правильно ли я Вас понял? Аттач с vlist, про который я вчера говорил, не выкладываю, я думаю, он у Вас есть. Если это не так, напишите, обязательно приложу. Спасибо еще раз за Ваши ответы.
Виртуальный листвью предназначен для работы с очень большим обьёмом данных. К примеру, если вы планируете отображать в списке миллионы данных. Иначе использовать LVS_OWNERDATA нецелесообразно. Иконки отображаются и в обычном лист-вью в стиле report. Если убрать этот LVS_OWNERDATA, не надо будет обрабатывать LVN_GETDISPINFO, что значительно упростит код.
посылается SendMessage( hList, LVM_REDRAWITEMS, iFirst, iLast ) а уже сам лист после этого пришлет родителю листа getdispinfo