123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- #include "main.h"
- #include "resource.h"
- #include"api__ml_rg.h"
- #include <strsafe.h>
- struct Progress
- {
- Progress()
- {
- processedFiles = 0;
- currentBytes = 0;
- totalBytes = 0;
- activeHWND = 0;
- threadHandle = 0;
- openDialogs = 0;
- done = false;
- killSwitch = 0;
- }
- size_t processedFiles;
- uint64_t currentBytes;
- uint32_t totalBytes;
- WorkQueue activeQueue;
- HWND activeHWND;
- HANDLE threadHandle;
- size_t openDialogs;
- bool done;
- int killSwitch;
- };
- DWORD WINAPI ThreadProc(void *param)
- {
- Progress *progress = (Progress *)param;
- ProgressCallback callback(progress->activeHWND);
- progress->activeQueue.Calculate(&callback, &progress->killSwitch);
- PostMessage(progress->activeHWND, WM_USER + 2, 0, 0);
- return 0;
- }
- void getViewport(RECT *r, HWND wnd, int full, RECT *sr)
- {
- POINT *p = NULL;
- if (p || sr || wnd)
- {
- HMONITOR hm = NULL;
- if (sr)
- hm = MonitorFromRect(sr, MONITOR_DEFAULTTONEAREST);
- else if (wnd)
- hm = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
- else if (p)
- hm = MonitorFromPoint(*p, MONITOR_DEFAULTTONEAREST);
- if (hm)
- {
- MONITORINFOEXW mi;
- memset(&mi, 0, sizeof(mi));
- mi.cbSize = sizeof(mi);
- if (GetMonitorInfoW(hm, &mi))
- {
- if (!full)
- *r = mi.rcWork;
- else
- *r = mi.rcMonitor;
- return ;
- }
- }
- }
- if (full)
- { // this might be borked =)
- r->top = r->left = 0;
- r->right = GetSystemMetrics(SM_CXSCREEN);
- r->bottom = GetSystemMetrics(SM_CYSCREEN);
- }
- else
- {
- SystemParametersInfoW(SPI_GETWORKAREA, 0, r, 0);
- }
- }
- BOOL windowOffScreen(HWND hwnd, POINT pt)
- {
- RECT r = {0}, wnd = {0}, sr = {0};
- GetWindowRect(hwnd, &wnd);
- sr.left = pt.x;
- sr.top = pt.y;
- sr.right = sr.left + (wnd.right - wnd.left);
- sr.bottom = sr.top + (wnd.bottom - wnd.top);
- getViewport(&r, hwnd, 0, &sr);
- return !PtInRect(&r, pt);
- }
- void SaveWindowPos(HWND hwnd)
- {
- RECT rect = {0};
- GetWindowRect(hwnd, &rect);
- char buf[16] = {0};
- StringCchPrintfA(buf, 16, "%d", rect.left);
- WritePrivateProfileStringA("ml_rg", "prog_x", buf, iniFile);
- StringCchPrintfA(buf, 16, "%d", rect.top);
- WritePrivateProfileStringA("ml_rg", "prog_y", buf, iniFile);
- }
- INT_PTR WINAPI ReplayGainProgressProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- Progress *progress = (Progress *)lParam;
- progress->killSwitch = 0;
- progress->done = false;
- progress->openDialogs = 0;
- progress->processedFiles = 0;
- progress->activeHWND = hwndDlg;
- wchar_t dummy[64] = {0};
- StringCchPrintfW(dummy, 64, WASABI_API_LNGSTRINGW(IDS_1_OF_X_FILES), progress->activeQueue.totalFiles);
- SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, dummy);
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)progress);
- DWORD threadId;
- progress->threadHandle = CreateThread(NULL, 0, ThreadProc, (void *)progress, CREATE_SUSPENDED, &threadId);
- SetThreadPriority(progress->threadHandle, THREAD_PRIORITY_IDLE);
- ResumeThread(progress->threadHandle);
- POINT pt = {(LONG)GetPrivateProfileIntA("ml_rg", "prog_x", -1, iniFile),
- (LONG)GetPrivateProfileIntA("ml_rg", "prog_y", -1, iniFile)};
- if (!windowOffScreen(hwndDlg, pt))
- SetWindowPos(hwndDlg, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
- else
- ShowWindow(hwndDlg, SW_SHOW);
- }
- break;
- case WM_DESTROY:
- {
- SaveWindowPos(hwndDlg);
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- CloseHandle(progress->threadHandle);
- progress->activeHWND = 0;
- delete progress;
- }
- break;
- case WM_USER: // file finished
- {
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- progress->processedFiles++;
- if (progress->processedFiles + 1 > progress->activeQueue.totalFiles)
- SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, WASABI_API_LNGSTRINGW(IDS_FINISHED));
- else
- {
- wchar_t dummy[64] = {0};
- StringCchPrintfW(dummy, 64,
- WASABI_API_LNGSTRINGW(IDS_X_OF_X_FILES),
- progress->processedFiles + 1, progress->activeQueue.totalFiles);
- SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, dummy);
- }
- }
- break;
- case WM_USER + 1: // album done
- {
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- WorkQueue::RGWorkQueue *queue = (WorkQueue::RGWorkQueue *)lParam;
- SaveWindowPos(hwndDlg);
- if (config_ask && config_ask_each_album)
- {
- progress->openDialogs++;
- DoResults(*queue);
- progress->openDialogs--;
- if (!progress->openDialogs && progress->done)
- DestroyWindow(hwndDlg);
- }
- else if (config_ask == 0)
- {
- WriteAlbum(*queue);
- }
- }
- break;
- case WM_USER + 2: // all tracks done
- {
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- ShowWindow(hwndDlg, SW_HIDE);
- SaveWindowPos(hwndDlg);
- if (config_ask && config_ask_each_album == 0)
- {
- DoResults(progress->activeQueue);
- }
- progress->killSwitch = 1;
- WaitForSingleObject(progress->threadHandle, INFINITE);
- progress->done = true;
- if (!progress->openDialogs)
- DestroyWindow(hwndDlg);
- }
- break;
- case WM_USER + 3: // total bytes of current file
- {
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- progress->currentBytes = 0;
- progress->totalBytes = (uint32_t)lParam;
- if (progress->totalBytes == 0)
- {
- SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, WASABI_API_LNGSTRINGW(IDS_PROCESSING));
- }
- else
- {
- wchar_t dummy[64] = {0};
- StringCchPrintfW(dummy, 64, L"%u%%", (progress->currentBytes * 100) / progress->totalBytes);
- SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, dummy);
- }
- }
- break;
- case WM_USER + 4: // more bytes read
- {
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- progress->currentBytes += lParam;
- if (progress->totalBytes == 0)
- {
- SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, WASABI_API_LNGSTRINGW(IDS_PROCESSING));
- }
- else
- {
- wchar_t dummy[64] = {0};
- StringCchPrintfW(dummy, 64, L"%u%%", (progress->currentBytes * 100) / progress->totalBytes);
- SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, dummy);
- }
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDCANCEL:
- {
- Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- progress->killSwitch = 1;
- break;
- }
- }
- break;
- }
- return 0;
- }
- void DoProgress(WorkQueue &workQueue)
- {
- Progress *progress = new Progress;
- progress->activeQueue = workQueue; // this is a huge slow copy, but I don't care at the moment
- WASABI_API_CREATEDIALOGPARAMW(IDD_PROGRESS, GetDialogBoxParent(), ReplayGainProgressProc, (LPARAM)progress);
- }
- HWND GetDialogBoxParent()
- {
- HWND parent = (HWND)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
- if (!parent || parent == (HWND)1)
- return plugin.hwndWinampParent;
- return parent;
- }
|