Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 2
Регистрация: 10.10.2012
Сообщений: 34
1

Потеря контроля над окном (ReadDirectoryChangesW)

06.05.2014, 15:51. Показов 1057. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток! Возникла проблема.
Программа должна мониторить изменения в заданной папке. Если изменилось время записи файла - вывести название. При нажатии на кнопку, начинается мониторинг папки из поля EDIT.
C++
1
2
3
4
5
6
7
8
9
10
switch (pBufferCurrent->Action)
                        {
                        case FILE_ACTION_MODIFIED:
                            {
                                wsprintf(buf,L"Измененный файл: %s",fname);
                                SendMessage(listbox1,LB_ADDSTRING,0,(LPARAM)buf);
                                CloseHandle(hDir);
                                break;
                            }
                        }
В таком виде, как сейчас я привел код - мониторится до первого изменения.
Но если я убираю CloseHandle и break (чтобы следить постоянно), то окно программы становится некликабельно и его нельзя открыть из панели задач (как будто она зависла), то есть полностью теряется контроль над окном. Сообщения в ListBox об открытии файлов тоже не выводятся. Выводятся они только после того, как делается CloseHandle. Почему так?
Естественно, даже если идет мониторинг до первого изменения, программа тоже "зависает" до получения этого самого первого изменения и закрытия хендла папки.
Как это исправить?

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <Windows.h>
#define PUSHBUTTON_1 101
#define EDIT_1 102
#define LABEL_1 103
#define LISTBOX_1 104
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void analysis(WCHAR *dir);
HWND hwnd, button1, edit1, label1, listbox1;
HANDLE hDir;
WCHAR buf[512];
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR szCmdLine, int iCmdShow)
{
    static wchar_t szAppName[] = L"lab11";
    MSG msg;
    WNDCLASSEX wc;
    wc.cbSize = sizeof(wc);
    wc.style = CS_HREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(COLOR_BACKGROUND);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;
    wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
    RegisterClassEx(&wc);
    hwnd = CreateWindow(szAppName,L"lab11",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,450,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,iCmdShow);
    UpdateWindow(hwnd);
    while(GetMessage(&msg,0,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,WPARAM wParam, LPARAM lparam)
{
    switch (iMsg)
    {
    case WM_CREATE:
        {
            edit1 = CreateWindowEx(WS_EX_CLIENTEDGE,L"EDIT",L"",ES_CENTER|WS_CHILD|WS_BORDER|WS_VISIBLE,15,15,350,30,hwnd,(HMENU)EDIT_1,NULL,NULL);
            button1 = CreateWindow(L"BUTTON",L"Начать анализ",BS_PUSHBUTTON|ES_CENTER|WS_CHILD|WS_VISIBLE,120,55,150,30,hwnd,(HMENU)PUSHBUTTON_1,NULL,NULL);
            listbox1 = CreateWindow(L"LISTBOX",L"ListBox1",WS_CHILD|LBS_EXTENDEDSEL|WS_VISIBLE,15,90,350,300,hwnd,(HMENU)LISTBOX_1,NULL,NULL);
        }break;
    case WM_COMMAND:
        {
            if(LOWORD(wParam)==PUSHBUTTON_1)
            {
                GetWindowText(edit1,buf,(GetWindowTextLength(edit1)+1));
                MessageBox(hwnd,buf,L"Путь",MB_OK);
                hDir = CreateFile(buf,FILE_LIST_DIRECTORY,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
                DWORD BytesReturned, nBufSize = 32*1024;
                FILE_NOTIFY_INFORMATION* pBuffer = (FILE_NOTIFY_INFORMATION*)calloc(1,nBufSize);
                FILE_NOTIFY_INFORMATION* pBufferCurrent;
                WCHAR fname[100];
                while(true)
                {
                    int ret = ReadDirectoryChangesW(hDir,pBuffer,nBufSize,TRUE,FILE_NOTIFY_CHANGE_LAST_WRITE,&BytesReturned,NULL,NULL);
                    pBufferCurrent = pBuffer;
                    while(pBufferCurrent)
                    {
                        wcsncpy(fname,pBufferCurrent->FileName,pBufferCurrent->FileNameLength/2);
                        fname[pBufferCurrent->FileNameLength/2]=0;
                        switch (pBufferCurrent->Action)
                        {
                        case FILE_ACTION_MODIFIED:
                            {
                                wsprintf(buf,L"Измененный файл: %s",fname);
                                SendMessage(listbox1,LB_ADDSTRING,0,(LPARAM)buf);
                                CloseHandle(hDir);
                                break;
                            }
                        }
                        if(pBufferCurrent->NextEntryOffset)
                            pBufferCurrent = (FILE_NOTIFY_INFORMATION*)(((BYTE*)pBufferCurrent)+pBufferCurrent->NextEntryOffset);
                        else
                        {
                            pBufferCurrent = NULL;
                        }
                    }
                }
            }
        }break;
    case WM_DESTROY:
        {
            PostQuitMessage(0);
        }
    default:
        return DefWindowProc(hwnd,iMsg,wParam,lparam);
    }
    return NULL;
}
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.05.2014, 15:51
Ответы с готовыми решениями:

Курсор мыши над окном
Не могу понять как сделать так, чтобы отслеживалось положение мыши (над окном/покинуло его)....

Потеря контроля над системой
Система не реагирует почти ни на что. Потеря доступа к контролю всего оборудования. Изменения...

Запрет действий над окном
Всем доброе время суток. Как запретить действия в программе над окном? Например: Развертывание на...

Нетривиальный вопрос по издевательству над чужим окном
Есть окно чужой проги, написанной, по-моему, на VC++. У него есть статус-бар, являющийся классом...

3
567 / 198 / 70
Регистрация: 25.05.2012
Сообщений: 816
07.05.2014, 07:35 2
Цитата Сообщение от rexx_ua Посмотреть сообщение
Но если я убираю CloseHandle и break (чтобы следить постоянно), то окно программы становится некликабельно и его нельзя открыть из панели задач (как будто она зависла), то есть полностью теряется контроль над окном. Сообщения в ListBox об открытии файлов тоже не выводятся. Выводятся они только после того, как делается CloseHandle. Почему так?
Все верно, так должно быть. У вас же там бесконечный цикл, в котором находится программа. Чтобы этого избежать, нужно запускать этот мониторинг в отдельном потоке.
1
0 / 0 / 2
Регистрация: 10.10.2012
Сообщений: 34
07.05.2014, 11:49  [ТС] 3
Цитата Сообщение от dmitry94 Посмотреть сообщение
Все верно, так должно быть. У вас же там бесконечный цикл, в котором находится программа. Чтобы этого избежать, нужно запускать этот мониторинг в отдельном потоке.
то есть, по-хорошему, я должен
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
hDir = CreateFile(buf,FILE_LIST_DIRECTORY,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
                DWORD BytesReturned, nBufSize = 32*1024;
                FILE_NOTIFY_INFORMATION* pBuffer = (FILE_NOTIFY_INFORMATION*)calloc(1,nBufSize);
                FILE_NOTIFY_INFORMATION* pBufferCurrent;
                WCHAR fname[100];
                while(true)
                {
                    int ret = ReadDirectoryChangesW(hDir,pBuffer,nBufSize,TRUE,FILE_NOTIFY_CHANGE_LAST_WRITE,&BytesReturned,NULL,NULL);
                    pBufferCurrent = pBuffer;
                    while(pBufferCurrent)
                    {
                        wcsncpy(fname,pBufferCurrent->FileName,pBufferCurrent->FileNameLength/2);
                        fname[pBufferCurrent->FileNameLength/2]=0;
                        switch (pBufferCurrent->Action)
                        {
                        case FILE_ACTION_MODIFIED:
                            {
                                wsprintf(buf,L"Измененный файл: %s",fname);
                                SendMessage(listbox1,LB_ADDSTRING,0,(LPARAM)buf);
                                CloseHandle(hDir);
                                break;
                            }
                        }
                        if(pBufferCurrent->NextEntryOffset)
                            pBufferCurrent = (FILE_NOTIFY_INFORMATION*)(((BYTE*)pBufferCurrent)+pBufferCurrent->NextEntryOffset);
                        else
                        {
                            pBufferCurrent = NULL;
                        }
                    }
                }
запихнуть в отдельный CreateThread и как-то передавать данные между ними, например, при помощи пайпов?
0
567 / 198 / 70
Регистрация: 25.05.2012
Сообщений: 816
07.05.2014, 12:12 4
Ну в целом типа того. Вот ReadDirectoryChangesW и FILE_NOTIFY_INFORMATION здесь например обсуждалось как реализовать сам мониторинг.

Как передавать данные - это уже другой вопрос. Можно, например, чтобы поток создавал определенные события в определенных случаях.
1
07.05.2014, 12:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.05.2014, 12:12
Помогаю со студенческими работами здесь

Определить, над каким окном находится курсор мыши
Всем знатокам доброго времени суток! Вопрос в заглавии. Спасибо за понимание.

Как узнать, над каким окном находится курсор мыши
Добрый день! Есть такая ситуация: из проекта на Лазарусе под WinCE запускается внешнее...

Какое событие позволяет понять, что над окном двигают другое окно
Есть окно проги, которую я пишу. Мне необходимо вызывать один метод всегда, когда над окном...

Управление курсором, находящимся над окном, стилем и цветом окна (использовать dllmain)
Господа, прошу вашей помощи. Надо лабу сделать С помощью меню стандартного или плавающего...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru