|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Win32 API - Текст в ListView и проч. |
|
Win32 API - Текст в ListView и проч.
|
Ветеран Сообщения: 1180 |
Профиль | Отправить PM | Цитировать
1. Это только у меня ListView в режиме LVS_REPORT отображает только примерно 100 символов в ячейке, или у всех так? хранит ведь полностью строчку
2. я так и не понял, в каких случаях ReadDirectoryChanges возвращает несколько записей и почему они все одинаковые? дальше приведён кусочек кода с комментариями. Он опирается на STL и самописную библиотеку напоминающую упрощённую смесь QT и Swing class DirectoryChanges // класс для ReadDirectoryChangesW { HANDLE fdirectory; OVERLAPPED foverlapped; vector<unsigned char> fbuffer; // буфер 4К для чтения StringEvent* fevent; // класс с одной пустой виртуальной функцией virtual void put(const wstring&) = 0; void restart(); static void __stdcall _competed(unsigned long, unsigned long, OVERLAPPED*); // FileIoCompletionRoutine public: DirectoryChanges(const wstring& dir); ~DirectoryChanges(); void setEvent(StringEvent* event) {fevent=event;} }; // каждый раз, при появлении данных, в ListView добавляется строчка // вследтсвие вызова fevent->put() DirectoryChanges::DirectoryChanges(const wstring& dir) : fdirectory(CreateFile ( // кусок прямо из хелпа dir.c_str(), FILE_LIST_DIRECTORY, // access (read-write) mode FILE_SHARE_READ|FILE_SHARE_DELETE, // share mode 0, // security descriptor OPEN_EXISTING, // how to create FILE_FLAG_OVERLAPPED|FILE_FLAG_BACKUP_SEMANTICS, // file attributes 0)), // file with attributes to copy foverlapped (), fbuffer (4096) { if (fdirectory==(HANDLE)-1) { ostringstream ss; ss << "DirectoryChanges::DirectoryChanges error=" << GetLastError(); throw runtime_error(ss.str()); } foverlapped.hEvent = reinterpret_cast<HANDLE>(this); // т.к. не используется в FileIoCompletionRoutine, микрософт не против } DirectoryChanges::~DirectoryChanges() { // stopListening(); CloseHandle(fdirectory); } void __stdcall DirectoryChanges::_competed(unsigned long code, unsigned long bytes_transfered, OVERLAPPED* ovlp) { // это место выполняется "асинхронным вызовом процедуры", в главном цикле, который обрабатывает сообщения, // функцией MsgWaitForMultipleObjectsEx. if (code==0) { try { // разглядываем что прочитали DirectoryChanges* this1 = reinterpret_cast<DirectoryChanges*>(ovlp->hEvent); FILE_NOTIFY_INFORMATION* info = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(&this1->fbuffer[0]); if (this1->fevent) { // 1. для начала посмотрим в виде HEX wostringstream ss; ss.fill('0'); ss.flags(ios::hex|ios::fixed); for (unsigned n=0; n<bytes_transfered; ++n) { ss << ' '; ss.width(2); ss << unsigned(this1->fbuffer[n]); } // выводим полученную строчку в ListView this1->fevent->put(ss.str()); // теперь разбираем результат, как написано в хелпе for (;;) // назовём его "цикл №2" { // закидываем строчку в ListView // опытным путём нашёл, что info->FileNameLength измеряется в байтах this1->fevent->put(wstring(info->FileName, info->FileNameLength>>1)); if (!info->NextEntryOffset) break; // типа если дошли до конца info = reinterpret_cast<FILE_NOTIFY_INFORMATION*>( // продвигаем указатель reinterpret_cast<char*>(info) + info->NextEntryOffset); } this1->restart(); // когда закончили с буфером, отправляем читать дальше } } // подстраховка, чтобы не порушить стек MsgWaitForMultipleObjectsEx // потому что у моего компилятора не сильно совместимая система откатов от исключений catch (exception& e) { MessageBoxA(0, e.what(), 0, MB_OK); } catch (...) { } } } void DirectoryChanges::restart() { // читаем всё сподряд if (!ReadDirectoryChangesW(fdirectory, &fbuffer[0], fbuffer.size(), true, FILE_NOTIFY_CHANGE_DIR_NAME| FILE_NOTIFY_CHANGE_FILE_NAME| FILE_NOTIFY_CHANGE_ATTRIBUTES| FILE_NOTIFY_CHANGE_SIZE| FILE_NOTIFY_CHANGE_LAST_WRITE| FILE_NOTIFY_CHANGE_LAST_ACCESS| FILE_NOTIFY_CHANGE_CREATION| FILE_NOTIFY_CHANGE_SECURITY, 0, &foverlapped, _competed)) { ostringstream ss; ss << "DirectoryChanges::start error=" << GetLastError(); throw runtime_error(ss.str()); } } class Form1 : public Form { struct event1 : StringEvent { Form1* form; event1(Form1* f) : form(f) {} void put(const wstring&); }; ListView view1; DirectoryChanges directory_changes; struct event1 event1; public: Form1(); //void perform(Message&); }; void Form1::event1::put(const wstring& s) { // void ListView::insertItem(/*позиция*/ control_Id, /*то,что я пожелаю*/ application_Id, /*строчка*/ text, /*ну ещё там кой-чего, инициализируется по умолчанию*/); form->view1.insertItem(0, 0, s); // чистый API: читаю, что записалось в ListView (может он урезал строчку?) vector<wchar_t> buf(4096); LV_ITEM lvi = LV_ITEM(); lvi.mask = LVIF_TEXT; lvi.pszText = &buf[0]; lvi.cchTextMax = buf.size(); unsigned size1 = SendMessage(form->view1.handle(), LVM_GETITEMTEXT, 0, long(&lvi)); // дублирую lvi.iSubItem = 2; SendMessage(form->view1.handle(), LVM_SETITEMTEXT, 0, long(&lvi)); // сколько же информации я прочитал? wostringstream ss; ss << size1; // ListView::setItemText(unsigned control_id, unsigned control_col_Id, const wstring& str); form->view1.setItemText(0, 1, ss.str()); // когда это место было раскомментировано, я убедился, что строчка хранится в ListView полностью // но тогда начинал "глючить" ReadDirectoryChangesW. Он каждый следующий раз говорил, что // изменится мой project1 Debug.exe, причём количество одинаковых записей увеличивалось на 1. // то есть первый раз выдалась одна запись // второй раз 2 одинаковые ("цикл №2" сработал 2 раза) // и так далее, в бесконечном цикле //MessageBox(0, &buf[0], 0, MB_OK); } Form1::Form1() : view1 (*this, ListView::style_report), directory_changes(wstr("d:\\")), event1 (this) { directory_changes.setEvent(&event1); directory_changes.start(); // ListView::insertColumn(unsigned column_Id, const wstring& str, unsigned width, ...) view1.insertColumn(0, wstr("Directory"), 5000); view1.insertColumn(1, wstr("Size"), 100); view1.insertColumn(2, wstr("Directory 2"), 5000); setCenter(&view1); // ну типа растягивается теперь на всю форму } |
|
Отправлено: 22:54, 06-11-2007 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать более продолжительные тесты показали, что ReadDirectoryChangesW может выдавать разные сообщения за один присест. По ходу дела он эти сообщения накапливает у себя. А вот с ListView пока не понял.
|
Отправлено: 12:36, 07-11-2007 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
[решено] Как переместить выделенную строку ListView | malev | AutoIt | 3 | 15-11-2009 12:29 | |
[решено] Сортировка данных ListView по столбцам | malev | AutoIt | 3 | 16-10-2009 17:53 | |
Интерфейс - Как убрать файл, правка. вид и проч. | inkviz | Microsoft Windows 2000/XP | 0 | 10-06-2009 00:16 | |
C/C++ - [решено] Вставка иконки в ListView (Builder) | ganselo | Программирование и базы данных | 1 | 01-06-2009 12:24 | |
ListView редактирование столбцов | lesco | Программирование и базы данных | 2 | 11-04-2003 22:23 |
|