neroFiddlesDlg.cpp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
  1. /******************************************************************************
  2. |* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. |* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. |* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. |* PARTICULAR PURPOSE.
  6. |*
  7. |* Copyright 1995-2005 Nero AG. All Rights Reserved.
  8. |*-----------------------------------------------------------------------------
  9. |* PROJECT: NeroFiddles NeroAPI Example
  10. |*
  11. |* FILE: NeroFiddlesDlg.cpp
  12. |*
  13. |* PURPOSE: Implementation of a dialog for interaction with the user.
  14. ******************************************************************************/
  15. // NeroFiddlesDlg.cpp : implementation file
  16. //
  17. #include "stdafx.h"
  18. #include "neroFiddles.h"
  19. #include "neroFiddlesDlg.h"
  20. #include "..\\..\\..\\..\\..\\..\\kernelcode\\Burndisc\\Burndisc\\DiscItem.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CAboutDlg dialog used for App About
  28. class CAboutDlg : public CDialog
  29. {
  30. public:
  31. CAboutDlg();
  32. // Dialog Data
  33. //{{AFX_DATA(CAboutDlg)
  34. enum { IDD = IDD_ABOUTBOX };
  35. //}}AFX_DATA
  36. // ClassWizard generated virtual function overrides
  37. //{{AFX_VIRTUAL(CAboutDlg)
  38. protected:
  39. virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
  40. //}}AFX_VIRTUAL
  41. // Implementation
  42. protected:
  43. //{{AFX_MSG(CAboutDlg)
  44. //}}AFX_MSG
  45. DECLARE_MESSAGE_MAP()
  46. };
  47. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  48. {
  49. //{{AFX_DATA_INIT(CAboutDlg)
  50. //}}AFX_DATA_INIT
  51. }
  52. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  53. {
  54. CDialog::DoDataExchange(pDX);
  55. //{{AFX_DATA_MAP(CAboutDlg)
  56. //}}AFX_DATA_MAP
  57. }
  58. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  59. //{{AFX_MSG_MAP(CAboutDlg)
  60. // No message handlers
  61. //}}AFX_MSG_MAP
  62. END_MESSAGE_MAP()
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CNeroFiddlesDlg dialog
  65. CNeroFiddlesDlg::CNeroFiddlesDlg(CWnd* pParent /*=NULL*/)
  66. : CDialog(CNeroFiddlesDlg::IDD, pParent)
  67. , m_pFile(NULL)
  68. , m_pniiFile(NULL)
  69. , m_pnwcWriteCD(NULL)
  70. , m_pndiDeviceInfos(NULL)
  71. {
  72. //{{AFX_DATA_INIT(CNeroFiddlesDlg)
  73. //}}AFX_DATA_INIT
  74. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  75. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  76. }
  77. void CNeroFiddlesDlg::DoDataExchange(CDataExchange* pDX)
  78. {
  79. CDialog::DoDataExchange(pDX);
  80. //{{AFX_DATA_MAP(CNeroFiddlesDlg)
  81. DDX_Control(pDX, IDC_CLOSE, m_chkbxClose);
  82. DDX_Control(pDX, IDC_IMPORT, m_chkbxImport);
  83. DDX_Control(pDX, IDC_AUDIO, m_chkbxAudio);
  84. DDX_Control(pDX, IDC_REMOVE, m_btnRemove);
  85. DDX_Control(pDX, IDC_FILELIST, m_lstFileList);
  86. DDX_Control(pDX, IDOK, m_OK);
  87. DDX_Control(pDX, IDCANCEL, m_Cancel);
  88. DDX_Control(pDX, IDC_ABORT, m_btnAbort);
  89. DDX_Control(pDX, IDC_PROGRESS1, m_pgsProgress);
  90. DDX_Control(pDX, IDC_MESSAGES, m_edtMessages);
  91. DDX_Control(pDX, IDC_DEVICES, m_cbxDevices);
  92. DDX_Control(pDX, IDC_BURN, m_btnBurn);
  93. DDX_Control(pDX, IDC_BROWSE, m_btnBrowse);
  94. //}}AFX_DATA_MAP
  95. }
  96. BEGIN_MESSAGE_MAP(CNeroFiddlesDlg, CDialog)
  97. //{{AFX_MSG_MAP(CNeroFiddlesDlg)
  98. ON_WM_SYSCOMMAND()
  99. ON_WM_PAINT()
  100. ON_WM_QUERYDRAGICON()
  101. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  102. ON_BN_CLICKED(IDC_BURN, OnBurn)
  103. ON_BN_CLICKED(IDC_ABORT, OnAbort)
  104. ON_BN_CLICKED(IDC_REMOVE, OnRemove)
  105. ON_BN_CLICKED(IDC_AUDIO, OnAudio)
  106. ON_BN_CLICKED(IDC_IMPORT, OnImport)
  107. ON_LBN_SELCHANGE(IDC_FILELIST, OnSelchangeFilelist)
  108. //}}AFX_MSG_MAP
  109. END_MESSAGE_MAP()
  110. /////////////////////////////////////////////////////////////////////////////
  111. // CNeroFiddlesDlg message handlers
  112. BOOL CNeroFiddlesDlg::OnInitDialog()
  113. {
  114. CDialog::OnInitDialog();
  115. // Add "About..." menu item to system menu.
  116. // IDM_ABOUTBOX must be in the system command range.
  117. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  118. ASSERT(IDM_ABOUTBOX < 0xF000);
  119. CMenu* pSysMenu = GetSystemMenu(FALSE);
  120. if (pSysMenu != NULL)
  121. {
  122. CString strAboutMenu;
  123. strAboutMenu.LoadString(IDS_ABOUTBOX);
  124. if (!strAboutMenu.IsEmpty())
  125. {
  126. pSysMenu->AppendMenu(MF_SEPARATOR);
  127. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  128. }
  129. }
  130. // Set the icon for this dialog. The framework does this automatically
  131. // when the application's main window is not a dialog
  132. SetIcon(m_hIcon, TRUE); // Set big icon
  133. SetIcon(m_hIcon, FALSE); // Set small icon
  134. // TODO: Add extra initialization here
  135. // Initialize the NeroAPI
  136. NeroAPIInit();
  137. return TRUE; // return TRUE unless you set the focus to a control
  138. }
  139. void CNeroFiddlesDlg::OnSysCommand(UINT nID, LPARAM lParam)
  140. {
  141. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  142. {
  143. CAboutDlg dlgAbout;
  144. dlgAbout.DoModal();
  145. }
  146. else
  147. {
  148. CDialog::OnSysCommand(nID, lParam);
  149. }
  150. }
  151. // If you add a minimize button to your dialog, you will need the code below
  152. // to draw the icon. For MFC applications using the document/view model,
  153. // this is automatically done for you by the framework.
  154. void CNeroFiddlesDlg::OnPaint()
  155. {
  156. if (IsIconic())
  157. {
  158. CPaintDC dc(this); // device context for painting
  159. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  160. // Center icon in client rectangle
  161. int cxIcon = GetSystemMetrics(SM_CXICON);
  162. int cyIcon = GetSystemMetrics(SM_CYICON);
  163. CRect rect;
  164. GetClientRect(&rect);
  165. int x = (rect.Width() - cxIcon + 1) / 2;
  166. int y = (rect.Height() - cyIcon + 1) / 2;
  167. // Draw the icon
  168. dc.DrawIcon(x, y, m_hIcon);
  169. }
  170. else
  171. {
  172. CDialog::OnPaint();
  173. }
  174. }
  175. // The system calls this to obtain the cursor to display while the user drags
  176. // the minimized window.
  177. HCURSOR CNeroFiddlesDlg::OnQueryDragIcon()
  178. {
  179. return (HCURSOR) m_hIcon;
  180. }
  181. void CNeroFiddlesDlg::OnBrowse()
  182. {
  183. // browse for the MP3 file for audio or any other file types for data that is supposed to be burned on CD
  184. // provide information about the file type that we want to open
  185. static char BASED_CODE szFilterAudio[] = "MP3 Files (*.mp3)|*.mp3|All Files (*.*)|*.*||";
  186. static char BASED_CODE szFilterData[] = "All Files (*.*)|*.*||";
  187. // create a CFileDialog object.
  188. // usage : CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL,
  189. // DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL,
  190. // CWnd* pParentWnd = NULL );
  191. //
  192. // bOpenFileDialog = TRUE, create a File Open dialog
  193. // lpszDefExt = NULL, do not automatically append a file extension
  194. // dwFlags = OFN_FILEMUSTEXIST, only accepts file names for files that are present
  195. // szFilter = "MP3 Files (*.mp3)|*.mp3|All Files (*.*)|*.*||"
  196. // pParentWnd = this, our current Dialog window is the parent
  197. CFileDialog dlgOpen(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT, m_chkbxAudio.GetCheck() ? szFilterAudio : szFilterData, this);
  198. // do nothing if IDCANCEL is returned
  199. if (dlgOpen.DoModal() == IDOK)
  200. {
  201. // retrieve multiple file pathname and put them into list box, ensure one file only exist once
  202. POSITION pos = dlgOpen.GetStartPosition();
  203. while (pos != NULL)
  204. {
  205. CString filename = dlgOpen.GetNextPathName(pos);
  206. if (m_lstFileList.FindString(0, filename) == LB_ERR)
  207. {
  208. m_lstFileList.AddString(filename);
  209. }
  210. }
  211. // check whether any devices have been found
  212. if (m_pndiDeviceInfos->nsdisNumDevInfos > 0)
  213. {
  214. // make the "Burn" button accessible
  215. m_btnBurn.EnableWindow(true);
  216. }
  217. }
  218. }
  219. void CNeroFiddlesDlg::OnRemove()
  220. {
  221. // TODO: Add your control notification handler code here
  222. // delete selected filenames, must do it in reverse order
  223. int selCount = m_lstFileList.GetSelCount();
  224. if (selCount > 0)
  225. {
  226. int* selection = new int[selCount];
  227. m_lstFileList.GetSelItems(selCount, selection);
  228. for (int i = selCount - 1; i >= 0; --i)
  229. {
  230. m_lstFileList.DeleteString(selection[i]);
  231. }
  232. delete[] selection;
  233. }
  234. m_btnRemove.EnableWindow(false);
  235. }
  236. void CNeroFiddlesDlg::OnSelchangeFilelist()
  237. {
  238. // TODO: Add your control notification handler code here
  239. // enable or disable <remove> button when selection changed
  240. int selCount = m_lstFileList.GetSelCount();
  241. m_btnRemove.EnableWindow(selCount > 0);
  242. }
  243. void CNeroFiddlesDlg::OnBurn()
  244. {
  245. #if 1
  246. int i = m_cbxDevices.GetCurSel();
  247. NERO_SCSI_DEVICE_INFO* nsdiDevice = (NERO_SCSI_DEVICE_INFO*)m_cbxDevices.GetItemDataPtr(i);
  248. m_ndhDeviceHandle = NeroOpenDevice(nsdiDevice);
  249. if(FALSE)
  250. {
  251. NERO_IMPORT_DATA_TRACK_INFO nidtInfo;
  252. NERO_IMPORT_DATA_TRACK_RESULT nidtResult;
  253. // Prepare the struct.
  254. CString csUserMsg = "";
  255. memset(&nidtInfo, 0, sizeof(nidtInfo));
  256. nidtInfo.nidtiSize = sizeof(nidtInfo);
  257. void* pCDStamp = NULL;
  258. NERO_ISO_ITEM* pniiItem = NULL;
  259. NERO_CD_INFO* pnciInfo = NeroGetCDInfo(m_ndhDeviceHandle, 0);
  260. if(pnciInfo != NULL)
  261. {
  262. pniiItem = NeroImportDataTrack(m_ndhDeviceHandle, pnciInfo->ncdiNumTracks - 1, &pCDStamp, &nidtInfo, 0, &nidtResult, NULL);
  263. NeroFreeMem(pnciInfo);
  264. }
  265. // If there is a volume name after import, print it out.
  266. if(nidtInfo.nidtipVolumeName != NULL)
  267. {
  268. csUserMsg.Format("Imported volume name: %s", nidtInfo.nidtipVolumeName);
  269. AppendString(csUserMsg);
  270. NeroFreeMem (nidtInfo.nidtipVolumeName);
  271. }
  272. // If there was an error during import, let the user know about it.
  273. if((nidtResult != NIDTR_NO_ERROR) || (pniiItem == NULL))
  274. {
  275. static LPCSTR errors[] = {"an unknown error","a generic error","a drive error","a read error","a filesystem error","an invalid track number"};
  276. if (nidtResult > NIDTR_INVALID_TRACKNUMBER)
  277. nidtResult = NIDTR_NO_ERROR;
  278. csUserMsg.Format("There was %s while importing the track!", errors[nidtResult]);
  279. AppendString(csUserMsg);
  280. }
  281. else if(m_pniiFile != NULL)
  282. {
  283. if(MergeIsoTracks(&m_pniiFile, pniiItem)) // Merge the new track with the existing one.
  284. m_pnwcWriteCD->nwcdpCDStamp = pCDStamp;
  285. else
  286. {
  287. AppendString("There was an error while merging tracks!");
  288. if(pCDStamp != NULL)
  289. NeroFreeCDStamp(pCDStamp), pCDStamp = NULL;
  290. }
  291. }
  292. }
  293. CDiscItem tagDiscItem;
  294. tagDiscItem.AddSiblingRootItem(_T("光盘根目录"),TRUE);
  295. #if 1
  296. tagDiscItem.AddPath2Path(_T("光盘根目录"), _T("光盘2级目录-A"));
  297. tagDiscItem.AddPath2Path(_T("光盘根目录"), _T("光盘2级目录-B"));
  298. tagDiscItem.AddPath2Path(_T("光盘根目录"), _T("光盘2级目录-C"));
  299. tagDiscItem.AddPath2Path(_T("光盘根目录"), _T("光盘2级目录-D"));
  300. tagDiscItem.AddFile2Path(_T("光盘根目录"),_T("F:\\刻录驱动.rar"));
  301. tagDiscItem.AddFile2Path(_T("光盘根目录"),_T("C:\\Users\\IT\\Downloads\\QQ7.9Light.exe"));
  302. tagDiscItem.AddFile2Path(_T("光盘根目录"),_T("C:\\Users\\IT\\Downloads\\CDBurn_imapi.rar"));
  303. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A"),_T("F:\\刻录驱动.rar"));
  304. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-B"),_T("F:\\刻录驱动.rar"));
  305. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-C"),_T("F:\\刻录驱动.rar"));
  306. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-D"),_T("F:\\刻录驱动.rar"));
  307. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-A"), _T("光盘3级目录-A"));
  308. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-A"), _T("光盘3级目录-B"));
  309. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-A"), _T("光盘3级目录-C"));
  310. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-A"), _T("光盘3级目录-D"));
  311. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B"), _T("光盘3级目录-A"));
  312. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B"), _T("光盘3级目录-B"));
  313. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B"), _T("光盘3级目录-C"));
  314. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B"), _T("光盘3级目录-D"));
  315. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-C"), _T("光盘3级目录-A"));
  316. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-C"), _T("光盘3级目录-B"));
  317. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-C"), _T("光盘3级目录-C"));
  318. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-C"), _T("光盘3级目录-D"));
  319. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D"), _T("光盘3级目录-A"));
  320. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D"), _T("光盘3级目录-B"));
  321. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D"), _T("光盘3级目录-C"));
  322. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D"), _T("光盘3级目录-D"));
  323. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-A"),_T("F:\\刻录驱动.rar"));
  324. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-B"),_T("F:\\刻录驱动.rar"));
  325. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-C"),_T("F:\\刻录驱动.rar"));
  326. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-D"),_T("F:\\刻录驱动.rar"));
  327. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B\\光盘3级目录-B"), _T("光盘4级目录-A"));
  328. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B\\光盘3级目录-B"), _T("光盘4级目录-B"));
  329. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B\\光盘3级目录-B"), _T("光盘4级目录-C"));
  330. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-B\\光盘3级目录-B"), _T("光盘4级目录-D"));
  331. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D\\光盘3级目录-B"), _T("光盘4级目录-A"));
  332. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D\\光盘3级目录-B"), _T("光盘4级目录-B"));
  333. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D\\光盘3级目录-B"), _T("光盘4级目录-C"));
  334. tagDiscItem.AddPath2Path(_T("光盘根目录\\光盘2级目录-D\\光盘3级目录-B"), _T("光盘4级目录-D"));
  335. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-A\\光盘4级目录-A"),_T("F:\\刻录驱动.rar"));
  336. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-A\\光盘4级目录-B"),_T("F:\\刻录驱动.rar"));
  337. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-A\\光盘4级目录-C"),_T("F:\\刻录驱动.rar"));
  338. tagDiscItem.AddFile2Path(_T("光盘根目录\\光盘2级目录-A\\光盘3级目录-A\\光盘4级目录-D"),_T("F:\\刻录驱动.rar"));
  339. tagDiscItem.AddSiblingPath(_T("光盘根目录"),_T("光盘根目录2"));
  340. tagDiscItem.AddSiblingPath(_T("光盘根目录"),_T("光盘根目录3"));
  341. tagDiscItem.AddSiblingPath(_T("光盘根目录"),_T("光盘根目录4"));
  342. tagDiscItem.AddSiblingPath(_T("光盘根目录"),_T("光盘根目录5"));
  343. tagDiscItem.AddSiblingPath(_T("光盘根目录"),_T("光盘根目录6"));
  344. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录2"),_T("光盘根目录21"));
  345. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录3"),_T("光盘根目录31"));
  346. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录4"),_T("光盘根目录41"));
  347. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录5"),_T("光盘根目录51"));
  348. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录6"),_T("光盘根目录61"));
  349. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录2"),_T("光盘根目录22"));
  350. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录3"),_T("光盘根目录32"));
  351. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录4"),_T("光盘根目录42"));
  352. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录5"),_T("光盘根目录52"));
  353. tagDiscItem.AddSiblingPath(_T("光盘根目录\\光盘根目录6"),_T("光盘根目录62"));
  354. #endif
  355. m_pniiFile = tagDiscItem.GetDiscItem();
  356. if(m_pnwcWriteCD != NULL)
  357. free(m_pnwcWriteCD), m_pnwcWriteCD = NULL;
  358. size_t stTheSize = sizeof(NERO_WRITE_CD);
  359. m_pnwcWriteCD = (NERO_WRITE_CD*)malloc(stTheSize);
  360. memset(m_pnwcWriteCD, 0, stTheSize);
  361. // no CD stamp, artist or title required
  362. m_pnwcWriteCD->nwcdpCDStamp = NULL;
  363. m_pnwcWriteCD->nwcdArtist = NULL;
  364. m_pnwcWriteCD->nwcdTitle = NULL;
  365. // no CD Extra information available
  366. m_pnwcWriteCD->nwcdCDExtra = FALSE;
  367. // do we have Audio tracks?
  368. m_pnwcWriteCD->nwcdNumTracks = 0;
  369. m_pnwcWriteCD->nwcdMediaType = MEDIA_DVD_ANY;
  370. m_pgsProgress.SetRange(0,100);
  371. // 创建刻录任务;
  372. m_pnwcWriteCD->nwcdIsoTrack = NeroCreateIsoTrackEx(m_pniiFile, "NeroFiddles", NCITEF_CREATE_ISO_FS|NCITEF_USE_JOLIET);
  373. // 开始刻录;
  374. int iRes = NeroBurn(m_ndhDeviceHandle, NERO_ISO_AUDIO_MEDIA, m_pnwcWriteCD, NBF_WRITE | NBF_CLOSE_SESSION , 10, &m_npProgress);
  375. // 获取刻录日志;
  376. //char* Log = NeroGetErrorLog();
  377. if(m_pnwcWriteCD != NULL)
  378. {
  379. if(m_pnwcWriteCD->nwcdpCDStamp != NULL)
  380. NeroFreeCDStamp(m_pnwcWriteCD->nwcdpCDStamp), m_pnwcWriteCD->nwcdpCDStamp = NULL;
  381. free(m_pnwcWriteCD), m_pnwcWriteCD = NULL;
  382. }
  383. // 关闭设备;
  384. NeroCloseDevice(m_ndhDeviceHandle);
  385. tagDiscItem.RemoveRootItem();
  386. #else
  387. // TODO: Add your control notification handler code here
  388. // perform the burn process
  389. // check whether a file has been selected
  390. if (m_lstFileList.GetCount() == 0)
  391. {
  392. // Tell the user what went wrong
  393. AppendString("You have to choose some files before you can start burning!");
  394. }
  395. else
  396. {
  397. // Get the number of audio files. The NERO_WRITE_CD struct already provides space for 1 audio track.
  398. int iNumAudio = 1;
  399. if(m_chkbxAudio.GetCheck())
  400. {
  401. for (int index = 0; index < m_lstFileList.GetCount(); ++index)
  402. {
  403. CString pathname;
  404. m_lstFileList.GetText(index, pathname);
  405. if(pathname.Right(4) == ".mp3")
  406. iNumAudio++;
  407. }
  408. }
  409. // usually this should always be uninitialized at this place but to be sure...
  410. if(m_pnwcWriteCD != NULL)
  411. free(m_pnwcWriteCD), m_pnwcWriteCD = NULL;
  412. // and allocate the memory for all initialization data
  413. size_t stTheSize = sizeof(NERO_WRITE_CD) + ((iNumAudio - 1) * sizeof(NERO_AUDIO_TRACK));
  414. m_pnwcWriteCD = (NERO_WRITE_CD*)malloc(stTheSize);
  415. memset(m_pnwcWriteCD, 0, stTheSize);
  416. // create NERO_ISO_ITEM struct from file list or even append audio tracks
  417. NERO_ISO_ITEM* niiPrevItem = NULL;
  418. NERO_ISO_ITEM* pItem1 = new NERO_ISO_ITEM;
  419. NERO_ISO_ITEM* pItem2 = new NERO_ISO_ITEM;
  420. memset(pItem1, 0, sizeof(NERO_ISO_ITEM));
  421. memset(pItem2, 0, sizeof(NERO_ISO_ITEM));
  422. pItem1->longFileName = strdup(_T("目录7"));
  423. pItem1->isDirectory = TRUE;
  424. m_pniiFile = pItem1;
  425. pItem2->longFileName = _strdup(_T("目录8"));
  426. pItem2->isDirectory = TRUE;
  427. pItem1->nextItem = pItem2;
  428. int iTrackCnt = 0;
  429. for (int index = 0; index < m_lstFileList.GetCount(); ++index)
  430. {
  431. CString pathname;
  432. m_lstFileList.GetText(index, pathname);
  433. AppendString("Preparing data file:" + pathname);
  434. char path[MAX_PATH];
  435. char* name;
  436. GetFullPathName(pathname, MAX_PATH, path, &name);
  437. if(!m_chkbxAudio.GetCheck())
  438. {
  439. NERO_ISO_ITEM* pniiNewItem = NeroCreateIsoItem();
  440. memset(pniiNewItem, 0, sizeof(NERO_ISO_ITEM));
  441. if (m_pniiFile == 0) // mniiFile refer to the first item
  442. m_pniiFile = pniiNewItem;
  443. pniiNewItem->longFileName = _strdup(name);
  444. pniiNewItem->longSourceFilePath = _strdup(path);
  445. pniiNewItem->isDirectory = FALSE;
  446. pniiNewItem->isReference = FALSE;
  447. pniiNewItem->unicodeFileName = NULL;
  448. pniiNewItem->nextItem = NULL;
  449. if(niiPrevItem)
  450. niiPrevItem->nextItem = pniiNewItem;
  451. niiPrevItem = pniiNewItem;
  452. pItem1->subDirFirstItem = pniiNewItem;
  453. pItem2->subDirFirstItem = pniiNewItem;
  454. }
  455. else if((pathname.Right(4) == ".mp3") && (iTrackCnt < iNumAudio))
  456. {
  457. // initialize the audio tracks memeber of NERO_WRITE_CD struct if we are about to write audio CD
  458. m_pnwcWriteCD->nwcdTracks[iTrackCnt].natPauseInBlksBeforeThisTrack = 150; // Always 2 sec. pause before
  459. m_pnwcWriteCD->nwcdTracks[iTrackCnt].natSourceDataExchg.ndeType = NERO_ET_FILE_MP3; // Has to be mp3 file
  460. NERO_DATA_EXCHANGE& ndeCurrent = m_pnwcWriteCD->nwcdTracks[iTrackCnt].natSourceDataExchg;
  461. ndeCurrent.ndeData.ndeLongFileName.reserved = 0; // As requested
  462. ndeCurrent.ndeData.ndeLongFileName.ptr = _strdup(path); // Last but not least the path
  463. iTrackCnt++;
  464. }
  465. }
  466. // no CD stamp, artist or title required
  467. m_pnwcWriteCD->nwcdpCDStamp = NULL;
  468. m_pnwcWriteCD->nwcdArtist = NULL;
  469. m_pnwcWriteCD->nwcdTitle = NULL;
  470. // no CD Extra information available
  471. m_pnwcWriteCD->nwcdCDExtra = FALSE;
  472. // do we have Audio tracks?
  473. m_pnwcWriteCD->nwcdNumTracks = iTrackCnt;
  474. // we want to write to a CD
  475. //m_pnwcWriteCD->nwcdMediaType = MEDIA_CD;
  476. m_pnwcWriteCD->nwcdMediaType = MEDIA_DVD_ANY;
  477. // get the currently selected device from the ComboBox
  478. int i = m_cbxDevices.GetCurSel();
  479. // retrieve the NERO_SCSI_DEVICE_INFO pointer for the selected device
  480. // and assign it to a local variable
  481. NERO_SCSI_DEVICE_INFO* nsdiDevice = (NERO_SCSI_DEVICE_INFO*)m_cbxDevices.GetItemDataPtr(i);
  482. // try to open the selected device
  483. m_ndhDeviceHandle = NeroOpenDevice(nsdiDevice);
  484. // check whether a valid handle was returned
  485. if (!m_ndhDeviceHandle)
  486. {
  487. // no handle available; tell the user what happened
  488. AppendString("Device could not be opened: "+(CString)nsdiDevice->nsdiDeviceName);
  489. }
  490. else
  491. {
  492. // Now, import the last session if wished. If the function fails, it's probably
  493. // due to no CD in drive.
  494. // NeroImportDataTrack creates a NERO_ISO_ITEM tree from an already existing ISO
  495. // track in order to create a new session with reference to files from older sessions.
  496. // m_pCDStamp will be filled with a pointer to a CDStamp object
  497. // which will have to be freed later by the CBurnContext destructor.
  498. if(m_chkbxImport.GetCheck())
  499. {
  500. NERO_IMPORT_DATA_TRACK_INFO nidtInfo;
  501. NERO_IMPORT_DATA_TRACK_RESULT nidtResult;
  502. // Prepare the struct.
  503. CString csUserMsg = "";
  504. memset(&nidtInfo, 0, sizeof(nidtInfo));
  505. nidtInfo.nidtiSize = sizeof(nidtInfo);
  506. void* pCDStamp = NULL;
  507. NERO_ISO_ITEM* pniiItem = NULL;
  508. NERO_CD_INFO* pnciInfo = NeroGetCDInfo(m_ndhDeviceHandle, 0);
  509. if(pnciInfo != NULL)
  510. {
  511. pniiItem = NeroImportDataTrack(m_ndhDeviceHandle, pnciInfo->ncdiNumTracks - 1, &pCDStamp, &nidtInfo, 0, &nidtResult, NULL);
  512. NeroFreeMem(pnciInfo);
  513. }
  514. // If there is a volume name after import, print it out.
  515. if(nidtInfo.nidtipVolumeName != NULL)
  516. {
  517. csUserMsg.Format("Imported volume name: %s", nidtInfo.nidtipVolumeName);
  518. AppendString(csUserMsg);
  519. NeroFreeMem (nidtInfo.nidtipVolumeName);
  520. }
  521. // If there was an error during import, let the user know about it.
  522. if((nidtResult != NIDTR_NO_ERROR) || (pniiItem == NULL))
  523. {
  524. static LPCSTR errors[] = {"an unknown error","a generic error","a drive error","a read error","a filesystem error","an invalid track number"};
  525. if (nidtResult > NIDTR_INVALID_TRACKNUMBER)
  526. nidtResult = NIDTR_NO_ERROR;
  527. csUserMsg.Format("There was %s while importing the track!", errors[nidtResult]);
  528. AppendString(csUserMsg);
  529. }
  530. else if(m_pniiFile != NULL)
  531. {
  532. if(MergeIsoTracks(&m_pniiFile, pniiItem)) // Merge the new track with the existing one.
  533. m_pnwcWriteCD->nwcdpCDStamp = pCDStamp;
  534. else
  535. {
  536. AppendString("There was an error while merging tracks!");
  537. if(pCDStamp != NULL)
  538. NeroFreeCDStamp(pCDStamp), pCDStamp = NULL;
  539. }
  540. }
  541. }
  542. // we have a valid device handle
  543. // while burning the "Abort" button needs to be enabled
  544. // all the other buttons and controls have to be disabled
  545. m_btnAbort.EnableWindow(true);
  546. m_Cancel.EnableWindow(false);
  547. m_OK.EnableWindow(false);
  548. m_cbxDevices.EnableWindow(false);
  549. m_btnBrowse.EnableWindow(false);
  550. m_btnBurn.EnableWindow(false);
  551. m_btnRemove.EnableWindow(false);
  552. m_chkbxAudio.EnableWindow(false);
  553. m_chkbxImport.EnableWindow(false);
  554. m_chkbxClose.EnableWindow(false);
  555. // set the range for the progress control, we will display percent
  556. m_pgsProgress.SetRange(0,100);
  557. // create an ISO track, the audio tracks are initialized above
  558. // usage : NeroCreateIsoTrack(struct NERO_ISO_ITEM *root, const char *name,
  559. // BOOL useJoliet, BOOL useMode2);
  560. //
  561. // root = mniiFile, the NERO_ISO_ITEM we filled before
  562. // name = neroFiddles
  563. if(!m_chkbxAudio.GetCheck())
  564. {
  565. m_pnwcWriteCD->nwcdIsoTrack = NeroCreateIsoTrackEx(m_pniiFile, "NeroFiddles", NCITEF_CREATE_ISO_FS|NCITEF_USE_JOLIET);
  566. }
  567. // start the burn process by calling NeroBurn
  568. // usage:NEROAPI_BURN_ERROR NADLL_ATTR NeroBurn( NERO_DEVICEHANDLE aDeviceHandle,
  569. // NERO_CD_FORMAT CDFormat, const void* pWriteCD, DWORD dwFlags, DWORD dwSpeedInX,
  570. // NERO_PROGRESS* pNeroProgress);
  571. //
  572. // aDeviceHandle = ndhDeviceHandle, the handle we got from NeroOpenDevice()
  573. // CDFormat = NERO_ISO_AUDIO_CD
  574. // pWriteCD = writeCD
  575. // dwFlags = NBF_WRITE, do not simulate - burn! NBF_CLOSE_SESSION means close only the session not the entire disc.
  576. // dwSpeedInX = 0, use maximum speed
  577. // pNeroProgress = npProgress, filled during NeroAPIInit()
  578. int iRes = NeroBurn(m_ndhDeviceHandle, /*NERO_ISO_AUDIO_CD*/NERO_ISO_AUDIO_MEDIA, m_pnwcWriteCD, NBF_WRITE | (!m_chkbxClose.GetCheck() ? NBF_CLOSE_SESSION : 0), 10, &m_npProgress);
  579. // free memory that was allocated for the track
  580. if(!m_chkbxAudio.GetCheck() && (m_pnwcWriteCD->nwcdIsoTrack != NULL))
  581. NeroFreeIsoTrack(m_pnwcWriteCD->nwcdIsoTrack);
  582. // close the device
  583. NeroCloseDevice(m_ndhDeviceHandle);
  584. // burning is finished, disable "Abort" activate all other controls
  585. m_btnAbort.EnableWindow(false);
  586. m_Cancel.EnableWindow(true);
  587. m_OK.EnableWindow(true);
  588. m_cbxDevices.EnableWindow(true);
  589. m_btnBrowse.EnableWindow(true);
  590. m_btnBurn.EnableWindow(true);
  591. m_btnRemove.EnableWindow(m_lstFileList.GetSelCount() > 0);
  592. m_chkbxAudio.EnableWindow(!m_chkbxImport.GetCheck());
  593. m_chkbxImport.EnableWindow(!m_chkbxAudio.GetCheck());
  594. m_chkbxClose.EnableWindow(!m_chkbxAudio.GetCheck());
  595. // clear the progress bar
  596. m_pgsProgress.SetPos(0);
  597. // make sure that aborted flag is not set if "Burn" button is pressed again
  598. m_bAborted = false;
  599. // retrieve the error log
  600. char* Log = NeroGetErrorLog();
  601. // display the error log contents
  602. AppendString(Log);
  603. // free the log
  604. NeroFreeMem(Log);
  605. // free NERO_ISO_ITEM struct list
  606. DeleteIsoItemTree(m_pniiFile);
  607. m_pniiFile = NULL;
  608. // free the memory allocated for audio tracks file paths
  609. for(int i = 0; i < iTrackCnt; i++)
  610. {
  611. const char* pcPath = m_pnwcWriteCD->nwcdTracks[i].natSourceDataExchg.ndeData.ndeLongFileName.ptr;
  612. if(pcPath != NULL)
  613. free((void*)pcPath), pcPath = NULL;
  614. }
  615. // Free the NERO_WRITE_CD struct too
  616. if(m_pnwcWriteCD != NULL)
  617. {
  618. if(m_pnwcWriteCD->nwcdpCDStamp != NULL)
  619. NeroFreeCDStamp(m_pnwcWriteCD->nwcdpCDStamp), m_pnwcWriteCD->nwcdpCDStamp = NULL;
  620. free(m_pnwcWriteCD), m_pnwcWriteCD = NULL;
  621. }
  622. // tell the user how the burn process was finished
  623. switch(iRes)
  624. {
  625. case NEROAPI_BURN_OK:
  626. AppendString ("BurnCD() : burn successful");
  627. break;
  628. case NEROAPI_BURN_UNKNOWN_CD_FORMAT:
  629. AppendString ("BurnCD() : unknown CD format");
  630. break;
  631. case NEROAPI_BURN_INVALID_DRIVE:
  632. AppendString ("BurnCD() : invalid drive");
  633. break;
  634. case NEROAPI_BURN_FAILED:
  635. AppendString ("BurnCD() : burn failed");
  636. break;
  637. case NEROAPI_BURN_FUNCTION_NOT_ALLOWED:
  638. AppendString ("BurnCD() : function not allowed");
  639. break;
  640. case NEROAPI_BURN_DRIVE_NOT_ALLOWED:
  641. AppendString ("BurnCD() : drive not allowed");
  642. break;
  643. case NEROAPI_BURN_USER_ABORT:
  644. AppendString ("BurnCD() : user aborted");
  645. break;
  646. case NEROAPI_BURN_BAD_MESSAGE_FILE:
  647. AppendString ("BurnCD() : bad message file");
  648. break;
  649. default:
  650. AppendString ("BurnCD() : unknown error");
  651. break;
  652. }
  653. }
  654. }
  655. #endif
  656. }
  657. BOOL NERO_CALLBACK_ATTR CNeroFiddlesDlg::IdleCallback(void *pUserData)
  658. {
  659. // idle callback is called frequently by NeroAPI
  660. // make sure that messages from other controls can be handled
  661. static MSG msg;
  662. while (!(((CNeroFiddlesDlg*)pUserData)->m_bAborted) && ::PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE))
  663. {
  664. if (!AfxGetThread()->PumpMessage())
  665. {
  666. break;
  667. }
  668. }
  669. // aborted-flag serves as function result
  670. return ((CNeroFiddlesDlg*)pUserData)->m_bAborted;
  671. }
  672. void CNeroFiddlesDlg::NeroAPIInit()
  673. {
  674. // initialization part, provide necessary information and check status
  675. m_bAborted = false;
  676. // try to open the NeroAPI DLL
  677. if (!NeroAPIGlueConnect (NULL))
  678. {
  679. AppendString("Cannot open NeroAPI.DLL");
  680. // it makes no sense to continue after loading the DLL failed
  681. return;
  682. }
  683. // the NeroAPI DLL could be openend, get version information
  684. AppendString("Retrieving version information.");
  685. WORD majhi, majlo, minhi, minlo;
  686. NeroGetAPIVersionEx(&majhi, &majlo, &minhi, &minlo, NULL);
  687. // format and display the version information
  688. CString strVersion;
  689. strVersion.Format("NeroAPI version %d.%d.%d.%d",
  690. majhi, majlo, minhi, minlo);
  691. AppendString(strVersion);
  692. // setup of structures that the NeroAPI needs
  693. AppendString("Filling NERO_SETTINGS structure");
  694. // Information for registry access
  695. strcpy(m_pcNeroFilesPath, "NeroFiles");
  696. strcpy(m_pcVendor, "Nero");
  697. strcpy(m_pcSoftware, "Nero - NeroFiddles");
  698. // use the US-English error message file
  699. strcpy(m_pcLanguageFile, "Nero.txt");
  700. // Initialize NeroAPI settings
  701. m_nsSettings.nstNeroFilesPath = m_pcNeroFilesPath;
  702. m_nsSettings.nstVendor = m_pcVendor;
  703. // set pointers to various callback functions
  704. m_nsSettings.nstIdle.ncCallbackFunction = IdleCallback;
  705. // this pointer is required to access non-static variables from callback functions
  706. m_nsSettings.nstIdle.ncUserData = this;
  707. m_nsSettings.nstSoftware = m_pcSoftware;
  708. m_nsSettings.nstUserDialog.ncCallbackFunction = UserDialog;
  709. m_nsSettings.nstUserDialog.ncUserData = this;
  710. m_nsSettings.nstLanguageFile = m_pcLanguageFile;
  711. // npProgress will be used during the burn process
  712. m_npProgress.npAbortedCallback = AbortedCallback;
  713. m_npProgress.npAddLogLineCallback = AddLogLine;
  714. m_npProgress.npDisableAbortCallback = NULL;
  715. m_npProgress.npProgressCallback = ProgressCallback;
  716. m_npProgress.npSetPhaseCallback = SetPhaseCallback;
  717. m_npProgress.npUserData = this;
  718. m_npProgress.npSetMajorPhaseCallback = NULL;
  719. m_npProgress.npSubTaskProgressCallback= NULL;
  720. // no devices available yet
  721. m_pndiDeviceInfos = NULL;
  722. // initialize the NeroAPI with nsSettings and the
  723. // Serial Number that we got from the Registry
  724. NEROAPI_INIT_ERROR initErr;
  725. initErr = NeroInit (&m_nsSettings, NULL);
  726. // display the result of NeroInit()
  727. switch (initErr)
  728. {
  729. case NEROAPI_INIT_OK:
  730. AppendString("Initialization of the NeroAPI successful.");
  731. break;
  732. case NEROAPI_INIT_INVALID_ARGS:
  733. AppendString("The arguments are not valid.");
  734. break;
  735. case NEROAPI_INIT_INVALID_SERIAL_NUM:
  736. AppendString("The Serial Number is not valid.");
  737. break;
  738. default:
  739. AppendString("An error occured. The type of error cannot be determined.");
  740. break;
  741. }
  742. // get a list of available drives
  743. m_pndiDeviceInfos = NeroGetAvailableDrivesEx (MEDIA_CD, NULL);
  744. // check whether any devices have been found
  745. if (!m_pndiDeviceInfos)
  746. {
  747. // no device found, let the user know
  748. AppendString("NeroGetAvailableDrivesEx() returned no available devices.");
  749. }
  750. else
  751. {
  752. // devices found
  753. // check the number of available devices to be sure
  754. if (m_pndiDeviceInfos->nsdisNumDevInfos > 0)
  755. {
  756. // we have some devices, now fill the ComboBox
  757. AppendString("Found the following devices:");
  758. for (DWORD dDeviceCounter = 0; dDeviceCounter < m_pndiDeviceInfos->nsdisNumDevInfos; dDeviceCounter++)
  759. {
  760. AppendString(m_pndiDeviceInfos->nsdisDevInfos[dDeviceCounter].nsdiDeviceName);
  761. // add the device name to the ComboBox and get the index number
  762. int i = m_cbxDevices.AddString(m_pndiDeviceInfos->nsdisDevInfos[dDeviceCounter].nsdiDeviceName);
  763. // use the index number to access the corresponding entry
  764. // connect the entry's ItemData pointer to a NERO_DEVICE_INFO structure
  765. m_cbxDevices.SetItemDataPtr(i, &m_pndiDeviceInfos->nsdisDevInfos[dDeviceCounter]);
  766. }
  767. // select the first ComboBox entry
  768. m_cbxDevices.SelectString(-1, m_pndiDeviceInfos->nsdisDevInfos[0].nsdiDeviceName);
  769. }
  770. else
  771. {
  772. AppendString("The number of available devices is 0.");
  773. }
  774. }
  775. }
  776. void CNeroFiddlesDlg::AppendString(CString str)
  777. {
  778. // a CString for temporary use
  779. CString strBuffer;
  780. // retrieve the content of the EditControl we use for messages
  781. m_edtMessages.GetWindowText (strBuffer);
  782. // add a new line if the EditControl is not empty
  783. if (!strBuffer.IsEmpty())
  784. {
  785. strBuffer += "\r\n";
  786. }
  787. // append the string the function got as a parameter
  788. strBuffer += str;
  789. // update the EditiControl with the new content
  790. m_edtMessages.SetWindowText (strBuffer);
  791. // Scroll the edit control to the end
  792. m_edtMessages.LineScroll (m_edtMessages.GetLineCount(), 0);
  793. }
  794. NeroUserDlgInOut NERO_CALLBACK_ATTR CNeroFiddlesDlg::UserDialog(void *pUserData, NeroUserDlgInOut type, void *data)
  795. {
  796. // handling of messages that require the user to perform an action
  797. // for reasons of brevity we only deal with the messages that
  798. // are absolutely mandatory for this application
  799. switch (type)
  800. {
  801. case DLG_AUTO_INSERT:
  802. return DLG_RETURN_CONTINUE;
  803. break;
  804. case DLG_DISCONNECT_RESTART:
  805. return DLG_RETURN_ON_RESTART;
  806. break;
  807. case DLG_DISCONNECT:
  808. return DLG_RETURN_CONTINUE;
  809. break;
  810. case DLG_AUTO_INSERT_RESTART:
  811. return DLG_RETURN_EXIT;
  812. break;
  813. case DLG_RESTART:
  814. return DLG_RETURN_EXIT;
  815. break;
  816. case DLG_SETTINGS_RESTART:
  817. return DLG_RETURN_CONTINUE;
  818. break;
  819. case DLG_OVERBURN:
  820. return DLG_RETURN_TRUE;
  821. break;
  822. case DLG_AUDIO_PROBLEMS:
  823. return DLG_RETURN_EXIT;
  824. break;
  825. case DLG_FILESEL_IMAGE:
  826. {
  827. // create filter for image files
  828. static char BASED_CODE szFilter[] = "Image Files (*.nrg)|*.nrg|All Files (*.*)|*.*||";
  829. // create a CFileDialog object.
  830. // usage : CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL,
  831. // DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL,
  832. // CWnd* pParentWnd = NULL );
  833. //
  834. // bOpenFileDialog = TRUE, create a File Open dialog
  835. // lpszDefExt = NULL, do not automatically append a file extension
  836. // dwFlags = OFN_OVERWRITEPROMPT, makes no sense during file open,
  837. // just in case we decide to use File Save later
  838. // szFilter = "Image Files (*.nrg)|*.nrg|All Files (*.*)|*.*||"
  839. // pParentWnd = ((CNeroFiddlesDlg*)pUserData), our current Dialog window is the parent
  840. CFileDialog dlgOpen(TRUE, NULL, "test.nrg", OFN_OVERWRITEPROMPT, szFilter, ((CNeroFiddlesDlg*)pUserData));
  841. // check how the dialog was ended
  842. if (dlgOpen.DoModal() == IDOK)
  843. {
  844. // user pressed "OK", copy the file name to the data parameter
  845. strcpy((char*)data,dlgOpen.GetPathName());
  846. // proceed with the burn process
  847. return DLG_RETURN_TRUE;
  848. }
  849. else
  850. {
  851. // user canceled, do not proceed with the burn process
  852. return DLG_BURNIMAGE_CANCEL;
  853. }
  854. }
  855. break;
  856. case DLG_WAITCD:
  857. {
  858. NERO_WAITCD_TYPE waitcdType = (NERO_WAITCD_TYPE) (int)data;
  859. char *waitcdString = NeroGetLocalizedWaitCDTexts (waitcdType);
  860. ((CNeroFiddlesDlg*)pUserData)->AppendString(waitcdString);
  861. NeroFreeMem(waitcdString);
  862. return DLG_RETURN_EXIT;
  863. break;
  864. }
  865. default:
  866. break;
  867. }
  868. // default return value, in case we forgot to handle a request
  869. return DLG_RETURN_EXIT;
  870. }
  871. BOOL NERO_CALLBACK_ATTR CNeroFiddlesDlg::ProgressCallback(void *pUserData, DWORD dwProgressInPercent)
  872. {
  873. // the NeroAPI updates the current progress counter
  874. // set the progress bar to the percentage value that was passed to this function
  875. ((CNeroFiddlesDlg*)pUserData)->m_pgsProgress.SetPos(dwProgressInPercent);
  876. return true;
  877. }
  878. BOOL NERO_CALLBACK_ATTR CNeroFiddlesDlg::AbortedCallback(void *pUserData)
  879. {
  880. // do not ask the user if he really wants to abort
  881. // just return the aborted flag
  882. return ((CNeroFiddlesDlg*)pUserData)->m_bAborted;
  883. }
  884. void NERO_CALLBACK_ATTR CNeroFiddlesDlg::AddLogLine(void *pUserData, NERO_TEXT_TYPE type, const char *text)
  885. {
  886. // Add the text that was passed to this function to the message log
  887. CString csTemp(text);
  888. ((CNeroFiddlesDlg*)pUserData)->AppendString("Log line:" + csTemp);
  889. return;
  890. }
  891. void NERO_CALLBACK_ATTR CNeroFiddlesDlg::SetPhaseCallback(void *pUserData, const char *text)
  892. {
  893. // display the current phase the burn process is currently going through
  894. CString csTemp(text);
  895. ((CNeroFiddlesDlg*)pUserData)->AppendString("Phase: " + csTemp);
  896. return;
  897. }
  898. void CNeroFiddlesDlg::NeroAPIFree()
  899. {
  900. // free the resources that have been used
  901. // make sure there is something to free so we do not run into an exception
  902. if (m_pndiDeviceInfos)
  903. {
  904. NeroFreeMem(m_pndiDeviceInfos);
  905. }
  906. // nothing to check before calling these functions
  907. NeroClearErrors();
  908. if(NeroDone())
  909. {
  910. AfxMessageBox("Detected memory leaks in NeroFiddles");
  911. }
  912. NeroAPIGlueDone();
  913. return;
  914. }
  915. void CNeroFiddlesDlg::OnOK()
  916. {
  917. // TODO: Add extra validation here
  918. // user decides to quit by pressing "OK"
  919. NeroAPIFree();
  920. CDialog::OnOK();
  921. }
  922. void CNeroFiddlesDlg::OnCancel()
  923. {
  924. // TODO: Add extra cleanup here
  925. // user decides to quit by pressing "Cancel"
  926. // we handle this like the "OK" button
  927. NeroAPIFree();
  928. CDialog::OnCancel();
  929. }
  930. void CNeroFiddlesDlg::OnAbort()
  931. {
  932. // TODO: Add your control notification handler code here
  933. // nothing more required but setting the aborted flag
  934. m_bAborted = true;
  935. }
  936. void CNeroFiddlesDlg::OnAudio()
  937. {
  938. // TODO: Add your control notification handler code here
  939. // If we should burn audio disc we are not able to import previous sessions
  940. // and they are always closed
  941. m_chkbxImport.EnableWindow(!m_chkbxAudio.GetCheck());
  942. m_chkbxClose.EnableWindow(!m_chkbxAudio.GetCheck());
  943. m_chkbxClose.SetCheck(m_chkbxAudio.GetCheck());
  944. }
  945. void CNeroFiddlesDlg::OnImport()
  946. {
  947. // TODO: Add your control notification handler code here
  948. // Imports a only possible on data discs
  949. m_chkbxAudio.EnableWindow(!m_chkbxImport.GetCheck());
  950. }
  951. // A helper to get the correct filename in a NERO_ISO_ITEM.
  952. inline LPCSTR GetFilename(const NERO_ISO_ITEM* pItem)
  953. {
  954. return (pItem->longFileName != NULL)? pItem->longFileName : pItem->fileName;
  955. }
  956. // The following function performs a merge operation between two iso item trees.
  957. // The second tree is added onto the first one and the extra items are deleted.
  958. // As we do not allow to add directories in our file list we do not make recursive
  959. // calls of this method.
  960. BOOL CNeroFiddlesDlg::MergeIsoTracks(NERO_ISO_ITEM** ppniiTarget, NERO_ISO_ITEM* pniiToAdd)
  961. {
  962. BOOL bResult = ((ppniiTarget != NULL) && (*ppniiTarget != NULL) && (pniiToAdd != NULL));
  963. // Two loops. Outer loops the first tree, the inner loops the second tree.
  964. for( ; bResult && (*ppniiTarget != NULL); ppniiTarget = &(*ppniiTarget)->nextItem)
  965. {
  966. for(NERO_ISO_ITEM** ppniiToAddLocal = &pniiToAdd; *ppniiToAddLocal != NULL; )
  967. {
  968. // Compare entry names...
  969. if(0 == stricmp(GetFilename(*ppniiTarget), GetFilename(*ppniiToAddLocal)))
  970. {
  971. // If there is a file name conflict between iso items that belong to imported sessions
  972. // always replace the old files in terms of modification times.
  973. time_t timeTarget = mktime(&(*ppniiTarget)->entryTime);
  974. if(timeTarget == (time_t)-1)
  975. {
  976. HANDLE hFile = NULL; // handle to file
  977. FILETIME ftCreationTime; // creation time
  978. FILETIME ftLastAccessTime; // last access time
  979. FILETIME ftLastWriteTime; // last write time
  980. hFile = CreateFile((*ppniiTarget)->longSourceFilePath, // open the file to get handle
  981. GENERIC_READ, // open for reading
  982. FILE_SHARE_READ, // share for reading
  983. NULL, // no security
  984. OPEN_EXISTING, // existing file only
  985. FILE_ATTRIBUTE_NORMAL, // normal file
  986. NULL); // no attr. template
  987. if(hFile == INVALID_HANDLE_VALUE)
  988. {
  989. CString csMsg;
  990. csMsg.Format("Could not open file: %s.", (*ppniiTarget)->longSourceFilePath);
  991. AppendString(csMsg); // show error
  992. }
  993. else if(GetFileTime(hFile, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
  994. timeTarget = CTime(ftLastWriteTime).GetTime();
  995. if(hFile != INVALID_HANDLE_VALUE)
  996. CloseHandle(hFile), hFile = NULL;
  997. }
  998. time_t timeToAdd = mktime(&(*ppniiToAddLocal)->entryTime);
  999. // If we have to replace one item, we will now switch places of items in the first and second tree.
  1000. // Since one of the items has to be deleted eventually, this operation will
  1001. // essentially keep the item from the second tree and delete the item from the first tree.
  1002. if(timeTarget < timeToAdd)
  1003. {
  1004. NERO_ISO_ITEM* pniiTmpItem = *ppniiToAddLocal;
  1005. *ppniiToAddLocal = *ppniiTarget;
  1006. *ppniiTarget = pniiTmpItem;
  1007. pniiTmpItem = (*ppniiToAddLocal)->nextItem;
  1008. (*ppniiToAddLocal)->nextItem = (*ppniiTarget)->nextItem;
  1009. (*ppniiTarget)->nextItem = pniiTmpItem;
  1010. }
  1011. // Remove the item from the second tree.
  1012. NERO_ISO_ITEM* pniiTmpItem = *ppniiToAddLocal;
  1013. *ppniiToAddLocal = pniiTmpItem->nextItem;
  1014. pniiTmpItem->nextItem = NULL;
  1015. DeleteIsoItemTree(pniiTmpItem);
  1016. }
  1017. else // No match, advance to the next item.
  1018. ppniiToAddLocal = &(*ppniiToAddLocal)->nextItem;
  1019. }
  1020. }
  1021. // Attach whatever is left of the new tree to the main tree.
  1022. *ppniiTarget = pniiToAdd;
  1023. // Returning true means, everything is fine, continue.
  1024. return bResult;
  1025. }
  1026. // This function deletes the iso tree recursively.
  1027. void CNeroFiddlesDlg::DeleteIsoItemTree(NERO_ISO_ITEM* pniiItem)
  1028. {
  1029. // First free our own long filename strings, then free the whole tree.
  1030. FreeOurOwnResources(pniiItem);
  1031. NeroFreeIsoItemTree(pniiItem);
  1032. }
  1033. void CNeroFiddlesDlg::FreeOurOwnResources(NERO_ISO_ITEM* pniiItem)
  1034. {
  1035. // Step through the tree until the ISO item tree pointer becomes NULL
  1036. while(pniiItem != NULL)
  1037. {
  1038. NERO_ISO_ITEM* pniiNextItem = pniiItem->nextItem;
  1039. // We have encountered another ISO item tree; recurse another level.
  1040. if(pniiItem->isDirectory)
  1041. FreeOurOwnResources (pniiItem->subDirFirstItem);
  1042. if(!pniiItem->isReference)
  1043. {
  1044. if(pniiItem->longFileName != NULL)
  1045. free((void*)pniiItem->longFileName), pniiItem->longFileName = NULL;
  1046. if(pniiItem->longSourceFilePath != NULL)
  1047. free((void*)pniiItem->longSourceFilePath), pniiItem->longSourceFilePath = NULL;
  1048. }
  1049. pniiItem = pniiNextItem;
  1050. }
  1051. }