Странная проблема с немодальными диалоговыми окнамиC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Странная проблема с немодальными диалоговыми окнами

Сообщение Anonymous »

У меня проблема с немодальными диалоговыми окнами. У меня есть один в цикле, который сканирует файлы в каталоге, добавляя файлы в класс связанного списка для последующей обработки. Раньше это работало нормально. Теперь, без внесения каких-либо изменений, он зависает на полпути и перестает обновляться. Я знаю, что цикл все еще выполняется, потому что по истечении определенного периода времени (того же времени, что и раньше) цикл завершается, и я вижу результаты. Иногда точка зависания перемещается, но обычно это происходит в одном и том же месте.
Странно то, что это происходит только в сборке Release. Отладочная сборка работает нормально.
Это имеет все признаки неинициализированной памяти и/или переполнения буфера, но я, хоть убей, не могу ее найти. Я провел последние три дня, анализируя цикл, пытаясь найти доказательства того, в чем проблема, но безрезультатно.
В любом случае, вот код обработчика команды. Прошу прощения за длину этого поста, но я понятия не имею, в чем я ошибаюсь, поэтому решил, что лучше опубликовать всю процедуру. Диалоговое окно обновляется в разделе «Информировать пользователя о ходе выполнения». Пожалуйста, посмотрите и посмотрите, что вы видите. Спасибо.
case ID_FILE_SCAN:
/////////////////////////////////////////////////////////////////////////////////////////////////
// Select directory and then scan, hash, and sort.
/////////////////////////////////////////////////////////////////////////////////////////////////
{
MessageBox(hWnd, _T("Navigate to the desired directory and double\n"
"click on any file to process the directory."), szTitle, MB_OK);

OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));

// Initially, _T(""), replaced by the path to scan via ofn.lpstrFile
TCHAR* pszOpenFileName = new TCHAR[MAX_PATH];
ZeroMemory(pszOpenFileName, sizeof(pszOpenFileName));

ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hWnd;
ofn.lpstrFile = pszOpenFileName;
ofn.nMaxFile = MAX_PATH;

// Save original current directory.
GetCurrentDirectory(MAX_PATH, szOldDirectoryName);

int LastAPICallLine = __LINE__ + 1;
if (!GetOpenFileName(&ofn)) // Retrieves the fully qualified file name that was selected.
{
if (CommDlgExtendedError() == 0)
{
delete[] pszOpenFileName;
break;
}
TCHAR sz[MAX_ERROR_MESSAGE_LEN];
StringCchPrintf(sz, MAX_ERROR_MESSAGE_LEN,
_T("API Error occurred at line %ld error code %ld"), LastAPICallLine, CommDlgExtendedError());
MessageBox(hWnd, sz, _T("ApplicationRegistry.cpp"), MB_OK + MB_ICONSTOP);
break;
}
ofn.lpstrFile[ofn.nFileOffset] = TCHAR('\0'); // We only want the path, so eliminate the file name.
WIN32_FIND_DATA Win32FindData;

FILETIME LocalFileTime;
SYSTEMTIME LocalSystemTime;

#define FORMATTED_FILE_DATE_LEN 11
TCHAR* pszFileDate = new TCHAR[FORMATTED_FILE_DATE_LEN];

#define FORMATTED_FILE_TIME_LEN 6
TCHAR* pszFileTime = new TCHAR[FORMATTED_FILE_TIME_LEN];

#define FORMATTED_FILE_SIZE_LEN 21
TCHAR* pszFileSize = new TCHAR[FORMATTED_FILE_SIZE_LEN];

pCHashedFiles->Reset();

// Save directory name in global array for use by other routines
StringCchCopy(szDirectoryName, MAX_PATH, ofn.lpstrFile);
SetCurrentDirectory(ofn.lpstrFile);

// Count the files in the directory.
int iTotalFiles = 0;
HANDLE hFind = FindFirstFile(_T(".\\*.*"), &Win32FindData);
if (hFind == INVALID_HANDLE_VALUE) break;
do iTotalFiles += Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 0 : 1;
while (FindNextFile(hFind, &Win32FindData) != 0);
FindClose(hFind);

// Setup to use the modeless dialog box to display progress.
dc = GetDC(hWndProgressBox);
TCHAR szFilesProcessed[100];
RECT WindowRect;
GetWindowRect(hWnd, &WindowRect);
ShowWindow(hWndProgressBox, SW_SHOW);
SetWindowPos(hWndProgressBox, HWND_NOTOPMOST, WindowRect.left + 50, WindowRect.top + 50, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
uint64_t FileSize;

// Get the first file in the directory
hFind = FindFirstFile(_T(".\\*.*"), &Win32FindData);
if (hFind == INVALID_HANDLE_VALUE)
{
ShowWindow(hWndProgressBox, SW_HIDE);
delete[] pszFileDate;
delete[] pszFileTime;
delete[] pszFileSize;
delete[] pszOpenFileName;
break;
}

BOOL bEscapePressed = false;
BytesProcessed = 0;

do
{
// Ignore subdirectories.
if (Win32FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;

// Get the last write time and format the local time equivalent of it.
FileTimeToLocalFileTime(&Win32FindData.ftLastWriteTime, &LocalFileTime);
FileTimeToSystemTime(&LocalFileTime, &LocalSystemTime);
StringCchPrintf(pszFileDate, FORMATTED_FILE_DATE_LEN, _T("%02d/%02d/%04d"),
LocalSystemTime.wMonth, LocalSystemTime.wDay, LocalSystemTime.wYear);
StringCchPrintf(pszFileTime, FORMATTED_FILE_TIME_LEN, _T("%02d:%02d"),
LocalSystemTime.wHour, LocalSystemTime.wMinute);

// Get the file size and format it.
FileSize = (uint64_t)Win32FindData.nFileSizeHigh * ((uint64_t)MAXDWORD + 1) +
(uint64_t)Win32FindData.nFileSizeLow;
StringCchPrintf(pszFileSize, FORMATTED_FILE_SIZE_LEN, _T("%9llu"), FileSize);
BytesProcessed += FileSize;

// Generate sha1 digest.
SHAFile.Process(Win32FindData.cFileName, 0, pszMessageDigest, NULL);

// Add the file information to the HashedFiles class.
pCHashedFiles->AddNode(pszMessageDigest, pszFileDate, pszFileTime, pszFileSize, Win32FindData.cFileName);

// Update the user about process.
int iPercent = (int)((float)pCHashedFiles->GetNodeCount() * 100.f / iTotalFiles + 0.5f);
StringCchPrintf(szFilesProcessed, 100,
_T("Files processed: %u %d%% of %d MBytes processed: %llu"),
pCHashedFiles->GetNodeCount(), iPercent, iTotalFiles, BytesProcessed / 1024 / 1024);
SetBkColor(dc, RGB(240, 240, 240));
TextOut(dc, 16, 16, szFilesProcessed, lstrlen(szFilesProcessed));
TextOut(dc, 16, 40, _T("Press ESC to abort."), 19);

// Check for ESC pressed - Abort if so.
MSG msg;
if (!PeekMessage(&msg, NULL, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE)) continue;
if (msg.wParam != VK_ESCAPE) continue;
pCHashedFiles->Reset();
bEscapePressed = true;
break;

} while (FindNextFile(hFind, &Win32FindData) != 0); // Process all files in the directory.

MessageBeep(MB_ICONASTERISK);
FindClose(hFind);
ReleaseDC(hWnd, dc);

// Sort by hash then file.
iSortMode = 0;
if (!bEscapePressed) pCHashedFiles->SortAndCheck(iSortMode);

// Setup initial view.
bMarked = false;
iStartNode = 0;
iSelectedFile = 0;
InvalidateRect(hWnd, NULL, true); // Generate paint message.

delete[] pszFileDate;
delete[] pszFileTime;
delete[] pszFileSize;
delete[] pszOpenFileName;

// Restore original current directory.
SetCurrentDirectory(szOldDirectoryName);

// Set a 3 second timer to close the modeless dialog box.
if (!bEscapePressed) uiTimer = SetTimer(hWnd, 1, 3000, NULL);
else uiTimer = SetTimer(hWnd, 1, 30, NULL);
}
break;

а вот код создания диалогового окна...
case WM_CREATE:
// Create the modeless dialog box - We will display it later in the process procedure
hWndProgressBox = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROGRESS_BOX), hWnd, NULL);
if (hWndProgressBox == NULL)
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(hWnd, _T("CreateDialog returned NULL"),
_T("Warning!"), MB_OK | MB_ICONEXCLAMATION);
}
break;


Подробнее здесь: https://stackoverflow.com/questions/783 ... alog-boxes
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»