Advertisement
Old_But_Gold

Untitled

Sep 13th, 2024
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.88 KB | None | 0 0
  1. #ifndef UNICODE
  2. #define UNICODE
  3. #endif
  4.  
  5. #include <Windows.h>
  6. #include <CommCtrl.h>
  7. #include <string>
  8. #include <iostream>
  9. #include <vector>
  10. #include <unordered_map>
  11. #include <fstream>
  12. #include <ctime>
  13.  
  14. #define LoadFilesButtonClicked 0x1
  15. #define SortFilesButtonClicked 0x2
  16.  
  17. #define SCREEN_WIDTH GetSystemMetrics(SM_CXSCREEN)
  18. #define SCREEN_HEIGHT GetSystemMetrics(SM_CYSCREEN)
  19.  
  20. struct FileData {
  21. std::wstring fileName;
  22. std::wstring fileSize;
  23. };
  24.  
  25. //g for global
  26. std::vector<FileData> gFilesVector;
  27.  
  28. HWND hEdit, hListViewLeft, hListViewRight, hLoadButton, hSortButton;
  29.  
  30. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  31.  
  32. void AddColumns(HWND hListView)
  33. {
  34. LVCOLUMN lvCol = { };
  35. lvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
  36.  
  37. lvCol.cx = 50;
  38. lvCol.pszText = (LPWSTR)L"Index";
  39. ListView_InsertColumn(hListView, 0, &lvCol);
  40.  
  41. RECT rect;
  42. GetWindowRect(hListView, &rect);
  43.  
  44. lvCol.cx = (rect.right - rect.left) / 2;
  45. lvCol.pszText = (LPWSTR)L"File Name";
  46. ListView_InsertColumn(hListView, 1, &lvCol);
  47.  
  48. lvCol.cx = (rect.right - rect.left) / 2 - 50;
  49. lvCol.pszText = (LPWSTR)L"File Size";
  50. ListView_InsertColumn(hListView, 2, &lvCol);
  51. }
  52.  
  53. void AddItemToListView(HWND hListView, FileData* fileData)
  54. {
  55. LVITEM lvItem = { };
  56. lvItem.mask = LVIF_TEXT;
  57.  
  58. int index = ListView_GetItemCount(hListView);
  59. lvItem.iItem = index; //index should start with the next Item
  60.  
  61. std::wstring indexStr = std::to_wstring(index + 1);
  62. lvItem.pszText = (LPWSTR)indexStr.c_str();
  63. ListView_InsertItem(hListView, &lvItem);
  64.  
  65. ListView_SetItemText(hListView, index, 1, (LPWSTR)fileData->fileName.c_str());
  66. ListView_SetItemText(hListView, index, 2, (LPWSTR)fileData->fileSize.c_str());
  67. }
  68.  
  69. std::wstring GenerateUniqueFileName(const std::wstring& baseName,
  70. std::unordered_map<std::wstring, int>& gNameCount)
  71. {
  72. std::wstring uniqueName = baseName;
  73. int count = gNameCount[baseName];
  74.  
  75. if (count > 0) {
  76. uniqueName = baseName + L"[" + std::to_wstring(count) + L"]";
  77. }
  78.  
  79. gNameCount[baseName]++;
  80.  
  81. return uniqueName;
  82. }
  83.  
  84. void LogError(std::wofstream& logFile, const std::wstring& message) {
  85. std::time_t currentTime = std::time(nullptr);
  86. std::tm localTime;
  87. localtime_s(&localTime, &currentTime);
  88.  
  89. wchar_t timeBuffer[80];
  90. wcsftime(timeBuffer, sizeof(timeBuffer) / sizeof(wchar_t), L"%Y-%m-%d %H:%M:%S", &localTime);
  91.  
  92. logFile << L"[" << timeBuffer << L"] " << message << std::endl;
  93. }
  94.  
  95. void LoadFilesData(HWND hListView, const std::wstring directoryPath,
  96. std::vector<FileData>& files, std::unordered_map<std::wstring, int>& gNameCount,
  97. std::wofstream& errorLogFile)
  98. {
  99. WIN32_FIND_DATA data;
  100.  
  101. std::wstring searchPath = directoryPath + L"//*";
  102.  
  103. HANDLE hFind = FindFirstFile(searchPath.c_str(), &data);
  104.  
  105. if (hFind == INVALID_HANDLE_VALUE) {
  106. DWORD errorCode = GetLastError();
  107. std::wstring errorMessage = L"Error when getting files from directory: " + directoryPath +
  108. L". Error Code: " + std::to_wstring(errorCode);
  109. //std::wcout << errorMessage << std::endl;
  110. LogError(errorLogFile, errorMessage);
  111. return;
  112. }
  113.  
  114. do {
  115. if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  116. if (wcscmp(data.cFileName, L".") != 0 && wcscmp(data.cFileName, L"..") != 0) {
  117. const std::wstring newDirPath = directoryPath + L"//" + data.cFileName;
  118. LoadFilesData(hListView, newDirPath, files, gNameCount, errorLogFile);
  119. }
  120. }
  121. else {
  122. FileData fileData;
  123. std::wstring baseName = data.cFileName;
  124.  
  125. fileData.fileName = GenerateUniqueFileName(baseName, gNameCount);
  126.  
  127. ULONGLONG fileSize = ((ULONGLONG)data.nFileSizeHigh << 32) + data.nFileSizeLow;
  128. fileData.fileSize = std::to_wstring(fileSize) + L" bytes";
  129.  
  130. gFilesVector.push_back(fileData);
  131. }
  132. } while (FindNextFile(hFind, &data) != 0);
  133.  
  134. FindClose(hFind);
  135. }
  136.  
  137. enum class SortDirection { Ascending, Descending };
  138.  
  139. void RadixSort(std::vector<FileData>& array, SortDirection sortDirection = SortDirection::Ascending)
  140. {
  141. if (array.size() < 2)
  142. return;
  143.  
  144. int maxLength = 0;
  145. for (const auto& item : array) {
  146. int size = static_cast<int>(item.fileSize.length());
  147. maxLength = size > maxLength ? size : maxLength;
  148. }
  149.  
  150. wchar_t maxChar = 0;
  151. for (const auto& item : array) {
  152. for (const auto& ch : item.fileSize) {
  153. maxChar = ch > maxChar ? ch : maxChar;
  154. }
  155. }
  156. maxChar++;
  157.  
  158. std::vector<FileData> output(array.size());
  159. std::vector<int> count(maxChar, 0);
  160.  
  161. for (int digit = maxLength - 1; digit >= 0; digit--)
  162. {
  163. std::fill(count.begin(), count.end(), 0);
  164.  
  165. for (const auto& item : array)
  166. {
  167. int bucketIndex = digit < item.fileSize.length() ? item.fileSize[digit] : 0;
  168. count[bucketIndex]++;
  169. }
  170.  
  171. for (int i = 1; i < maxChar; i++)
  172. {
  173. count[i] += count[i - 1];
  174. }
  175.  
  176. if (sortDirection == SortDirection::Ascending)
  177. {
  178. for (int i = array.size() - 1; i >= 0; i--)
  179. {
  180. int bucketIndex = digit < array[i].fileSize.length() ? array[i].fileSize[digit] : 0;
  181. output[--count[bucketIndex]] = array[i];
  182. }
  183. }
  184. else
  185. {
  186. for (int i = 0; i < array.size(); i++)
  187. {
  188. int bucketIndex = digit < array[i].fileSize.length() ? array[i].fileSize[digit] : 0;
  189. output[--count[bucketIndex]] = array[i];
  190. }
  191. }
  192.  
  193. for (int i = 0; i < array.size(); i++)
  194. {
  195. array[i] = output[i];
  196. }
  197. }
  198. }
  199.  
  200. void SortListView(HWND hListView)
  201. {
  202. if (gFilesVector.size() > 0) {
  203. ListView_DeleteAllItems(hListView);
  204.  
  205. RadixSort(gFilesVector);
  206.  
  207. SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
  208.  
  209. size_t size = gFilesVector.size();
  210.  
  211. for (auto i = 0; i < size; i++) {
  212. AddItemToListView(hListView, &gFilesVector[i]);
  213. }
  214.  
  215. SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
  216. }
  217. else {
  218. MessageBox(hListView, L"Fill your left table!", L"Error", MB_ICONERROR);
  219. }
  220. }
  221.  
  222. void PrepareListView(HWND hListView)
  223. {
  224. wchar_t directoryPath[MAX_PATH] = { 0 };
  225. GetWindowTextW(hEdit, directoryPath, MAX_PATH);
  226.  
  227. WIN32_FIND_DATA data;
  228.  
  229. std::wstring searchPath = std::wstring(directoryPath) + L"\\*";
  230.  
  231. HANDLE hFind = FindFirstFile(searchPath.c_str(), &data);
  232.  
  233. if (hFind == INVALID_HANDLE_VALUE || searchPath == L"\\*") {
  234. MessageBox(hListView, L"Enter existing directory path!", L"Error", MB_ICONERROR);
  235. return;
  236. }
  237.  
  238. ListView_DeleteAllItems(hListView);
  239.  
  240. std::wofstream errorLogFile(L"D://errors.log.txt", std::ios::app);
  241.  
  242. gFilesVector = { };
  243. std::unordered_map<std::wstring, int> gNameCount = { };
  244.  
  245. SendMessage(hListView, WM_SETREDRAW, FALSE, 0);
  246.  
  247. LoadFilesData(hListView, directoryPath, gFilesVector, gNameCount, errorLogFile);
  248.  
  249. int size = static_cast<int>(gFilesVector.size());
  250.  
  251. for (int i = 0; i < size; i++) {
  252. AddItemToListView(hListView, &gFilesVector[i]);
  253. }
  254.  
  255. SendMessage(hListView, WM_SETREDRAW, TRUE, 0);
  256. }
  257.  
  258. int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
  259. _In_ PWSTR pCmdLine, _In_ int nCmdShow)
  260. {
  261. /*if (AllocConsole()) {
  262. FILE* fp;
  263. freopen_s(&fp, "CONOUT$", "w", stdout);
  264. }*/
  265.  
  266. const wchar_t CLASS_NAME[] = L"WINAPI_LAB1";
  267.  
  268. WNDCLASS wc = { };
  269. wc.lpfnWndProc = WindowProc;
  270. wc.hInstance = hInstance;
  271. wc.lpszClassName = CLASS_NAME;
  272.  
  273. RegisterClass(&wc);
  274.  
  275. HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"WINAPI_LAB1", WS_OVERLAPPEDWINDOW,
  276. CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT,
  277. NULL, NULL, hInstance, NULL
  278. );
  279.  
  280. if (hwnd == NULL)
  281. {
  282. return 0;
  283. }
  284.  
  285. ShowWindow(hwnd, SW_SHOWMAXIMIZED);
  286.  
  287. MSG msg;
  288. while (GetMessage(&msg, NULL, 0, 0) > 0)
  289. {
  290. TranslateMessage(&msg);
  291. DispatchMessage(&msg);
  292. }
  293.  
  294. return 0;
  295. }
  296.  
  297. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  298. {
  299. switch (uMsg)
  300. {
  301. case WM_PAINT:
  302. {
  303. PAINTSTRUCT ps;
  304. HDC hdc = BeginPaint(hwnd, &ps);
  305.  
  306. FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
  307. EndPaint(hwnd, &ps);
  308. }
  309. return 0;
  310.  
  311. case WM_CREATE:
  312. {
  313. hListViewLeft = CreateWindowEx(0, WC_LISTVIEW, L"",
  314. WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT,
  315. 10, 40, SCREEN_WIDTH / 2 - 10, SCREEN_HEIGHT - 120,
  316. hwnd, NULL, NULL, NULL);
  317.  
  318. hListViewRight = CreateWindowEx(0, WC_LISTVIEW, L"",
  319. WS_CHILD | WS_VISIBLE | WS_BORDER | LVS_REPORT,
  320. 10 + SCREEN_WIDTH / 2, 40, SCREEN_WIDTH / 2 - 50, SCREEN_HEIGHT - 120,
  321. hwnd, NULL, NULL, NULL);
  322.  
  323. AddColumns(hListViewLeft);
  324. AddColumns(hListViewRight);
  325.  
  326. hEdit = CreateWindowEx(0, WC_EDIT, L"",
  327. WS_CHILD | WS_VISIBLE | WS_BORDER,
  328. 10, 10, SCREEN_WIDTH - 400, 20,
  329. hwnd, NULL, NULL, NULL);
  330.  
  331. hLoadButton = CreateWindowEx(0, WC_BUTTON, L"Load Files",
  332. WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
  333. SCREEN_WIDTH - 380, 8, 120, 25,
  334. hwnd, (HMENU)LoadFilesButtonClicked, NULL, NULL);
  335.  
  336. hSortButton = CreateWindowEx(0, WC_BUTTON, L"Sort Files",
  337. WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
  338. SCREEN_WIDTH - 160, 8, 120, 25,
  339. hwnd, (HMENU)SortFilesButtonClicked, NULL, NULL);
  340.  
  341. }
  342. break;
  343.  
  344. case WM_COMMAND:
  345. {
  346. int wmId = LOWORD(wParam);
  347. int wmEvent = HIWORD(wParam);
  348.  
  349. switch (wmId)
  350. {
  351. case LoadFilesButtonClicked:
  352. {
  353. if (wmEvent == BN_CLICKED) {
  354. PrepareListView(hListViewLeft);
  355. //GetDlgItem(hwnd, LoadFilesButtonClicked); – GETS HWND OF Window element
  356. }
  357. break;
  358. }
  359.  
  360. case SortFilesButtonClicked:
  361. {
  362. if (wmEvent == BN_CLICKED) {
  363. SortListView(hListViewRight);
  364. }
  365. break;
  366. }
  367. }
  368. }
  369. break;
  370.  
  371. case WM_CLOSE:
  372. /*if (MessageBox(hwnd, L"Really quit?", L"My application", MB_OKCANCEL) == IDOK) {
  373. DestroyWindow(hwnd);
  374. }*/
  375. PostQuitMessage(0);
  376. break;
  377.  
  378. case WM_DESTROY:
  379. return 0;
  380.  
  381. default:
  382. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  383. }
  384. return 0;
  385. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement