winamp/Src/burnlib/uiBurnPlayList.cpp

1346 lines
45 KiB
C++
Raw Normal View History

2024-09-24 14:54:57 +02:00
#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;
}