diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/burnlib/uiBurnPlayList.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/burnlib/uiBurnPlayList.cpp')
-rw-r--r-- | Src/burnlib/uiBurnPlayList.cpp | 1345 |
1 files changed, 1345 insertions, 0 deletions
diff --git a/Src/burnlib/uiBurnPlayList.cpp b/Src/burnlib/uiBurnPlayList.cpp new file mode 100644 index 00000000..622d2f6c --- /dev/null +++ b/Src/burnlib/uiBurnPlayList.cpp @@ -0,0 +1,1345 @@ +#include "./uiBurnPlaylist.h" +#include "./resource.h" +#include <shlwapi.h> +#include <commctrl.h> + +#include <strsafe.h> +#include "./uiCheckMedium.h" +#include "./uiUnitReady.h" + +#define WM_PLBURNERCOMMAND ((WM_USER) + 26) +#define PLB_LICENSE 0 +#define PLB_DECODE 1 +#define PLB_BURN 2 + +#define TIMER_UPDATECLOCK_ID 1979 +#define TIMER_UPDATECLOCK_INTERVAL 1000 +#define TIMER_PROGRESS_ID 1978 +#define TIMER_PROGRESS_INTERVAL 500 + +#define COLUMN_COUNT 0 +#define COLUMN_TITLE 1 +#define COLUMN_DURATION 2 +#define COLUMN_STATUS 3 +#define COLUMN_FILENAME 4 + +const int COLUMNWIDTH[] = {20, 220, 60, 102, 280}; +const int COLUMNALLIGN[] = {LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_CENTER, LVCFMT_LEFT, LVCFMT_LEFT}; +const int COLUMNNAME[] = {IDS_COLUMN_INDEX, IDS_COLUMN_TITLE, IDS_COLUMN_DURATION, IDS_COLUMN_STATUS, IDS_COLUMN_FILE}; + +const COLORREF strip[] = { RGB(198, 238, 255), RGB(184, 233, 255), RGB(167, 227, 255), RGB(151, 221, 255), RGB(133, 215, 255), RGB(115, 208, 255), RGB(99, 202, 255), + RGB(82, 196, 255), RGB(64, 190, 255), RGB(46, 184, 255), RGB(29, 177, 255), RGB(12, 171, 255), RGB(2, 165, 255), RGB(0, 158, 255) }; + + +static UINT uMsgBroadcastNotify = 0; +BurnPlaylistUI::BurnPlaylistUI(void) +{ + hwnd = NULL; + tmpfilename = NULL; + hTmpFile = NULL; + currentPercent = -1; + stripBmp = NULL; + cancelOp = FALSE; + workDone = NULL; + readyClose = TRUE; + ZeroMemory(&estimated, sizeof(aproxtime)); + +} + +BurnPlaylistUI::~BurnPlaylistUI(void) +{ + if(hwnd) DestroyWindow(hwnd); + if (hTmpFile) + { + CloseHandle(hTmpFile); + hTmpFile=0; + } + if (tmpfilename) + { + DeleteFileW(tmpfilename); + free(tmpfilename); + tmpfilename=0; + } +} + +DWORD BurnPlaylistUI::Burn(obj_primo *primoSDK, DWORD drive, DWORD maxspeed, DWORD burnFlags, BurnerPlaylist *playlist, + const wchar_t* tempPath, HWND ownerWnd) +{ + if (!primoSDK) return BURNPLAYLISTUI_PRIMOSDKNOTSET; + DWORD retCode; + extendedView = FALSE; + this->primoSDK = primoSDK; + this->drive = drive; + this->playlist = playlist; + this->maxspeed = maxspeed; + this->burnFlags = burnFlags; + this->ownerWnd = ownerWnd; + + stage = PLSTAGE_READY; + + wchar_t fname[64] = {0}; + DWORD uid = GetTickCount() & 0x00FFFFFF; + StringCchPrintfW(fname, 64, L"wa%06I32X.tmp", uid); + tmpfilename = (wchar_t*)malloc((lstrlenW(tempPath) + 48)*sizeof(wchar_t)); + if (tempPath) PathCombineW(tmpfilename, tempPath, fname); + else + { + wchar_t path[2048] = {0}; + GetTempPathW(2048, path); + PathCombineW(tmpfilename, path, fname); + } + + LPCDLGTEMPLATE templ = NULL; + HRSRC hres = FindResourceExW(hResource, MAKEINTRESOURCEW(5), MAKEINTRESOURCEW(IDD_DLG_BURNER), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); + if (hres) templ = (LPCDLGTEMPLATE)LoadResource(hResource, hres); + retCode = (DWORD)DialogBoxIndirectParamW(dllInstance, templ, NULL, (DLGPROC)WndProc, (LPARAM)this); + return retCode; +} + + +void BurnPlaylistUI::OnInitDialog(HWND hwndDlg) +{ + hwnd = hwndDlg; + errCode = BURNPLAYLISTUI_SUCCESS; + + SetPropW(hwnd, L"WABURNER", hwnd); + SetPropW(hwnd, L"DRIVE", (HANDLE)(INT_PTR)drive); + + EnableWindow(GetDlgItem(hwndDlg, IDC_CHK_ADDTODB), (PRIMOSDK_TEST != (burnFlags&PRIMOSDK_TEST))); + CheckDlgButton(hwndDlg, IDC_CHK_ADDTODB, BST_CHECKED); + CheckDlgButton(hwndDlg, IDC_CHK_EJECT, BST_CHECKED); + + if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_READY, (LPARAM)hwnd); + + if (!uMsgBroadcastNotify) uMsgBroadcastNotify = RegisterWindowMessageA("WABURNER_BROADCAST_MSG"); + if (uMsgBroadcastNotify) SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & drive), (LPARAM)TRUE); + + SetExtendedView(extendedView); + SetColumns(); + FillList(); + + wchar_t format[512] = {0}, buffer[512] = {0}; + SetReadyClose(TRUE); + + LoadStringW(hResource, IDS_BURNINGCDDA, format, 512); + StringCchPrintfW(buffer, 512, format, drive); + + + if (PRIMOSDK_TEST == (burnFlags&PRIMOSDK_TEST)) + { + HANDLE hImage = NULL; + hImage = LoadBitmapW(hResource, MAKEINTRESOURCEW(IDB_TESTMODE)); + if(hImage == NULL){ + hImage = LoadBitmapW(dllInstance, MAKEINTRESOURCEW(IDB_TESTMODE)); + } + SendDlgItemMessage(hwnd, IDC_PIC_TESTMODE, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hImage); + ShowWindow(GetDlgItem(hwnd, IDC_PIC_TESTMODE), SW_SHOW); + } + + SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer); + SendDlgItemMessage(hwnd, IDC_PRG_TOTAL, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); + SetProgress(0); + + startedTime = GetTickCount(); + /// estimation + realSpeed = 0; + DWORD retCode, reqspeed; + WAMEDIUMINFO detectedMedium; + retCode = GetMediumInfo(primoSDK, &drive, &detectedMedium); // required before GetDiscSpeed + if (PRIMOSDK_OK == retCode) + { + + switch(maxspeed) + { + case PRIMOSDK_MAX: + reqspeed = 0xFFFFFFFF; + break; + case PRIMOSDK_BEST: + reqspeed = 0xFFFFFFF0; + break; + case PRIMOSDK_MIN: + reqspeed = 0x00000000; + break; + case PRIMOSDK_MEDIUM: + reqspeed = 0x0000FFFF; + break; + default: reqspeed = maxspeed*100; + } + // TODO: benski> should "retCode =" go before this? + primoSDK->GetDiscSpeed(&drive, reqspeed, &realSpeed); + if (PRIMOSDK_OK != retCode) realSpeed = 0; + } + if (!realSpeed) realSpeed = 4*100; + + estimated.license = (DWORD)playlist->GetCount(); + estimated.convert = playlist->GetTotalLengthMS() /(60*1000); + estimated.transition = 0; + estimated.chkdisc = 1; + estimated.init = 1; + estimated.leadin = 20; + estimated.burn = playlist->GetTotalLengthMS()/(realSpeed*10); + estimated.leadout = 20; + estimated.finish = 5; + estimatedTime = 0; + + UpdateTime(TRUE); + + ShowWindow(hwnd, SW_SHOWNORMAL); + SetForegroundWindow(hwnd); + BringWindowToTop(hwnd); + UpdateWindow(hwnd); + + SetTimer(hwnd, TIMER_UPDATECLOCK_ID, TIMER_UPDATECLOCK_INTERVAL, NULL); + + hTmpFile = CreateFileW(tmpfilename, GENERIC_READ|GENERIC_WRITE/*FILE_APPEND_DATA | FILE_READ_DATA*/, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN, NULL); + if (INVALID_HANDLE_VALUE == hTmpFile) + { + wchar_t title[64] = {0}; + hTmpFile = NULL; + LoadStringW(hResource, IDS_TEMPORARY_FILE, title, 64); + MessageBoxW(NULL, tmpfilename, title, MB_OK); + ReportError(IDS_TMPCREATEFAILED, FALSE); + return; + } + PostMessage(hwnd, WM_PLBURNERCOMMAND, PLB_LICENSE, 0); + return; +} + +void BurnPlaylistUI::SetColumns(void) +{ + HWND ctrlWnd = GetDlgItem(hwnd, IDC_LST_DETAILS); + + LVCOLUMNW clmn = {0}; + clmn.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT; + int count = sizeof(COLUMNWIDTH) /sizeof(int); + wchar_t buffer[512] = {0}; + for (int i = 0; i < count; i++) + { + LoadStringW(hResource, COLUMNNAME[i], buffer, 512); + clmn.cx = COLUMNWIDTH[i]; + clmn.fmt = COLUMNALLIGN[i]; + clmn.pszText = buffer; + clmn.iSubItem = i; + SendMessageW(ctrlWnd, LVM_INSERTCOLUMNW, i, (LPARAM)&clmn); + } + + // extra styles + SendMessageW(ctrlWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, + /*LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |*/ LVS_EX_LABELTIP, + /*LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES |*/ LVS_EX_LABELTIP); + +} + +void BurnPlaylistUI::FillList(void) +{ + HWND ctrlWnd = GetDlgItem(hwnd, IDC_LST_DETAILS); + LVITEMW item = {0}; + wchar_t buffer[128] = {0}; + for(size_t i = 0; i < playlist->GetCount(); i++) + { + BurnerItem *bi = playlist->at(i); + item.mask = LVIF_TEXT | LVIF_PARAM; + item.iItem = (int)i; + item.iSubItem = COLUMN_COUNT; + _i64tow_s(i + 1, buffer, 128, 10); + item.pszText = buffer; + item.lParam = (LPARAM)bi; + SendMessage(ctrlWnd, LVM_INSERTITEMW, 0, (LPARAM)&item); + + item.mask = LVIF_TEXT; + + item.iSubItem = COLUMN_TITLE; + item.pszText = const_cast<wchar_t*>(bi->GetTitle()); + SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item); + item.iSubItem = COLUMN_DURATION; + item.pszText = GetTimeString(buffer, 128, bi->GetLength()/1000); + SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item); + item.iSubItem = COLUMN_STATUS; + item.pszText = L""; + SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item); + item.iSubItem = COLUMN_FILENAME; + item.pszText = const_cast<wchar_t*>(bi->GetFullName()); + SendMessage(ctrlWnd, LVM_SETITEMW, 0, (LPARAM)&item); + } + +} +void BurnPlaylistUI::SetProgress(int position) +{ + if (currentPercent == position) return; + wchar_t buffer[8] = {0}; + StringCchPrintfW(buffer, 8, L"%d%%", position); + SetDlgItemTextW(hwnd, IDC_LBL_PERCENT, buffer); + SendDlgItemMessage(hwnd, IDC_PRG_TOTAL, PBM_SETPOS, position, 0); + currentPercent = position; + +} +void BurnPlaylistUI::UpdateTime(BOOL recalcEstimates) +{ + wchar_t buffer[128] = {0}; + if (recalcEstimates) + { + estimatedTime = 0; + DWORD *pe = (DWORD*)&estimated; + for (int i = 0; i < sizeof(estimated) /sizeof(DWORD); i++) estimatedTime += pe[i]; + SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_ESTIMATED_VAL), GetTimeString(buffer, 128, estimatedTime)); + } + unsigned int elapsedTime = (GetTickCount() - startedTime)/1000; + SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_ELAPSED_VAL), GetTimeString(buffer, 128, elapsedTime)); + if (estimatedTime <= elapsedTime) + { + estimatedTime = elapsedTime; + SetWindowTextW(GetDlgItem(hwnd, IDC_LBL_ESTIMATED_VAL), buffer); + } +} + + +void BurnPlaylistUI::ReportError(unsigned int stringCode, BOOL allowContinue) +{ + wchar_t buffer[512] = {0}; + LoadStringW(hResource, stringCode, buffer, 512); + ReportError(buffer, allowContinue); +} +void BurnPlaylistUI::ReportError(const wchar_t *errorString, BOOL allowContinue) +{ + HWND ctrlWnd; + if (!allowContinue) + { + // stop timer and set progress to the end + estimatedTime = 0; + KillTimer(hwnd, TIMER_UPDATECLOCK_ID); + SetProgress(100); + // update time + UpdateTime(FALSE); + } + else + { + ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_SHOW); + } + + // set caption to the Burning canceled. + wchar_t buffer[128] = {0}, format[128] = {0}; + LoadStringW(hResource, (allowContinue) ? IDS_BURNINGSTOPPED : IDS_BURNINGCANCELED, format, 128); + StringCchPrintfW(buffer, 128, format, drive); + SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer); + LoadStringW(hResource, IDS_REASON, buffer, 128); + + // set operation info to Cancelation cause: error message + SetDlgItemTextW(hwnd, IDC_LBL_CURRENTOPERATION, buffer); + SetDlgItemTextW(hwnd, IDC_LBL_CURRENTOPERATION_VAL, errorString); + + // set cancel/close button to 'close' mode and enable it + LoadStringW(hResource, IDS_CLOSE, buffer, 128); + ctrlWnd = GetDlgItem(hwnd, IDCANCEL); + SetWindowTextW(ctrlWnd, buffer); + EnableWindow(ctrlWnd, TRUE); + // set extended view (show all info) + SetExtendedView(TRUE); + // make some noise + MessageBeep(MB_ICONHAND); + // set status to ready for closing + SetReadyClose(TRUE); + // if somebody waiting - we done! + if(workDone) SetEvent(workDone); + if (!allowContinue) if (uMsgBroadcastNotify) SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & drive), (LPARAM)FALSE); +} + +void BurnPlaylistUI::UpdateItemStatus(int index) +{ + LVITEMW lvi; + lvi.mask = LVIF_TEXT; + lvi.iItem = index; + lvi.iSubItem= COLUMN_STATUS; + lvi.pszText = NULL; + SendDlgItemMessage(hwnd, IDC_LST_DETAILS, LVM_SETITEMW, 0, (LPARAM)&lvi); +} +void BurnPlaylistUI::SetItemStatusText(int index, unsigned int stringCode, BOOL redraw) +{ + wchar_t buffer[128] = {0}; + LoadStringW(hResource, stringCode, buffer, 128); + LVITEMW lvi = {0}; + lvi.mask = LVIF_TEXT; + lvi.iItem = index; + lvi.iSubItem = COLUMN_STATUS; + lvi.pszText = buffer; + + HWND lstWnd = GetDlgItem(hwnd, IDC_LST_DETAILS); + SendMessage(lstWnd, LVM_SETITEMW, 0, (LPARAM)&lvi); + if (redraw) ListView_RedrawItems(lstWnd, index, index); + +} +void BurnPlaylistUI::SetCurrentOperation(unsigned int stringCode) +{ + wchar_t buffer[128] = {0}; + LoadStringW(hResource, stringCode, buffer, 128); + SetDlgItemTextW(hwnd, IDC_LBL_CURRENTOPERATION_VAL, buffer); +} +int BurnPlaylistUI::MessageBox(unsigned int messageCode, unsigned int captionCode, unsigned int uType) +{ + wchar_t message[512] = {0}, caption[64] = {0}; + LoadStringW(hResource, messageCode, message, 512); + LoadStringW(hResource, captionCode, caption, 64); + return MessageBoxW(hwnd, message, caption, uType); +} +void BurnPlaylistUI::OnCancel(void) +{ + ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_HIDE); + if (!readyClose && workDone) + { + + HWND btnWnd = GetDlgItem(hwnd, IDCANCEL); + EnableWindow(btnWnd, FALSE); + wchar_t message[512] = {0}, caption[64] = {0}; + LoadStringW(hResource, IDS_MB_CANCELBURNING, message, 512); + LoadStringW(hResource, IDS_CONFIRMATION, caption, 64); + if (IDYES != MessageBoxW(hwnd, message, caption, MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST)) + { + EnableWindow(btnWnd, TRUE); + return; + } + + wchar_t buffer[64] = {0}; + LoadStringW(hResource, IDS_BURNINGABORTEDBYUSER, buffer, 64); + SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer); + SetCurrentOperation(IDS_CANCELING); + cancelOp = TRUE; + MSG msg; + SetTimer(hwnd, TIMER_PROGRESS_ID, TIMER_PROGRESS_INTERVAL, NULL); + while (WAIT_TIMEOUT == WaitForSingleObject(workDone, 20)) + { + while (PeekMessageW(&msg, NULL, 0,0, PM_REMOVE)) + { + if(IsDialogMessage(hwnd, &msg)) continue; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + KillTimer(hwnd, TIMER_PROGRESS_ID); + cancelOp = FALSE; + CloseHandle(workDone); + workDone = NULL; + KillTimer(hwnd, TIMER_UPDATECLOCK_ID); + SetProgress(100); + estimatedTime = 0; + UpdateTime(FALSE); + if (hTmpFile) + { + CloseHandle(hTmpFile); + hTmpFile = NULL; + } + if (tmpfilename) DeleteFileW(tmpfilename); + SetReadyClose(TRUE); + EnableWindow(btnWnd, TRUE); + MessageBeep(MB_OK); + DWORD errorCode; + DWORD status = playlist->GetStatus(&errorCode); + if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_FINISHED, errorCode); + if (uMsgBroadcastNotify) + { + SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & drive), (LPARAM)FALSE); + } + if(BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHK_AUTOCLOSE) || BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_CHK_HIDEWINDOW)) + { + PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), (LPARAM)GetDlgItem(hwnd, IDCANCEL)); + } + } + else + { + if (workDone) CloseHandle(workDone); + workDone = NULL; + if (tmpfilename) DeleteFileW(tmpfilename); + PostMessage(hwnd, WM_DESTROY, 0,0); + } +} +void BurnPlaylistUI::SetReadyClose(BOOL ready) +{ + readyClose = ready; + wchar_t buffer[32] = {0}; + LoadStringW(hResource, (readyClose) ? IDS_CLOSE : IDS_CANCEL, buffer, 32); + SetDlgItemTextW(hwnd, IDCANCEL, buffer); +} +void BurnPlaylistUI::OnDestroy(void) +{ + if (stripBmp) + { + DeleteObject(stripBmp); + stripBmp = NULL; + } + if (hTmpFile) + { + CloseHandle(hTmpFile); + hTmpFile = NULL; + } + + if (tmpfilename) + { + DeleteFileW(tmpfilename); + free(tmpfilename); + tmpfilename = NULL; + } + EndDialog(hwnd, errCode); + if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_DESTROYED, 0); +} + +void BurnPlaylistUI::SetExtendedView(BOOL extView) +{ + extendedView = extView; + if (!hwnd) return; + + ShowWindow(GetDlgItem(hwnd, IDC_LST_DETAILS), extView); + ShowWindow(GetDlgItem(hwnd, IDC_GRP_OPTIONS), extView); + ShowWindow(GetDlgItem(hwnd, IDC_CHK_AUTOCLOSE), extView); + ShowWindow(GetDlgItem(hwnd, IDC_CHK_EJECT), extView); + ShowWindow(GetDlgItem(hwnd, IDC_CHK_ADDTODB), extView); + ShowWindow(GetDlgItem(hwnd, IDC_CHK_HIDEWINDOW), extView); + + RECT rw; + HWND ctrlWnd; + GetWindowRect(hwnd, &rw); + int height = (extView) ? 413 : 147; + + SetWindowPos(hwnd, HWND_TOP, 0, 0, rw.right - rw.left, height, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + + ctrlWnd = GetDlgItem(hwnd, IDC_BTN_EXTENDEDVIEW); + wchar_t buffer[32] = {0}; + LoadStringW(hResource, (extView) ? IDS_SHOWLESS : IDS_SHOWMORE, buffer, 32); + SetWindowTextW(ctrlWnd, buffer); +} + +HBITMAP BurnPlaylistUI::CreateStripBmp(HDC compDC) +{ + HDC hdc = CreateCompatibleDC(compDC); + if (!hdc) return NULL; + + BITMAPINFO info; + // create DIB Section + info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info.bmiHeader.biWidth = 1; + info.bmiHeader.biHeight = -14; + info.bmiHeader.biPlanes = 1; + info.bmiHeader.biBitCount = 24; + info.bmiHeader.biCompression = BI_RGB; + info.bmiHeader.biSizeImage = 0; + info.bmiHeader.biXPelsPerMeter = 0; + info.bmiHeader.biYPelsPerMeter = 0; + info.bmiHeader.biClrUsed = 0; + info.bmiHeader.biClrImportant = 0; + void *data; + HBITMAP bmp = CreateDIBSection(hdc, (const BITMAPINFO*) &info, DIB_RGB_COLORS, &data, NULL, 0); + if (bmp) + { + CopyMemory(data, strip, sizeof(strip)); + } + DeleteDC(hdc); + return bmp; +} + +DWORD BurnPlaylistUI::DrawList(NMLVCUSTOMDRAW* listDraw) +{ + switch(listDraw->nmcd.dwDrawStage) + { + case CDDS_PREPAINT: + return CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT; + + case CDDS_ITEMPREPAINT: + if ((int)listDraw->nmcd.dwItemSpec%2) + { + listDraw->clrTextBk = RGB(238, 238, 238);//GetSysColor(COLOR_WINDOW); + } + { + BurnerItem *bi = (BurnerItem*)listDraw->nmcd.lItemlParam; + DWORD biCode; + int status = bi->GetStatus(&biCode); + switch(status) + { + case BURNERITEM_LICENSING: + case BURNERITEM_DECODING: + case BURNERITEM_BURNING: + listDraw->clrText = RGB(30, 120, 40); + break; + case BURNERITEM_LICENSED: + case BURNERITEM_DECODED: + case BURNERITEM_BURNED: + switch(biCode) + { + case BURNERITEM_SUCCESS: + listDraw->clrText = RGB(10, 10, 60); + break; + case BURNERITEM_ABORTED: + listDraw->clrText = RGB(100, 10, 40); + break; + default: + listDraw->clrText = RGB(220, 0, 0); + break; + } + break; + case BURNERITEM_ABORTED: + listDraw->clrText = RGB(96, 24, 24); + break; + case BURNERITEM_SKIPPED: + listDraw->clrText = RGB(204, 204, 220); + break; + } + } + return CDRF_DODEFAULT | CDRF_NOTIFYSUBITEMDRAW; + + case CDDS_ITEMPREPAINT | CDDS_SUBITEM: + { + BurnerItem *bi = (BurnerItem*)listDraw->nmcd.lItemlParam; + DWORD biCode; + int status = bi->GetStatus(&biCode); + switch(status) + { + case BURNERITEM_DECODING: + case BURNERITEM_BURNING: + if (listDraw->iSubItem == COLUMN_STATUS) + { + if (!stripBmp) stripBmp = CreateStripBmp(listDraw->nmcd.hdc); + HDC hdc = CreateCompatibleDC(listDraw->nmcd.hdc); + HGDIOBJ tmpBmp = SelectObject(hdc, stripBmp); + + RECT rc; + ListView_GetSubItemRect(listDraw->nmcd.hdr.hwndFrom, (int)listDraw->nmcd.dwItemSpec, COLUMN_STATUS, LVIR_BOUNDS, &rc); + + HBRUSH hb = ((int)listDraw->nmcd.dwItemSpec%2) ? CreateSolidBrush(RGB(240, 242, 245)) :GetSysColorBrush(COLOR_WINDOW); + RECT rb; + SetRect(&rb, rc.left, rc.top, rc.left + 4, rc.bottom); + FillRect(listDraw->nmcd.hdc, &rb, hb); + SetRect(&rb, rc.left + 4, rc.top, rc.right - 4, rc.top + 1); + FillRect(listDraw->nmcd.hdc, &rb, hb); + SetRect(&rb, rc.left + 4, rc.bottom - 1, rc.right - 4, rc.bottom); + FillRect(listDraw->nmcd.hdc, &rb, hb); + + int len = int (((float)(rc.right - rc.left - 8)) * (((float)biCode)/100.0f)); + + SetRect(&rb, rc.left + 4 + len, rc.top, rc.right, rc.bottom); + FillRect(listDraw->nmcd.hdc, &rb, hb); + + for (int i = rc.left + 4; i < rc.left + 4 + len; i++) + { + BitBlt(listDraw->nmcd.hdc, i, rc.top + 1, 1, rc.bottom - rc.top -2, hdc, 0, 0, SRCCOPY); + } + SelectObject(hdc, tmpBmp); + DeleteDC(hdc); + wchar_t buffer[32] = {0}, text[64] = {0}; + LoadStringW(hResource, (BURNERITEM_DECODING == status) ? IDS_PREPARING : IDS_BURNING, buffer, 32); + + StringCchPrintfW(text, 64, L"%s (%d%%)" , buffer, biCode); + SetTextColor(listDraw->nmcd.hdc, RGB(30, 120, 0)); + SetBkMode(listDraw->nmcd.hdc,TRANSPARENT); + InflateRect(&rc, -4, 0); + DrawTextW(listDraw->nmcd.hdc, text, -1, &rc, DT_CENTER | DT_VCENTER |DT_END_ELLIPSIS |DT_SINGLELINE); + if((int)listDraw->nmcd.dwItemSpec%2) DeleteObject(hb); + return CDRF_SKIPDEFAULT; + + } + break; + } + } + + break; + default: + break; + } + return CDRF_DODEFAULT; +} + +void BurnPlaylistUI::OnLicense(void) +{ + SetReadyClose(FALSE); + if (workDone) ResetEvent(workDone); + if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_WORKING, 0); + controlTime = GetTickCount(); + if (!workDone) workDone = CreateEvent(NULL, FALSE, FALSE, NULL); + playlist->CheckLicense(OnLicensingPlaylist, this); +} + +void BurnPlaylistUI::OnDecode(void) +{ + prevRefresh = 0; + SetReadyClose(FALSE); + if (workDone) ResetEvent(workDone); + if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_WORKING, 0); + controlTime = GetTickCount(); + ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_HIDE); + DWORD retCode = playlist->Decode(hTmpFile, OnDecodePlaylist, this, FALSE); + if (BURNERPLAYLIST_DECODESTARTING == retCode) + { + if(!workDone) workDone = CreateEvent(NULL, FALSE, FALSE, NULL); + } +} + +void BurnPlaylistUI::OnBurn(void) +{ + // check disc + SetReadyClose(FALSE); + if (workDone) ResetEvent(workDone); + if (ownerWnd) PostMessage(ownerWnd, WM_BURNNOTIFY, BURN_WORKING, 0); + estimated.transition = (GetTickCount() - controlTime)/1000; + UpdateTime(TRUE); + ShowWindow(GetDlgItem(hwnd, IDC_BTN_CONTINUE), SW_HIDE); + DWORD totalSectors = playlist->GetTotalSectors(); + SetReadyClose(FALSE); + controlTime = GetTickCount(); + WAMEDIUMINFO mi; + FillMemory(&mi, sizeof(WAMEDIUMINFO), 0xFF); + mi.recordable = TRUE; + mi.isCD = TRUE; + mi.freeSectors = totalSectors; // plus lead-in + CheckMediumUI cm; + SetProgress(0); + SetCurrentOperation(IDS_CHECKINGDISC); + DWORD time =totalSectors/75; + int min = time / 60 + ((time % 60) ? 1 : 0); + wchar_t string[512] = {0}; + LoadStringW(hResource, IDS_BURNREQDISC, string, 512); + wchar_t buffer[512] = {0}; + StringCchPrintfW(buffer, 512, string, min); + DWORD retCode = cm.Check(primoSDK, &drive, &mi, buffer, FALSE, TRUE, hwnd); + estimated.chkdisc = (GetTickCount() - controlTime)/1000; + UpdateTime(TRUE); + switch(retCode) + { + case CHECKMEDIUMUI_MATCH: + { + // start burning + DWORD reqspeed; + unsigned int strcode; + switch(maxspeed) + { + case PRIMOSDK_MAX: + reqspeed = 0xFFFFFFFF; + strcode = IDS_SPEEDMAX; + break; + case PRIMOSDK_BEST: + reqspeed = 0xFFFFFFF0; + strcode = IDS_SPEEDBEST; + break; + case PRIMOSDK_MIN: + reqspeed = 0x00000000; + strcode = IDS_SPEEDMIN; + break; + case PRIMOSDK_MEDIUM: + reqspeed = 0xFFFFF000; + strcode = IDS_SPEEDMED; + break; + default: + reqspeed = maxspeed*100; + strcode = IDS_SPEED; + break; + } + primoSDK->GetDiscSpeed(&drive, reqspeed, &realSpeed); + wchar_t at[8] = {0}, spd[16] = {0}, spddesc[32] = {0}; + StringCchPrintfW(spd, 16, L"%d.%02dx", realSpeed/100, realSpeed%100); + + LoadStringW(hResource, strcode, spddesc, 32); + LoadStringW(hResource, IDS_BURNINGCDDA, buffer, 512); + StringCchPrintfW(string, 512, buffer, drive); + LoadStringW(hResource, IDS_AT, at, 8); + switch(maxspeed) + { + case PRIMOSDK_BEST: + StringCchPrintfW(buffer, 512, L"%s %s %s", string, at, spddesc); + break; + case PRIMOSDK_MAX: + case PRIMOSDK_MEDIUM: + case PRIMOSDK_MIN: + StringCchPrintfW(buffer,512, L"%s %s %s (%s)", string, at, spddesc, spd); + break; + default: + StringCchPrintfW(buffer,512, L"%s %s %s %s", string, at, spd, spddesc); + break; + } + SetDlgItemTextW(hwnd, IDC_LBL_CAPTION, buffer); + + retCode = playlist->Burn(primoSDK, drive, maxspeed, burnFlags, hTmpFile,OnBurnPlaylist, this, FALSE); + if (BURNERPLAYLIST_BURNSTARTING == retCode) + { + if (!workDone) workDone = CreateEvent(NULL, FALSE, FALSE, NULL); + SetReadyClose(FALSE); + return; + } + break; + } + case CHECKMEDIUMUI_CANCELED: ReportError(IDS_BURNINGABORTEDBYUSER, FALSE); break; + case CHECKMEDIUMUI_DISCNOTSET: ReportError(IDS_CHKDSCWRONGPARAMETER, FALSE); break; + case CHECKMEDIUMUI_DRIVENOTSET: ReportError(IDS_CHKDSCWRONGPARAMETER, FALSE); break; + case CHECKMEDIUMUI_PRIMOSDKNOTSET: ReportError(IDS_CHKDSCWRONGPARAMETER, FALSE); break; + case CHECKMEDIUMUI_UNABLETOCREATEDIALOG: ReportError(IDS_CHKDSCDIALOGFAILED, FALSE); break; + case CHECKMEDIUMUI_MESSAGEPUMPERROR: ReportError(IDS_CHKDSCMSGPUMPFAILED, FALSE); break; + default: + { + ReportError(IDS_PRIMOINITFAILED, FALSE); + + DWORD statCode, cmd, sense, asc, ascq; + statCode = primoSDK->UnitStatus(&drive, &cmd, &sense, &asc, &ascq); + wchar_t caption[64] = {0}, message[512] = {0}, myerror[128] = {0}, libprfx[32] = {0}, liberror[128] = {0}, drvprfx[32] = {0}, drverror[128] = {0}; + LoadStringW(hResource, IDS_BURNERROR, caption, 64); + LoadStringW(hResource, IDS_PRIMOINITFAILED, myerror, 128); + LoadStringW(hResource, IDS_LIBERRORPREFIX, libprfx, 32); + LoadStringW(hResource, IDS_DRVERRORPREFIX, drvprfx, 32); + GetPrimoCodeText(liberror, 128, statCode); + GetUnitStatusText(drverror, 128, sense, asc, ascq); + StringCchPrintfW(message, 512, L"%s%s%s%s%s", myerror, libprfx, liberror, drvprfx, drverror); + MessageBoxW(hwnd, message, caption, MB_OK | MB_ICONEXCLAMATION); + } + break; + } + SetReadyClose(TRUE); + if (workDone) SetEvent(workDone); +} +DWORD BurnPlaylistUI::OnLicensingPlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param) +{ + BurnPlaylistUI *dlg = (BurnPlaylistUI *) userparam; + switch (notifyCode) + { + case BURNERPLAYLIST_LICENSINGFINISHED: + dlg->stage = PLSTAGE_LICENSED; + dlg->estimated.license = (GetTickCount() - dlg->controlTime)/1000; + dlg->UpdateTime(TRUE); + KillTimer(dlg->hwnd, TIMER_PROGRESS_ID); + dlg->SetProgress(100); + switch(errorCode) + { + + case BURNERPLAYLIST_FILENOTLICENSED: // param contains number of successfully processed files + dlg->ReportError(IDS_LICENSEFAILED, (param) ? TRUE : FALSE); + if(param) + { + dlg->estimated.convert = ((int)param)/(60*1000); + dlg->estimated.burn = ((int)param)/(dlg->realSpeed*10); + dlg->controlTime = GetTickCount(); + dlg->MessageBox(IDS_LICENSEFAILEDMSG, IDS_BURNERROR, MB_OK | MB_ICONERROR); + dlg->estimated.transition += (GetTickCount() - dlg->controlTime)/1000; + dlg->UpdateTime(TRUE); + } + break; + case BURNERPLAYLIST_SUCCESS: dlg->SetCurrentOperation(IDS_LICENSESUCCESS); break; + case BURNERPLAYLIST_NOFILES: dlg->ReportError(IDS_NOFILES, FALSE); break; + case BURNERPLAYLIST_DECODESERVICEFAILED: dlg->ReportError(IDS_DECODESERVICEFAILED, FALSE); break; + case BURNERPLAYLIST_WRONGFILECOUNT: dlg->ReportError(IDS_LICENSEWRONGFILECOUNT, FALSE); break; + default: dlg->ReportError(IDS_LICENSEFAILED, FALSE); break; + } + PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, 0); + if (BURNERPLAYLIST_SUCCESS == errorCode) PostMessage(dlg->hwnd, WM_PLBURNERCOMMAND, PLB_DECODE, 0); + break; + case BURNERPLAYLIST_LICENSINGSTARTING: + switch(errorCode) + { + case BURNERPLAYLIST_ITEMADDED: dlg->SetItemStatusText((int)param, IDS_LICENSEITEMPROGRESS, TRUE); break; + case BURNERPLAYLIST_ADDITEMSKIPPED: dlg->SetItemStatusText((int)param, IDS_SKIPPED, TRUE); break; + case BURNERPLAYLIST_SUCCESS: + dlg->SetCurrentOperation(IDS_LICENSEPROGRESS); + SetTimer(dlg->hwnd, TIMER_PROGRESS_ID, 100, NULL); + break; + } + break; + case BURNERPLAYLIST_LICENSINGPROGRESS: + unsigned int strcode(IDS_UNKNOWN); + switch(errorCode) + { + case BURN_OK: dlg->SetItemStatusText((int)param, IDS_LICENSEITEMSUCCESS, TRUE); break; + case BURN_FILE_NOT_FOUND: dlg->SetItemStatusText((int)param, IDS_FILENOTFOUND, TRUE); break; + case BURN_DRM_NO_LICENSE: dlg->SetItemStatusText((int)param, IDS_DRMNOLICENSE, TRUE); break; + case BURN_DRM_NOT_ALLOWED: dlg->SetItemStatusText((int)param, IDS_DRMNOBURNING, TRUE); break; + case BURN_DRM_BURN_COUNT_EXCEEDED: dlg->SetItemStatusText((int)param, IDS_DRMBURNCOUNTEXCEEDED, TRUE); break; + case BURN_NO_DECODER: dlg->SetItemStatusText((int)param, IDS_NODECODER, TRUE); break; + default: dlg->SetItemStatusText((int)param, IDS_LICENSEITEMFAILED, TRUE); break; + } + break; + } + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + return (!dlg->cancelOp) ? BURNERPLAYLIST_CONTINUE : BURNERPLAYLIST_STOP; +} +DWORD BurnPlaylistUI::OnDecodePlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param) +{ + BurnPlaylistUI *dlg = (BurnPlaylistUI *) userparam; + switch (notifyCode) + { + case BURNERPLAYLIST_DECODESTARTING: + switch(errorCode) + { + case BURNERPLAYLIST_SUCCESS: + dlg->SetCurrentOperation(IDS_PREPARINGDATA); + dlg->processed = 0; + dlg->count = 0; + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + break; + case BURNERPLAYLIST_ITEMADDED: dlg->SetItemStatusText((int)param, IDS_SCHEDULED, TRUE); dlg->count++; break; + case BURNERPLAYLIST_ADDITEMSKIPPED: dlg->SetItemStatusText((int)param, IDS_SKIPPED, TRUE); break; + } + break; + case BURNERPLAYLIST_DECODEFINISHED: + dlg->stage = PLSTAGE_DECODED; + dlg->SetProgress(100); + dlg->estimated.convert = (GetTickCount() - dlg->controlTime)/1000; + dlg->UpdateTime(TRUE); + dlg->controlTime = GetTickCount(); + dlg->estimated.burn = dlg->playlist->GetStateLengthMS(BURNERITEM_DECODED, BURNERITEM_SUCCESS)/(dlg->realSpeed*10); + switch(errorCode) + { + case BURNERPLAYLIST_SUCCESS: + dlg->SetCurrentOperation(IDS_PREPARESUCCESS); + PostMessage(dlg->hwnd, WM_PLBURNERCOMMAND, PLB_BURN, 0); + break; + case BURNERPLAYLIST_NOFILES: dlg->ReportError(IDS_NOFILES, FALSE); break; + case BURNERPLAYLIST_ABORTED: dlg->ReportError(IDS_BURNINGABORTEDBYUSER, FALSE); break; + case BURNERPLAYLIST_DECODESERVICEFAILED: dlg->ReportError(IDS_DECODESERVICEFAILED, FALSE); break; + case BURNERPLAYLIST_THREADCREATEFAILED: dlg->ReportError(IDS_DECODESTARTFAILED, FALSE); break; + + + default: + dlg->ReportError(IDS_PREPAREFAILED, TRUE); + dlg->MessageBox(IDS_PREPAREFAILEDMSG, IDS_BURNERROR, MB_OK | MB_ICONERROR); + dlg->estimated.transition += (GetTickCount() - dlg->controlTime)/1000; + dlg->UpdateTime(TRUE); + break; + + } + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + break; + case BURNERPLAYLIST_DECODEPROGRESS: + { + BPLDECODEINFO *info = (BPLDECODEINFO*)param; + switch(errorCode) + { + case BURNERPLAYLIST_DECODENEXTITEM: + if(!dlg->cancelOp) + { + wchar_t text[64] = {0}, of[16] = {0}, buffer[128] = {0}; + BPLDECODEINFO *info = (BPLDECODEINFO*)param; + LoadStringW(hResource, IDS_PREPARINGDATA, text, 64); + LoadStringW(hResource, IDS_OF, of, 16); + StringCchPrintfW(buffer, 128, L"%s ( %d %s %d )", text, dlg->processed + 1, of, dlg->count); + SetDlgItemTextW(dlg->hwnd, IDC_LBL_CURRENTOPERATION_VAL, buffer); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, info->iIndex); + } + break; + case BURNERPLAYLIST_DECODEITEM: + switch(info->iNotifyCode) + { + case BURNERITEM_DECODESTARTING: + ListView_RedrawItems(GetDlgItem(dlg->hwnd, IDC_LST_DETAILS), info->iIndex, info->iIndex); + if(!dlg->cancelOp) dlg->SetProgress((int)info->percentCompleted); + break; + case BURNERITEM_DECODEPROGRESS: + if (GetTickCount() - dlg->prevRefresh < 100) break; + dlg->UpdateItemStatus(info->iIndex); + if(!dlg->cancelOp) + { + dlg->SetProgress((int)info->percentCompleted); + if ((int)info->percentCompleted) + { + dlg->estimated.convert = (GetTickCount() - dlg->controlTime)/((int)(info->percentCompleted*10)); + dlg->UpdateTime(TRUE); + } + } + dlg->prevRefresh = GetTickCount(); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMDECODEPROGRESS, info->iIndex); + break; + case BURNERITEM_DECODEFINISHED: + switch(info->iErrorCode) + { + case BURNERITEM_SUCCESS: dlg->SetItemStatusText(info->iIndex, IDS_PREPAREITEMSUCCESS, TRUE); break; + case BURNERITEM_ABORTED: dlg->SetItemStatusText(info->iIndex, IDS_CANCELED, TRUE); break; + case BURNERITEM_BADFILENAME: dlg->SetItemStatusText(info->iIndex, IDS_BADFILENAME, TRUE); break; + case BURNERITEM_UNABLEOPENFILE: dlg->SetItemStatusText(info->iIndex, IDS_NODECODER, TRUE); break; + case BURNERITEM_WRITEERROR: dlg->SetItemStatusText(info->iIndex, IDS_CACHEWRITEFAILED, TRUE); break; + default: + dlg->SetItemStatusText(info->iIndex, IDS_PREPAREITEMFAILED, TRUE); + dlg->estimated.burn -= info->iInstance->GetLength()/(dlg->realSpeed*10); + dlg->UpdateTime(TRUE); + break; + } + dlg->processed++; + if(!dlg->cancelOp) dlg->SetProgress((int)info->percentCompleted); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, info->iIndex); + break; + } + break; + } + } + break; + case BURNERPLAYLIST_DECODECANCELING: dlg->SetCurrentOperation(IDS_CANCELING); break; + } + return (!dlg->cancelOp) ? BURNERPLAYLIST_CONTINUE : BURNERPLAYLIST_STOP; +} + +DWORD BurnPlaylistUI::OnBurnPlaylist(void *sender, void *userparam, DWORD notifyCode, DWORD errorCode, ULONG_PTR param) +{ + BurnPlaylistUI *dlg = (BurnPlaylistUI *) userparam; + BurnerPlaylist *playlist = (BurnerPlaylist*)sender; + switch (notifyCode) + { + case BURNERPLAYLIST_BURNSTARTING: + switch(errorCode) + { + case BURNERPLAYLIST_SUCCESS: dlg->SetCurrentOperation(IDS_MASTERINGDISC); break; + case BURNERPLAYLIST_ITEMADDED: + dlg->SetItemStatusText((int)param, IDS_SCHEDULED, TRUE); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, param); + break; + case BURNERPLAYLIST_ADDITEMSKIPPED: + dlg->SetItemStatusText((int)param, IDS_SKIPPED, TRUE); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, param); + break; + case BURNERPLAYLIST_ADDITEMFAILED: + dlg->SetItemStatusText((int)param, IDS_BURNITEMADDFAILED, TRUE); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, param); + break; + case BURNERPLAYLIST_BEGINBURN: dlg->SetCurrentOperation(IDS_INITIALIZINGBURNER); break; + } + break; + case BURNERPLAYLIST_BURNPROGRESS: + switch(errorCode) + { + case BURNERPLAYLIST_WRITELEADIN: + + dlg->estimated.init = (GetTickCount() - dlg->controlTime)/1000; + dlg->controlTime = GetTickCount(); + dlg->UpdateTime(TRUE); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + if (dlg->cancelOp) break; + dlg->SetCurrentOperation(IDS_WRITELEADIN); + break; + case BURNERPLAYLIST_WRITELEADOUT: + dlg->controlTime = GetTickCount(); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + if (dlg->cancelOp) break; + dlg->SetCurrentOperation(IDS_WRITELEADOUT); + break; + case BURNERPLAYLIST_DISCOPEN: + if (!dlg->cancelOp) dlg->SetCurrentOperation(IDS_DISCOPEN); + break; + case BURNERPLAYLIST_DISCCLOSE: + if (!dlg->cancelOp) dlg->SetCurrentOperation(IDS_DISCCLOSE); + break; + case BURNERPLAYLIST_WRITEITEMBEGIN: + if (((BPLRUNSTATUS*)param)->iIndex == 0) + { + dlg->estimated.leadin = (GetTickCount() - dlg->controlTime)/1000; + dlg->controlTime = GetTickCount(); + } + ListView_RedrawItems(GetDlgItem(dlg->hwnd, IDC_LST_DETAILS), ((BPLRUNSTATUS*)param)->iIndex, ((BPLRUNSTATUS*)param)->iIndex); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, ((BPLRUNSTATUS*)param)->iIndex); + break; + case BURNERPLAYLIST_WRITEITEMEND: + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMSTATECHANGED, ((BPLRUNSTATUS*)param)->iIndex); + if (dlg->cancelOp) break; + dlg->SetItemStatusText(((BPLRUNSTATUS*)param)->iIndex, IDS_BURNITEMSUCCESS, TRUE); + break; + case BURNERPLAYLIST_WRITEDATA: + { + BPLRUNSTATUS *status = (BPLRUNSTATUS*)param; + int percent = (int)(status->sCurrent * 100 / status->sTotal); + if (!percent) break; + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_ITEMBURNPROGRESS, ((BPLRUNSTATUS*)param)->iIndex); + if (dlg->cancelOp) break; + if (dlg->currentPercent != percent) + { + dlg->SetProgress(percent); + wchar_t format[128] = {0}, buffer[164] = {0}; + LoadStringW(hResource, IDS_BURNPROGRESS, format, 128); + StringCchPrintfW(buffer, 164, format , percent); + SetDlgItemTextW(dlg->hwnd, IDC_LBL_CURRENTOPERATION_VAL, buffer); + } + dlg->UpdateItemStatus(((BPLRUNSTATUS*)param)->iIndex); + dlg->estimated.burn = (GetTickCount() - dlg->controlTime)/((int)(percent*10)); + dlg->UpdateTime(TRUE); + + } + break; + } + break; + case BURNERPLAYLIST_BURNFINISHING: + dlg->estimated.leadout = (GetTickCount() - dlg->controlTime)/1000; + dlg->UpdateTime(TRUE); + dlg->controlTime = GetTickCount(); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + playlist->SetEjectWhenDone((BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_EJECT)) ? PRIMOSDK_OPENTRAYEJECT : 0); + if (dlg->cancelOp) break; + dlg->SetCurrentOperation(IDS_RELEASINGBURNER); + break; + case BURNERPLAYLIST_BURNFINISHED: + dlg->stage = PLSTAGE_BURNED; + dlg->estimated.finish = (GetTickCount() - dlg->controlTime)/1000; + dlg->SetProgress(100); + + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_FINISHED, errorCode); + + switch(errorCode) + { + case BURNERPLAYLIST_ABORTED: dlg->ReportError(IDS_BURNINGABORTEDBYUSER, FALSE); return BURNERPLAYLIST_STOP; + case BURNERPLAYLIST_NOFILES: dlg->ReportError(IDS_NOFILES, FALSE); return BURNERPLAYLIST_STOP; + case BURNERPLAYLIST_ADDITEMFAILED: dlg->ReportError(IDS_MASTERINGFAILED, FALSE); return BURNERPLAYLIST_STOP; + case BURNERPLAYLIST_THREADCREATEFAILED: dlg->ReportError(IDS_BURNSTARTFAILED, FALSE); return BURNERPLAYLIST_STOP; + } + + if (BURNERPLAYLIST_SUCCESS != errorCode) // rest of the errors + { + unsigned int strcode(IDS_BURNFAILED); + switch(errorCode) + { + case BURNERPLAYLIST_BEGINBURNFAILED: strcode = IDS_BEGINBURNFAILED; break; + case BURNERPLAYLIST_WRITEAUDIOFAILED: strcode = IDS_WRITEAUDIOFAILED; break; + case BURNERPLAYLIST_ENDBURNFAILED: strcode = IDS_ENDBURNFAILED; break; + } + dlg->ReportError(strcode, FALSE); + + wchar_t caption[64] = {0}, message[512] = {0}, myerror[128] = {0}, libprfx[32] = {0}, liberror[128] = {0}, drvprfx[32] = {0}, drverror[128] = {0}; + LoadStringW(hResource, IDS_BURNERROR, caption, 64); + LoadStringW(hResource, strcode, myerror, 128); + LoadStringW(hResource, IDS_LIBERRORPREFIX, libprfx, 32); + LoadStringW(hResource, IDS_DRVERRORPREFIX, drvprfx, 32); + GetPrimoCodeText(liberror, 128, (0x000000FF & (((DWORD)param) >> 24))); + GetUnitStatusText(drverror, 128, (0x000000FF & (((DWORD)param) >> 16)), (0x000000FF & (((DWORD)param) >> 8)), (0x000000FF & (DWORD)param)); + StringCchPrintfW(message, 512, L"%s%s%s%s%s", myerror, libprfx, liberror, drvprfx, drverror); + MessageBoxW(dlg->hwnd, message, caption, MB_OK | MB_ICONEXCLAMATION); + return BURNERPLAYLIST_STOP; + } + + // this is a happy end :) + if(BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_ADDTODB)) dlg->playlist->AddCompilationToCDDB(); + + KillTimer(dlg->hwnd, TIMER_UPDATECLOCK_ID); + dlg->estimatedTime = 0; + dlg->UpdateTime(FALSE); + // set caption to the Burning completed. + { + wchar_t buffer[128] = {0}, format[128] = {0}; + LoadStringW(hResource, IDS_BURNINGCOMPLETED, format, 128); + StringCchPrintfW(buffer, 128, format, dlg->drive); + SetDlgItemTextW(dlg->hwnd, IDC_LBL_CAPTION, buffer); + } + + dlg->SetCurrentOperation(IDS_BURNSUCCESS); + + dlg->SetReadyClose(TRUE); + if (dlg->workDone) SetEvent(dlg->workDone); + + if (uMsgBroadcastNotify) + SendNotifyMessage(HWND_BROADCAST, uMsgBroadcastNotify, (WPARAM)(0xFF & dlg->drive), (LPARAM)FALSE); + + if(BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_AUTOCLOSE) || + BST_CHECKED == IsDlgButtonChecked(dlg->hwnd, IDC_CHK_HIDEWINDOW)) + { + PostMessage(dlg->hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), (LPARAM)GetDlgItem(dlg->hwnd, IDCANCEL)); + } + + MessageBeep(MB_OK); + break; + case BURNERPLAYLIST_BURNCANCELING: + dlg->SetItemStatusText(((BPLRUNSTATUS*)param)->iIndex, + (BURNERITEM_CANCELING == dlg->playlist->at(((BPLRUNSTATUS*)param)->iIndex)->GetStatus(NULL)) ? IDS_CANCELING : IDS_CANCELED, + TRUE); + if (dlg->ownerWnd) PostMessage(dlg->ownerWnd, WM_BURNNOTIFY, BURN_STATECHANGED, notifyCode); + break; + } + return (!dlg->cancelOp) ? BURNERPLAYLIST_CONTINUE : BURNERPLAYLIST_STOP; +} + +LRESULT BurnPlaylistUI::WndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static BurnPlaylistUI *pl = NULL; + switch(uMsg) + { + case WM_INITDIALOG: + pl = (BurnPlaylistUI*)lParam; + pl->OnInitDialog(hwndDlg); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDCANCEL: + pl->OnCancel(); + break; + case IDC_BTN_EXTENDEDVIEW: + if (BN_CLICKED == HIWORD(wParam)) pl->SetExtendedView(!pl->extendedView); + break; + case IDC_BTN_CONTINUE: + if (BN_CLICKED == HIWORD(wParam)) + { + + wchar_t buffer[128] = {0}, format[128] = {0}; + LoadStringW(hResource, IDS_BURNINGCDDA, format, 128); + StringCchPrintfW(buffer, 128, format, pl->drive); + SetDlgItemTextW(hwndDlg, IDC_LBL_CAPTION, buffer); + LoadStringW(hResource, IDS_CURRENTOPERATION, buffer, 128); + SetDlgItemTextW(hwndDlg, IDC_LBL_CURRENTOPERATION, buffer); + ShowWindow((HWND)lParam, SW_HIDE); + PostMessage(hwndDlg, WM_PLBURNERCOMMAND, PLB_LICENSE, 0); + } + break; + case IDC_CHK_AUTOCLOSE: + if (BN_CLICKED == HIWORD(wParam)) + { + if (pl->ownerWnd) + PostMessage(pl->ownerWnd, WM_BURNNOTIFY, + BURN_CONFIGCHANGED, + MAKELPARAM(BURNCFG_AUTOCLOSE, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_AUTOCLOSE)))); + } + break; + case IDC_CHK_EJECT: + if (BN_CLICKED == HIWORD(wParam)) + { + if (pl->ownerWnd) + PostMessage(pl->ownerWnd, WM_BURNNOTIFY, + BURN_CONFIGCHANGED, + MAKELPARAM(BURNCFG_AUTOEJECT, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_EJECT)))); + } + break; + case IDC_CHK_ADDTODB: + if (BN_CLICKED == HIWORD(wParam)) + { + if (pl->ownerWnd) + PostMessage(pl->ownerWnd, WM_BURNNOTIFY, + BURN_CONFIGCHANGED, + MAKELPARAM(BURNCFG_ADDTODB, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_ADDTODB)))); + } + break; + case IDC_CHK_HIDEWINDOW: + if (BN_CLICKED == HIWORD(wParam)) + { + if (pl->ownerWnd) + PostMessage(pl->ownerWnd, WM_BURNNOTIFY, + BURN_CONFIGCHANGED, + MAKELPARAM(BURNCFG_HIDEVIEW, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDEWINDOW)))); + ShowWindow(hwndDlg, (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDEWINDOW)) ? SW_HIDE : SW_SHOW); + } + break; + } + break; + case WM_DESTROY: + pl->OnDestroy(); + break; + case WM_TIMER: + switch(wParam) + { + case TIMER_UPDATECLOCK_ID: + pl->UpdateTime(FALSE); + break; + case TIMER_PROGRESS_ID: + if (pl->currentPercent == 100) pl->currentPercent = 0; + pl->SetProgress(pl->currentPercent + 1); + break; + } + break; + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == IDC_LST_DETAILS) + { + if(((LPNMHDR)lParam)->code == NM_CUSTOMDRAW) + { + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG)(LONG_PTR)pl->DrawList((NMLVCUSTOMDRAW*)lParam)); + return TRUE; + } + if(((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) + { + int index = (int)SendMessage(((LPNMHDR)lParam)->hwndFrom, LVM_GETNEXTITEM, -1, LVNI_FOCUSED); + if(index == -1) return FALSE; + ListView_SetItemState(((LPNMHDR)lParam)->hwndFrom, index, 0, LVIS_SELECTED | LVIS_FOCUSED); + return TRUE; + } + } + break; + case WM_PLBURNERCOMMAND: + switch(wParam) + { + case PLB_LICENSE: + pl->OnLicense(); + break; + case PLB_DECODE: + pl->OnDecode(); + break; + case PLB_BURN: + pl->OnBurn(); + break; + } + break; + case WM_BURNUPDATEOWNER: + { + LONG tmpWnd = (LONG)(ULONG_PTR)pl->ownerWnd; + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, tmpWnd); + pl->ownerWnd = (HWND)lParam; + return tmpWnd; + } + case WM_BURNGETSTATUS: + { + DWORD retCode = 0; + switch(wParam) + { + case BURNSTATUS_DRIVE: + retCode = pl->drive; + break; + case BURNSTATUS_ELAPSED: + retCode = (GetTickCount() - pl->startedTime)/1000; + break; + case BURNSTATUS_ESTIMATED: + retCode = pl->estimatedTime; + break; + case BURNSTATUS_STATE: + retCode = pl->playlist->GetStatus(NULL); + break; + case BURNSTATUS_ERROR: + pl->playlist->GetStatus(&retCode); + break; + case BURNSTATUS_PROGRESS: + retCode = (GetTickCount() - pl->startedTime)/(pl->estimatedTime*10); + break; + } + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, retCode); + return retCode; + } + case WM_BURNGETITEMSTATUS: + { + DWORD retCode = 0; + if (((DWORD)lParam) >= pl->playlist->GetCount()) break; + { + BurnerItem *item = pl->playlist->at(lParam); + if (!item) break; + switch(wParam) + { + case BURNSTATUS_STATE: + retCode = item->GetStatus(NULL); + break; + case BURNSTATUS_PROGRESS: + case BURNSTATUS_ERROR: + item->GetStatus(&retCode); + break; + + } + } + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, retCode); + return retCode; + } + case WM_BURNCONFIGCHANGED: + switch(wParam) + { + case BURNCFG_AUTOCLOSE: + CheckDlgButton(hwndDlg, IDC_CHK_AUTOCLOSE, (lParam) ? BST_CHECKED : BST_UNCHECKED); + break; + case BURNCFG_AUTOEJECT: + CheckDlgButton(hwndDlg, IDC_CHK_EJECT, (lParam) ? BST_CHECKED : BST_UNCHECKED); + break; + case BURNCFG_ADDTODB: + if (PRIMOSDK_TEST == (pl->burnFlags&PRIMOSDK_TEST)) lParam = FALSE; + CheckDlgButton(hwndDlg, IDC_CHK_ADDTODB, (lParam) ? BST_CHECKED : BST_UNCHECKED); + break; + case BURNCFG_HIDEVIEW: + CheckDlgButton(hwndDlg, IDC_CHK_HIDEWINDOW, (lParam) ? BST_CHECKED : BST_UNCHECKED); + break; + } + break; + } + if (uMsgBroadcastNotify && uMsgBroadcastNotify == uMsg && HIWORD(wParam) && pl && pl->playlist) + { + CHAR cLetter; + cLetter = (CHAR)LOWORD(wParam); + if (!cLetter || (cLetter == (CHAR)(0xFF & pl->drive))) + { + if (!cLetter) cLetter = (CHAR)(0xFF & pl->drive); + if (BURNERPLAYLIST_BURNFINISHED != pl->playlist->GetStatus(NULL)) + SendNotifyMessage((HWND)lParam, uMsgBroadcastNotify, (WPARAM)cLetter, TRUE); + } + } + return 0; +} + |