Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef UNICODE
- #define UNICODE
- #endif
- #include <Windows.h>
- #include <CommCtrl.h>
- #include <string>
- #include <iostream>
- #include <vector>
- #include <unordered_map>
- #include <fstream>
- #include <ctime>
- #define LoadFilesButtonClicked 0x1
- #define SortFilesButtonClicked 0x2
- #define SCREEN_WIDTH GetSystemMetrics(SM_CXSCREEN)
- #define SCREEN_HEIGHT GetSystemMetrics(SM_CYSCREEN)
- struct FileData {
- std::wstring fileName;
- std::wstring fileSize;
- };
- //g for global
- std::vector<FileData> gFilesVector;
- HWND hEdit, hListViewLeft, hListViewRight, hLoadButton, hSortButton;
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- void AddColumns(HWND hListView)
- {
- LVCOLUMN lvCol = { };
- lvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
- lvCol.cx = 50;
- lvCol.pszText = (LPWSTR)L"Index";
- ListView_InsertColumn(hListView, 0, &lvCol);
- RECT rect;
- GetWindowRect(hListView, &rect);
- lvCol.cx = (rect.right - rect.left) / 2;
- lvCol.pszText = (LPWSTR)L"File Name";
- ListView_InsertColumn(hListView, 1, &lvCol);
- lvCol.cx = (rect.right - rect.left) / 2 - 50;
- lvCol.pszText = (LPWSTR)L"File Size";
- ListView_InsertColumn(hListView, 2, &lvCol);
- }
- void AddItemToListView(HWND hListView, FileData* fileData)
- {
- LVITEM lvItem = { };
- lvItem.mask = LVIF_TEXT;
- int index = ListView_GetItemCount(hListView);
- lvItem.iItem = index; //index should start with the next Item
- std::wstring indexStr = std::to_wstring(index + 1);
- lvItem.pszText = (LPWSTR)indexStr.c_str();
- ListView_InsertItem(hListView, &lvItem);
- ListView_SetItemText(hListView, index, 1, (LPWSTR)fileData->fileName.c_str());
- ListView_SetItemText(hListView, index, 2, (LPWSTR)fileData->fileSize.c_str());
- }
- std::wstring GenerateUniqueFileName(const std::wstring& baseName,
- std::unordered_map<std::wstring, int>& gNameCount)
- {
- std::wstring uniqueName = baseName;
- int count = gNameCount[baseName];
- if (count > 0) {
- uniqueName = baseName + L"[" + std::to_wstring(count) + L"]";
- }
- gNameCount[baseName]++;
- return uniqueName;
- }
- void LogError(std::wofstream& logFile, const std::wstring& message) {
- std::time_t currentTime = std::time(nullptr);
- std::tm localTime;
- localtime_s(&localTime, ¤tTime);
- wchar_t timeBuffer[80];
- wcsftime(timeBuffer, sizeof(timeBuffer) / sizeof(wchar_t), L"%Y-%m-%d %H:%M:%S", &localTime);
- logFile << L"[" << timeBuffer << L"] " << message << std::endl;
- }
- void LoadFilesData(HWND hListView, const std::wstring directoryPath,
- std::vector<FileData>& files, std::unordered_map<std::wstring, int> &gNameCount,
- std::wofstream &errorLogFile)
- {
- WIN32_FIND_DATA data;
- std::wstring searchPath = directoryPath + L"//*";
- HANDLE hFind = FindFirstFile(searchPath.c_str(), &data);
- if (hFind == INVALID_HANDLE_VALUE) {
- DWORD errorCode = GetLastError();
- std::wstring errorMessage = L"Error when getting files from directory: " + directoryPath +
- L". Error Code: " + std::to_wstring(errorCode);
- //std::wcout << errorMessage << std::endl;
- LogError(errorLogFile, errorMessage);
- return;
- }
- do {
- if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if (wcscmp(data.cFileName, L".") != 0 && wcscmp(data.cFileName, L"..") != 0) {
- const std::wstring newDirPath = directoryPath + L"//" + data.cFileName;
- LoadFilesData(hListView, newDirPath, files, gNameCount, errorLogFile);
- }
- }
- else {
- FileData fileData;
- std::wstring baseName = data.cFileName;
- fileData.fileName = GenerateUniqueFileName(baseName, gNameCount);
- ULONGLONG fileSize = ((ULONGLONG)data.nFileSizeHigh << 32) + data.nFileSizeLow;
- fileData.fileSize = std::to_wstring(fileSize) + L" bytes";
- gFilesVector.push_back(fileData);
- }
- } while (FindNextFile(hFind, &data) != 0);
- FindClose(hFind);
- }
- void Swap(int i, int j)
- {
- auto temp = gFilesVector[i];
- gFilesVector[i] = gFilesVector[j];
- gFilesVector[j] = temp;
- }
- int Partition(int left, int right)
- {
- auto pivot = gFilesVector[left].fileSize.c_str();
- int j = left;
- for (int i = left + 1; i <= right; i++)
- {
- if (wcscmp(gFilesVector[i].fileSize.c_str(), pivot) <= 0)
- {
- j++;
- Swap(i, j);
- }
- }
- Swap(left, j);
- return j;
- }
- void QSort(int left, int right)
- {
- while (left < right)
- {
- int pivotIndex = Partition(left, right);
- if (pivotIndex - left <= right - pivotIndex)
- {
- QSort(left, pivotIndex - 1);
- left = pivotIndex + 1;
- }
- else
- {
- QSort(pivotIndex + 1, right);
- right = pivotIndex - 1;
- }
- }
- }
- enum class SortDirection { Ascending, Descending };
- void RadixSortStrings(std::vector<FileData>& array, SortDirection sortDirection)
- {
- if (array.size() < 2)
- return;
- int maxLength = 0;
- for (const auto& item : array) {
- int size = static_cast<int>(item.fileSize.length());
- maxLength = size > maxLength ? size : maxLength;
- }
- wchar_t maxChar = 0;
- for (const auto& item : array) {
- for (const auto& ch : item.fileSize) {
- maxChar = ch > maxChar ? ch : maxChar;
- }
- }
- maxChar++;
- std::vector<FileData> output(array.size());
- std::vector<int> count(maxChar, 0);
- for (int digit = maxLength - 1; digit >= 0; digit--)
- {
- std::fill(count.begin(), count.end(), 0);
- for (const auto& item : array)
- {
- int bucketIndex = digit < item.fileSize.length() ? item.fileSize[digit] : 0;
- count[bucketIndex]++;
- }
- for (int i = 1; i < maxChar; i++)
- {
- count[i] += count[i - 1];
- }
- if (sortDirection == SortDirection::Ascending)
- {
- for (int i = array.size() - 1; i >= 0; i--)
- {
- int bucketIndex = digit < array[i].fileSize.length() ? array[i].fileSize[digit] : 0;
- output[--count[bucketIndex]] = array[i];
- }
- }
- else
- {
- for (int i = 0; i < array.size(); i++)
- {
- int bucketIndex = digit < array[i].fileSize.length() ? array[i].fileSize[digit] : 0;
- output[--count[bucketIndex]] = array[i];
- }
- }
- for (int i = 0; i < array.size(); i++)
- {
- array[i] = output[i];
- }
- }
- }
- void RadixSort(std::vector<FileData>& array, SortDirection sortDirection = SortDirection::Ascending)
- {
- RadixSortStrings(array, sortDirection);
- }
- void SortListView(HWND hListView)
- {
- if (gFilesVector.size() > 0) {
- ListView_DeleteAllItems(hListView);
- //QSort(0, gFilesVector.size() - 1);
- RadixSort(gFilesVector);
- SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
- size_t size = gFilesVector.size();
- for (auto i = 0; i < size; i++) {
- AddItemToListView(hListView, &gFilesVector[i]);
- }
- SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
- }
- else {
- MessageBox(hListView, L"Fill your left table!", L"Error", MB_ICONERROR);
- }
- }
- void PrepareListView(HWND hListView)
- {
- wchar_t directoryPath[MAX_PATH] = { 0 };
- GetWindowTextW(hEdit, directoryPath, MAX_PATH);
- WIN32_FIND_DATA data;
- std::wstring searchPath = std::wstring(directoryPath) + L"\\*";
- HANDLE hFind = FindFirstFile(searchPath.c_str(), &data);
- if (hFind == INVALID_HANDLE_VALUE || searchPath == L"\\*") {
- MessageBox(hListView, L"Enter existing directory path!", L"Error", MB_ICONERROR);
- return;
- }
- ListView_DeleteAllItems(hListView);
- std::wofstream errorLogFile(L"D://errors.log.txt", std::ios::app);
- gFilesVector = { };
- std::unordered_map<std::wstring, int> gNameCount = { };
- SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
- LoadFilesData(hListView, directoryPath, gFilesVector, gNameCount, errorLogFile);
- int size = static_cast<int>(gFilesVector.size());
- for (int i = 0; i < size; i++) {
- AddItemToListView(hListView, &gFilesVector[i]);
- }
- SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
- }
- int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
- _In_ PWSTR pCmdLine, _In_ int nCmdShow)
- {
- /*if (AllocConsole()) {
- FILE* fp;
- freopen_s(&fp, "CONOUT$", "w", stdout);
- }*/
- const wchar_t CLASS_NAME[] = L"WINAPI_LAB1";
- WNDCLASS wc = { };
- wc.lpfnWndProc = WindowProc;
- wc.hInstance = hInstance;
- wc.lpszClassName = CLASS_NAME;
- RegisterClass(&wc);
- HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"WINAPI_LAB1", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT,
- NULL, NULL, hInstance, NULL
- );
- if (hwnd == NULL)
- {
- return 0;
- }
- ShowWindow(hwnd, SW_SHOWMAXIMIZED);
- MSG msg;
- while (GetMessage(&msg, NULL, 0, 0) > 0)
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return 0;
- }
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
- EndPaint(hwnd, &ps);
- }
- return 0;
- case WM_CREATE:
- {
- hListViewLeft = CreateWindowEx(0, WC_LISTVIEW, L"",
- WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT,
- 10, 40, SCREEN_WIDTH / 2 - 10, SCREEN_HEIGHT - 120,
- hwnd, NULL, NULL, NULL);
- hListViewRight = CreateWindowEx(0, WC_LISTVIEW, L"",
- WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT,
- 10 + SCREEN_WIDTH / 2, 40, SCREEN_WIDTH / 2 - 50, SCREEN_HEIGHT - 120,
- hwnd, NULL, NULL, NULL);
- AddColumns(hListViewLeft);
- AddColumns(hListViewRight);
- hEdit = CreateWindowEx(0, WC_EDIT, L"",
- WS_CHILD | WS_VISIBLE | WS_BORDER,
- 10, 10, SCREEN_WIDTH - 400, 20,
- hwnd, NULL, NULL, NULL);
- hLoadButton = CreateWindowEx(0, WC_BUTTON, L"Load Files",
- WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
- SCREEN_WIDTH - 380, 8, 120, 25,
- hwnd, (HMENU)LoadFilesButtonClicked, NULL, NULL);
- hSortButton = CreateWindowEx(0, WC_BUTTON, L"Sort Files",
- WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
- SCREEN_WIDTH - 160, 8, 120, 25,
- hwnd, (HMENU)SortFilesButtonClicked, NULL, NULL);
- }
- break;
- case WM_COMMAND:
- {
- int wmId = LOWORD(wParam);
- int wmEvent = HIWORD(wParam);
- switch (wmId)
- {
- case LoadFilesButtonClicked:
- {
- if (wmEvent == BN_CLICKED) {
- PrepareListView(hListViewLeft);
- //GetDlgItem(hwnd, LoadFilesButtonClicked); – GETS HWND OF Window element
- }
- break;
- }
- case SortFilesButtonClicked:
- {
- if (wmEvent == BN_CLICKED) {
- SortListView(hListViewRight);
- }
- break;
- }
- }
- }
- break;
- case WM_CLOSE:
- /*if (MessageBox(hwnd, L"Really quit?", L"My application", MB_OKCANCEL) == IDOK) {
- DestroyWindow(hwnd);
- }*/
- PostQuitMessage(0);
- break;
- case WM_DESTROY:
- return 0;
- default:
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement