ConvertDlg.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:31k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. // ConvertDlg.cpp : implementation file
  22. //
  23. #include "stdafx.h"
  24. #include "mplayerc.h"
  25. #include "....filtersfilters.h"
  26. #include "......includematroskamatroska.h"
  27. #include "GraphBuilder.h"
  28. #include "ConvertPropsDlg.h"
  29. #include "ConvertResDlg.h"
  30. #include "ConvertChapDlg.h"
  31. #include "ConvertDlg.h"
  32. // TODO: subtitle source filter
  33. // CConvertDlg dialog
  34. CConvertDlg::CConvertDlg(CWnd* pParent /*=NULL*/)
  35. : CResizableDialog(CConvertDlg::IDD, pParent)
  36. , m_dwRegister(0)
  37. , m_fn(_T(""))
  38. {
  39. }
  40. CConvertDlg::~CConvertDlg()
  41. {
  42. }
  43. void CConvertDlg::AddFile(CString fn)
  44. {
  45. CPath path(fn);
  46. path.StripPath();
  47. CGraphBuilder gb(m_pGB, NULL);
  48. CComPtr<IBaseFilter> pBF;
  49. if(FAILED(gb.AddSourceFilter(fn, &pBF)))
  50. return;
  51. int cnt = 0;
  52. while(S_OK == m_pCGB->RenderStream(NULL, NULL, pBF, NULL, m_pMux)) cnt++;
  53. if(!cnt) {MessageBeep(-1); DeleteFilter(pBF); return;}
  54. if(m_tree.GetCount() == 0)
  55. {
  56. if(CComQIPtr<IDSMPropertyBag> pPB = m_pMux)
  57. pPB->DelAllProperties();
  58. if(CString(_T(".dsm")).CompareNoCase(path.GetExtension()) != 0)
  59. {
  60. CPath p(fn);
  61. p.RemoveExtension();
  62. SetOutputFile(CString((LPCTSTR)p) + _T(".dsm"));
  63. }
  64. }
  65. CTreeItemFile* t = new CTreeItemFile(fn, pBF, m_tree, NULL);
  66. AddFilter(*t, pBF);
  67. m_tree.Expand(*t, TVE_EXPAND);
  68. m_tree.EnsureVisible(*t);
  69. }
  70. bool CConvertDlg::SetOutputFile(LPCTSTR fn)
  71. {
  72. if(!m_pGB || !m_pMux)
  73. return false;
  74. NukeDownstream(m_pMux, m_pGB);
  75. CComPtr<IBaseFilter> pFW;
  76. CComQIPtr<IFileSinkFilter2> pFSF = m_pMux;
  77. if(pFSF) {pFW = m_pMux;}
  78. else {pFW.CoCreateInstance(CLSID_FileWriter); pFSF = pFW;}
  79. if(!pFSF
  80. || FAILED(m_pGB->AddFilter(pFW, NULL))
  81. || FAILED(pFSF->SetFileName(CStringW(fn), NULL))
  82. || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE))
  83. || FAILED(m_pCGB->RenderStream(NULL, NULL, m_pMux, NULL, pFW)))
  84. {
  85. m_pGB->RemoveFilter(pFW);
  86. return false;
  87. }
  88. m_fn = fn;
  89. UpdateData(FALSE);
  90. return true;
  91. }
  92. void CConvertDlg::AddFilter(HTREEITEM hTIParent, IBaseFilter* pBFParent)
  93. {
  94. BeginEnumPins(pBFParent, pEP, pPin)
  95. {
  96. PIN_DIRECTION dir;
  97. CComPtr<IPin> pPinTo;
  98. CComPtr<IBaseFilter> pBF;
  99. if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
  100. || FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
  101. || !(pBF = GetFilterFromPin(pPinTo)))
  102. continue;
  103. CTreeItem* t = NULL;
  104. if(pBF == m_pMux)
  105. {
  106. t = new CTreeItemPin(pPin, m_tree, hTIParent);
  107. }
  108. else
  109. {
  110. t = new CTreeItemFilter(pBF, m_tree, hTIParent);
  111. AddFilter(*t, pBF);
  112. }
  113. }
  114. EndEnumPins
  115. if(CComQIPtr<IDSMPropertyBag> pPB = pBFParent)
  116. {
  117. ULONG props;
  118. if(FAILED(pPB->CountProperties(&props)))
  119. props = 0;
  120. for(ULONG i = 0; i < props; i++)
  121. {
  122. PROPBAG2 PropBag;
  123. memset(&PropBag, 0, sizeof(PropBag));
  124. ULONG cPropertiesReturned = 0;
  125. if(FAILED(pPB->GetPropertyInfo(i, 1, &PropBag, &cPropertiesReturned)))
  126. continue;
  127. HRESULT hr;
  128. CComVariant var;
  129. if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
  130. {
  131. CComQIPtr<IDSMPropertyBag> pPBMux = m_pMux;
  132. CComBSTR value;
  133. if(pPBMux && FAILED(pPBMux->GetProperty(PropBag.pstrName, &value)))
  134. pPBMux->SetProperty(PropBag.pstrName, var.bstrVal);
  135. }
  136. CoTaskMemFree(PropBag.pstrName);
  137. }
  138. }
  139. CTreeItem* t2 = new CTreeItemResourceFolder(m_tree, hTIParent);
  140. if(CComQIPtr<IDSMResourceBag> pRB = pBFParent)
  141. {
  142. for(DWORD i = 0, cnt = pRB->ResGetCount(); i < cnt; i++)
  143. {
  144. CComBSTR name, mime, desc;
  145. BYTE* pData = NULL;
  146. DWORD len = 0;
  147. if(FAILED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL)))
  148. continue;
  149. if(len > 0)
  150. {
  151. m_pTIs.AddTail(new CTreeItemResource(CDSMResource(name, desc, mime, pData, len), m_tree, *t2));
  152. }
  153. CoTaskMemFree(pData);
  154. }
  155. }
  156. m_tree.Expand(*t2, TVE_EXPAND);
  157. CTreeItem* t3 = new CTreeItemChapterFolder(m_tree, hTIParent);
  158. if(CComQIPtr<IDSMChapterBag> pCB = pBFParent)
  159. {
  160. for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
  161. {
  162. REFERENCE_TIME rt;
  163. CComBSTR name;
  164. if(FAILED(pCB->ChapGet(i, &rt, &name)))
  165. continue;
  166. m_pTIs.AddTail(new CTreeItemChapter(CDSMChapter(rt, name), m_tree, *t3));
  167. }
  168. }
  169. m_tree.Expand(*t3, TVE_EXPAND);
  170. m_tree.Expand(hTIParent, TVE_EXPAND);
  171. }
  172. void CConvertDlg::DeleteFilter(IBaseFilter* pBF)
  173. {
  174. BeginEnumPins(pBF, pEP, pPin)
  175. {
  176. PIN_DIRECTION dir;
  177. CComPtr<IPin> pPinTo;
  178. CComPtr<IBaseFilter> pBF;
  179. if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
  180. || FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
  181. || !(pBF = GetFilterFromPin(pPinTo)))
  182. continue;
  183. if(pBF != m_pMux) DeleteFilter(pBF);
  184. }
  185. EndEnumPins
  186. m_pGB->RemoveFilter(pBF);
  187. }
  188. void CConvertDlg::DeleteItem(HTREEITEM hTI)
  189. {
  190. if(!hTI) return;
  191. DeleteChildren(hTI);
  192. CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
  193. if(POSITION pos = m_pTIs.Find(t)) m_pTIs.RemoveAt(pos);
  194. delete t;
  195. m_tree.DeleteItem(hTI);
  196. }
  197. void CConvertDlg::DeleteChildren(HTREEITEM hTI)
  198. {
  199. if(!hTI) return;
  200. if(m_tree.ItemHasChildren(hTI))
  201. {
  202. HTREEITEM hChildItem = m_tree.GetChildItem(hTI);
  203. while(hChildItem != NULL)
  204. {
  205. HTREEITEM hNextItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
  206. DeleteItem(hChildItem);
  207. hChildItem = hNextItem;
  208. }
  209. }
  210. }
  211. HTREEITEM CConvertDlg::HitTest(CPoint& sp, CPoint& cp)
  212. {
  213. sp = CPoint((LPARAM)GetMessagePos());
  214. cp = sp;
  215. m_tree.ScreenToClient(&cp);
  216. UINT flags = 0;
  217. HTREEITEM hTI = m_tree.HitTest(cp, &flags);
  218. return hTI && (flags&TVHT_ONITEM) ? hTI : NULL;
  219. }
  220. void CConvertDlg::ShowPopup(CPoint p)
  221. {
  222. CMenu m;
  223. m.CreatePopupMenu();
  224. int i = 1;
  225. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDFILE));
  226. m.AppendMenu(MF_SEPARATOR);
  227. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_PROPERTIES));
  228. switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  229. {
  230. case 1:
  231. {
  232. CFileDialog fd(TRUE, NULL, m_fn, 
  233. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY, 
  234. _T("Media files|*.*||"), this, 0);
  235. if(fd.DoModal() == IDOK) AddFile(fd.GetPathName());
  236. }
  237. break;
  238. case 2:
  239. EditProperties(CComQIPtr<IDSMPropertyBag>(m_pMux));
  240. break;
  241. }
  242. }
  243. void CConvertDlg::ShowFilePopup(HTREEITEM hTI, CPoint p)
  244. {
  245. CTreeItemFile* t = dynamic_cast<CTreeItemFile*>((CTreeItem*)m_tree.GetItemData(hTI));
  246. ASSERT(t);
  247. CMenu m;
  248. m.CreatePopupMenu();
  249. int i = 1;
  250. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
  251. switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  252. {
  253. case 1:
  254. DeleteFilter(t->m_pBF);
  255. DeleteItem(hTI);
  256. break;
  257. }
  258. }
  259. void CConvertDlg::ShowPinPopup(HTREEITEM hTI, CPoint p)
  260. {
  261. CTreeItemPin* t = dynamic_cast<CTreeItemPin*>((CTreeItem*)m_tree.GetItemData(hTI));
  262. ASSERT(t);
  263. if(!t->m_pPin) return;
  264. CComPtr<IPin> pPinTo;
  265. t->m_pPin->ConnectedTo(&pPinTo);
  266. CMediaType mtconn;
  267. if(pPinTo) t->m_pPin->ConnectionMediaType(&mtconn);
  268. CArray<CMediaType> mts;
  269. BeginEnumMediaTypes(t->m_pPin, pEMT, pmt)
  270. mts.Add(*pmt);
  271. EndEnumMediaTypes(pmt)
  272. CMenu m;
  273. m.CreatePopupMenu();
  274. int i = 1, mtbase = 1000, mti = mtbase;
  275. m.AppendMenu(MF_STRING, i++, !pPinTo ? ResStr(IDS_CONVERT_ENABLESTREAM) : ResStr(IDS_CONVERT_DISABLESTREAM));
  276. if(mts.GetCount() > 1)
  277. {
  278. m.AppendMenu(MF_SEPARATOR);
  279. for(int i = 0; i < mts.GetCount(); i++)
  280. m.AppendMenu(MF_STRING | (mts[i] == mtconn ? MF_CHECKED : 0), mti++, CMediaTypeEx(mts[i]).ToString());
  281. }
  282. m.AppendMenu(MF_SEPARATOR);
  283. m.AppendMenu(MF_STRING | (!pPinTo ? MF_GRAYED : 0), i++, ResStr(IDS_CONVERT_PINPROPERTIES));
  284. switch(i = (int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  285. {
  286. case 1:
  287. if(pPinTo) {m_pGB->Disconnect(pPinTo); m_pGB->Disconnect(t->m_pPin);}
  288. else if(pPinTo = GetFirstDisconnectedPin(m_pMux, PINDIR_INPUT)) m_pGB->ConnectDirect(t->m_pPin, pPinTo, NULL);
  289. t->Update();
  290. break;
  291. case 2:
  292. EditProperties(CComQIPtr<IDSMPropertyBag>(pPinTo));
  293. break;
  294. default:
  295. i -= mtbase;
  296. if(i >= 0 && i < mts.GetCount())
  297. {
  298. if(pPinTo) {m_pGB->Disconnect(pPinTo); m_pGB->Disconnect(t->m_pPin);}
  299. else {pPinTo = GetFirstDisconnectedPin(m_pMux, PINDIR_INPUT);}
  300. HRESULT hr = m_pGB->ConnectDirect(t->m_pPin, pPinTo, &mts[i]);
  301. if(FAILED(hr))
  302. {
  303. AfxMessageBox(_T("Reconnection attempt failed!"));
  304. if(mtconn.majortype != GUID_NULL) 
  305. hr = m_pGB->ConnectDirect(t->m_pPin, pPinTo, &mtconn);
  306. }
  307. t->Update();
  308. }
  309. break;
  310. }
  311. }
  312. void CConvertDlg::ShowResourceFolderPopup(HTREEITEM hTI, CPoint p)
  313. {
  314. CTreeItemResourceFolder* t = dynamic_cast<CTreeItemResourceFolder*>((CTreeItem*)m_tree.GetItemData(hTI));
  315. ASSERT(t);
  316. CMenu m;
  317. m.CreatePopupMenu();
  318. int i = 1;
  319. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDRESOURCE));
  320. if(m_tree.ItemHasChildren(*t))
  321. {
  322. m.AppendMenu(MF_SEPARATOR);
  323. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDRESOURCE));
  324. }
  325. switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  326. {
  327. case 1:
  328. {
  329. CFileDialog fd(TRUE, NULL, NULL, 
  330. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY, 
  331. _T("All files|*.*||"), this, 0);
  332. if(fd.DoModal() == IDOK) 
  333. {
  334. CString fn = fd.GetPathName();
  335. if(FILE* f = _tfopen(fn, _T("rb")))
  336. {
  337. CDSMResource res;
  338. CPath path(fn);
  339. path.StripPath();
  340. res.name = (LPCTSTR)path;
  341. CRegKey key;
  342. TCHAR mime[256];
  343. ULONG len = countof(mime);
  344. if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, path.GetExtension().MakeLower(), KEY_READ)
  345. && ERROR_SUCCESS == key.QueryStringValue(_T("Content Type"), mime, &len))
  346. res.mime = mime;
  347. CTreeItemResource* t = new CTreeItemResource(res, m_tree, hTI);
  348. m_pTIs.AddTail(t);
  349. if(EditResource(t))
  350. {
  351. fseek(f, 0, 2);
  352. long size = ftell(f);
  353. fseek(f, 0, 0);
  354. t->m_res.data.SetSize(size);
  355. for(BYTE* ptr = t->m_res.data.GetData(),* end = ptr + size; 
  356. size > 0 && end - ptr >= size && fread(ptr, min(size, 1024), 1, f) > 0; 
  357. ptr += 1024, size -= 1024);
  358. fclose(f);
  359. }
  360. else
  361. {
  362. DeleteItem(*t);
  363. }
  364. }
  365. else
  366. {
  367. AfxMessageBox(_T("Cannot open file!"));
  368. }
  369. }
  370. }
  371. break;
  372. case 2:
  373. DeleteChildren(hTI);
  374. break;
  375. }
  376. }
  377. void CConvertDlg::ShowResourcePopup(HTREEITEM hTI, CPoint p)
  378. {
  379. CTreeItemResource* t = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_tree.GetItemData(hTI));
  380. ASSERT(t);
  381. CMenu m;
  382. m.CreatePopupMenu();
  383. int i = 1;
  384. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
  385. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_SAVEAS));
  386. if(AfxGetAppSettings().fEnableWebServer) m.AppendMenu(MF_STRING, 1000, ResStr(IDS_CONVERT_LAUNCHINBROWSER));
  387. m.AppendMenu(MF_SEPARATOR);
  388. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_RESOURCEPROPERTIES));
  389. switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  390. {
  391. case 1:
  392. DeleteItem(*t);
  393. break;
  394. case 2:
  395. {
  396. CFileDialog fd(FALSE, NULL, CString(t->m_res.name), 
  397. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
  398. _T("All files|*.*||"), this, 0);
  399. if(fd.DoModal() == IDOK)
  400. {
  401. if(FILE* f = _tfopen(fd.GetPathName(), _T("wb")))
  402. {
  403. fwrite(t->m_res.data.GetData(), 1, t->m_res.data.GetSize(), f);
  404. fclose(f);
  405. }
  406. }
  407. }
  408. break;
  409. case 3:
  410. EditResource(t);
  411. break;
  412. case 1000:
  413. {
  414. CString url;
  415. url.Format(_T("http://localhost:%d/convres.html?id=%x"), AfxGetAppSettings().nWebServerPort, (DWORD)&t->m_res);
  416. ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);
  417. }
  418. break;
  419. }
  420. }
  421. bool CConvertDlg::EditProperties(IDSMPropertyBag* pPB)
  422. {
  423. CConvertPropsDlg dlg(!!CComQIPtr<IPin>(pPB), this);
  424. ULONG props;
  425. if(FAILED(pPB->CountProperties(&props)))
  426. props = 0;
  427. for(ULONG i = 0; i < props; i++)
  428. {
  429. PROPBAG2 PropBag;
  430. memset(&PropBag, 0, sizeof(PropBag));
  431. ULONG cPropertiesReturned = 0;
  432. if(FAILED(pPB->GetPropertyInfo(i, 1, &PropBag, &cPropertiesReturned)))
  433. continue;
  434. HRESULT hr;
  435. CComVariant var;
  436. if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
  437. dlg.m_props[CString(PropBag.pstrName)] = CString(var);
  438. CoTaskMemFree(PropBag.pstrName);
  439. }
  440. if(IDOK != dlg.DoModal())
  441. return false;
  442. pPB->DelAllProperties();
  443. POSITION pos = dlg.m_props.GetStartPosition();
  444. while(pos)
  445. {
  446. CString key, value;
  447. dlg.m_props.GetNextAssoc(pos, key, value);
  448. pPB->SetProperty(CStringW(key), CStringW(value));
  449. }
  450. return true;
  451. }
  452. bool CConvertDlg::EditResource(CTreeItemResource* t)
  453. {
  454. CConvertResDlg dlg(this);
  455. dlg.m_name = t->m_res.name;
  456. dlg.m_mime = t->m_res.mime;
  457. dlg.m_desc = t->m_res.desc;
  458. if(IDOK != dlg.DoModal())
  459. return false;
  460. t->m_res.name = dlg.m_name;
  461. t->m_res.mime = dlg.m_mime;
  462. t->m_res.desc = dlg.m_desc;
  463. t->Update();
  464. return true;
  465. }
  466. void CConvertDlg::ShowChapterFolderPopup(HTREEITEM hTI, CPoint p)
  467. {
  468. CTreeItemChapterFolder* t = dynamic_cast<CTreeItemChapterFolder*>((CTreeItem*)m_tree.GetItemData(hTI));
  469. ASSERT(t);
  470. CMenu m;
  471. m.CreatePopupMenu();
  472. int i = 1;
  473. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDCHAPTER));
  474. if(m_tree.ItemHasChildren(*t))
  475. {
  476. m.AppendMenu(MF_SEPARATOR);
  477. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVEALL));
  478. }
  479. switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  480. {
  481. case 1:
  482. {
  483. CDSMChapter chap;
  484. CTreeItemChapter* t = new CTreeItemChapter(CDSMChapter(0, L""), m_tree, hTI);
  485. m_pTIs.AddTail(t);
  486. if(!EditChapter(t)) 
  487. DeleteItem(*t);
  488. }
  489. break;
  490. case 2:
  491. DeleteChildren(hTI);
  492. break;
  493. }
  494. }
  495. void CConvertDlg::ShowChapterPopup(HTREEITEM hTI, CPoint p)
  496. {
  497. CTreeItemChapter* t = dynamic_cast<CTreeItemChapter*>((CTreeItem*)m_tree.GetItemData(hTI));
  498. ASSERT(t);
  499. CMenu m;
  500. m.CreatePopupMenu();
  501. int i = 1;
  502. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
  503. m.AppendMenu(MF_SEPARATOR);
  504. m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_CHAPTERPROPERTIES));
  505. switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
  506. {
  507. case 1:
  508. DeleteItem(hTI);
  509. break;
  510. case 2:
  511. EditChapter(t);
  512. break;
  513. }
  514. }
  515. bool CConvertDlg::EditChapter(CTreeItemChapter* t)
  516. {
  517. CConvertChapDlg dlg(this);
  518. int h = (int)(t->m_chap.rt/10000000/60/60);
  519. int m = (int)(t->m_chap.rt/10000000/60%60);
  520. int s = (int)(t->m_chap.rt/10000000%60);
  521. int ms = (int)(t->m_chap.rt/10000%1000);
  522. dlg.m_name = t->m_chap.name;
  523. dlg.m_time.Format(_T("%02d:%02d:%02d.%03d"), h, m, s, ms);
  524. if(IDOK != dlg.DoModal())
  525. return false;
  526. TCHAR c;
  527. if(_stscanf(dlg.m_time, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms) != 7)
  528. return false;
  529. t->m_chap.name = dlg.m_name;
  530. t->m_chap.rt = ((((__int64)h*60+m)*60+s)*1000+ms)*10000;
  531. t->Update();
  532. return true;
  533. }
  534. void CConvertDlg::DoDataExchange(CDataExchange* pDX)
  535. {
  536. __super::DoDataExchange(pDX);
  537. DDX_Control(pDX, IDC_TREE1, m_tree);
  538. DDX_Text(pDX, IDC_EDIT1, m_fn);
  539. }
  540. BOOL CConvertDlg::PreTranslateMessage(MSG* pMsg)
  541. {
  542. if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
  543. return TRUE;
  544. return __super::PreTranslateMessage(pMsg);
  545. }
  546. BOOL CConvertDlg::OnInitDialog()
  547. {
  548. __super::OnInitDialog();
  549. SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);
  550. SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE);
  551. AddAnchor(IDC_TREE1, TOP_LEFT, BOTTOM_RIGHT);
  552. AddAnchor(IDC_EDIT1, BOTTOM_LEFT, BOTTOM_RIGHT);
  553. AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);
  554. AddAnchor(IDC_HLINE, BOTTOM_LEFT, BOTTOM_RIGHT);
  555. AddAnchor(IDC_BUTTON2, BOTTOM_CENTER);
  556. AddAnchor(IDC_BUTTON3, BOTTOM_CENTER);
  557. AddAnchor(IDC_BUTTON4, BOTTOM_CENTER);
  558. CSize s(400, 200);
  559. SetMinTrackSize(s);
  560. m_streamtypesbm.LoadBitmap(IDB_STREAMTYPES);
  561. m_streamtypes.Create(16, 18, ILC_MASK|ILC_COLOR32, 0, 4);
  562. m_streamtypes.Add(&m_streamtypesbm, 0xffffff);
  563. m_tree.SetImageList(&m_streamtypes, TVSIL_NORMAL);
  564. GetWindowText(m_title);
  565. m_nIDEventStatus = SetTimer(1, 1000, NULL);
  566. HRESULT hr;
  567. m_pMux = new CDSMMuxerFilter(NULL, &hr, false, false);
  568. if(FAILED(m_pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2))
  569. || FAILED(m_pGB.CoCreateInstance(CLSID_FilterGraph))
  570. || FAILED(m_pCGB->SetFiltergraph(m_pGB))
  571. || FAILED(m_pGB->AddFilter(m_pMux, L"Mux"))
  572. || !(m_pMC = m_pGB) || !(m_pME = m_pGB) || !(m_pMS = m_pMux)
  573. || FAILED(m_pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0))) 
  574. {
  575. MessageBeep(-1);
  576. SendMessage(WM_CLOSE);
  577. return TRUE;
  578. }
  579. AddToRot(m_pGB, &m_dwRegister);
  580. return TRUE;  // return TRUE unless you set the focus to a control
  581. // EXCEPTION: OCX Property Pages should return FALSE
  582. }
  583. void CConvertDlg::OnOK()
  584. {
  585. }
  586. BEGIN_MESSAGE_MAP(CConvertDlg, CResizableDialog)
  587. ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
  588. ON_WM_DROPFILES()
  589. ON_WM_CLOSE()
  590. ON_NOTIFY(NM_CLICK, IDC_TREE1, OnNMClickTree1)
  591. ON_NOTIFY(NM_RCLICK, IDC_TREE1, OnNMRclickTree1)
  592. ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnNMDblclkTree1)
  593. ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
  594. ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
  595. ON_WM_TIMER()
  596. ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
  597. ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2)
  598. ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton3)
  599. ON_UPDATE_COMMAND_UI(IDC_BUTTON3, OnUpdateButton3)
  600. ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton4)
  601. ON_UPDATE_COMMAND_UI(IDC_BUTTON4, OnUpdateButton4)
  602. END_MESSAGE_MAP()
  603. // CConvertDlg message handlers
  604. LRESULT CConvertDlg::OnGraphNotify(WPARAM wParam, LPARAM lParam)
  605. {
  606.     HRESULT hr = S_OK;
  607. LONG evCode, evParam1, evParam2;
  608.     while(m_pME && SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
  609.     {
  610. hr = m_pME->FreeEventParams(evCode, evParam1, evParam2);
  611. bool fStop = false;
  612.         if(EC_COMPLETE == evCode)
  613.         {
  614. fStop = true;
  615. }
  616. else if(EC_ERRORABORT == evCode)
  617. {
  618. fStop = true;
  619. CString errmsg;
  620. LPVOID lpMsgBuf;
  621. if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
  622. NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL))
  623. {
  624. errmsg = (LPCTSTR)lpMsgBuf;
  625. LocalFree(lpMsgBuf);
  626. }
  627. CString str;
  628. str.Format(_T("Could not complete conversion, the output file is most likely unusable.nnError code: 0x%08x"), evParam1);
  629. if(!errmsg.IsEmpty()) str += _T(" (") + errmsg + _T(")");
  630. AfxMessageBox(str, MB_OK);
  631. }
  632. if(fStop && m_pMC)
  633. {
  634. m_pMC->Stop();
  635. m_tree.EnableWindow(TRUE);
  636. }
  637. }
  638. return hr;
  639. }
  640. void CConvertDlg::OnDropFiles(HDROP hDropInfo)
  641. {
  642. for(int i = 0, j = DragQueryFile(hDropInfo, 0xffffffff, 0, 0); i < j; i++)
  643. {
  644. CString fn;
  645. fn.ReleaseBufferSetLength(DragQueryFile(hDropInfo, i, fn.GetBuffer(MAX_PATH), MAX_PATH));
  646. AddFile(fn);
  647. }
  648. __super::OnDropFiles(hDropInfo);
  649. }
  650. void CConvertDlg::OnClose()
  651. {
  652. HTREEITEM hTI = m_tree.GetRootItem();
  653. while(hTI)
  654. {
  655. HTREEITEM hTINext = m_tree.GetNextSiblingItem(hTI);
  656. DeleteItem(hTI);
  657. hTI = hTINext;
  658. }
  659. if(m_dwRegister) RemoveFromRot(m_dwRegister);
  660. __super::OnClose();
  661. }
  662. void CConvertDlg::OnNMClickTree1(NMHDR* pNMHDR, LRESULT* pResult)
  663. {
  664. CPoint sp, cp;
  665. HTREEITEM hTI = HitTest(sp, cp);
  666. if(!hTI) return;
  667. m_tree.SelectItem(hTI);
  668. *pResult = 0;
  669. }
  670. void CConvertDlg::OnNMRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)
  671. {
  672. CPoint sp, cp;
  673. HTREEITEM hTI = HitTest(sp, cp);
  674. if(hTI)
  675. {
  676. m_tree.SelectItem(hTI);
  677. CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
  678. if(dynamic_cast<CTreeItemPin*>(t))
  679. ShowPinPopup(hTI, sp);
  680. else if(dynamic_cast<CTreeItemFile*>(t))
  681. ShowFilePopup(hTI, sp);
  682. else if(dynamic_cast<CTreeItemResourceFolder*>(t))
  683. ShowResourceFolderPopup(hTI, sp);
  684. else if(dynamic_cast<CTreeItemResource*>(t))
  685. ShowResourcePopup(hTI, sp);
  686. else if(dynamic_cast<CTreeItemChapterFolder*>(t))
  687. ShowChapterFolderPopup(hTI, sp);
  688. else if(dynamic_cast<CTreeItemChapter*>(t))
  689. ShowChapterPopup(hTI, sp);
  690. }
  691. else
  692. {
  693. ShowPopup(sp);
  694. }
  695. *pResult = 0;
  696. }
  697. void CConvertDlg::OnNMDblclkTree1(NMHDR *pNMHDR, LRESULT *pResult)
  698. {
  699. CPoint sp, cp;
  700. HTREEITEM hTI = HitTest(sp, cp);
  701. if(hTI)
  702. {
  703. CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
  704. if(CTreeItemPin* t2 = dynamic_cast<CTreeItemPin*>(t))
  705. {
  706. CComPtr<IPin> pPinTo;
  707. t2->m_pPin->ConnectedTo(&pPinTo);
  708. if(CComQIPtr<IDSMPropertyBag> pPB = pPinTo)
  709. EditProperties(pPB);
  710. }
  711. else if(CTreeItemResource* t2 = dynamic_cast<CTreeItemResource*>(t))
  712. {
  713. EditResource(t2);
  714. }
  715. else if(CTreeItemChapter* t2 = dynamic_cast<CTreeItemChapter*>(t))
  716. {
  717. EditChapter(t2);
  718. }
  719. }
  720. *pResult = 0;
  721. }
  722. void CConvertDlg::OnBnClickedButton1()
  723. {
  724. UpdateData();
  725. CFileDialog fd(FALSE, _T(".dsm"), m_fn, 
  726. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 
  727. _T("DirectShow Media file|*.dsm|All files|*.*|"), this, 0);
  728. if(fd.DoModal() != IDOK) return;
  729. if(!SetOutputFile(fd.GetPathName()))
  730. {
  731. AfxMessageBox(_T("Could not set output file"));
  732. }
  733. }
  734. void CConvertDlg::OnUpdateButton1(CCmdUI* pCmdUI)
  735. {
  736. OAFilterState fs;
  737. pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs == State_Stopped);
  738. }
  739. void CConvertDlg::OnTimer(UINT nIDEvent)
  740. {
  741. if(nIDEvent == m_nIDEventStatus && m_pMS && m_pMC)
  742. {
  743. OAFilterState fs;
  744. if(SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Stopped)
  745. {
  746. GUID tf;
  747. m_pMS->GetTimeFormat(&tf);
  748. REFERENCE_TIME rtCur, rtDur;
  749. HRESULT hr = m_pMS->GetDuration(&rtDur);
  750. m_pMS->GetCurrentPosition(&rtCur);
  751. CString str;
  752. if(hr == S_OK) str.Format(_T("%.2f%%"), 1.0 * (rtCur * 100) / rtDur);
  753. else if(tf == TIME_FORMAT_BYTE) str.Format(_T("%.2fKB"), 1.0 * rtCur / 1024);
  754. else if(tf == TIME_FORMAT_MEDIA_TIME) str.Format(_T("%02d:%02d:%02d"), int(rtCur/3600000000)%60, int(rtCur/60000000)%60, int(rtCur/1000000)%60);
  755. else str = _T("Please Wait");
  756. SetWindowText(_T("Converting - ") + str);
  757. }
  758. else
  759. {
  760. SetWindowText(m_title);
  761. }
  762. }
  763. __super::OnTimer(nIDEvent);
  764. }
  765. void CConvertDlg::OnBnClickedButton2()
  766. {
  767. OAFilterState fs;
  768. if(FAILED(m_pMC->GetState(0, &fs)))
  769. return;
  770. if(fs == State_Stopped)
  771. {
  772. if(m_pMS)
  773. {
  774. LONGLONG pos = 0;
  775. m_pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
  776. }
  777. if(CComQIPtr<IDSMPropertyBag> pPB = m_pMux)
  778. {
  779. pPB->SetProperty(L"APPL", L"Media Player Classic");
  780. }
  781. if(CComQIPtr<IDSMResourceBag> pRB = m_pMux)
  782. {
  783. pRB->ResRemoveAll(0);
  784. POSITION pos = m_pTIs.GetHeadPosition();
  785. while(pos)
  786. {
  787. if(CTreeItemResource* t2 = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_pTIs.GetNext(pos)))
  788. pRB->ResAppend(
  789. t2->m_res.name, t2->m_res.desc, t2->m_res.mime, 
  790. t2->m_res.data.GetData(), t2->m_res.data.GetSize(), 
  791. NULL);
  792. }
  793. }
  794. if(CComQIPtr<IDSMChapterBag> pCB = m_pMux)
  795. {
  796. pCB->ChapRemoveAll();
  797. POSITION pos = m_pTIs.GetHeadPosition();
  798. while(pos)
  799. {
  800. if(CTreeItemChapter* t2 = dynamic_cast<CTreeItemChapter*>((CTreeItem*)m_pTIs.GetNext(pos)))
  801. pCB->ChapAppend(t2->m_chap.rt, t2->m_chap.name);
  802. }
  803. }
  804. }
  805. if(m_pMC) 
  806. {
  807. if(SUCCEEDED(m_pMC->Run()))
  808. m_tree.EnableWindow(FALSE);
  809. }
  810. }
  811. void CConvertDlg::OnUpdateButton2(CCmdUI* pCmdUI)
  812. {
  813. int nIn, nOut, nInC, nOutC;
  814. CountPins(m_pMux, nIn, nOut, nInC, nOutC);
  815. OAFilterState fs;
  816. pCmdUI->Enable(nInC > 0 && nOutC > 0 && GetDlgItem(IDC_EDIT1)->GetWindowTextLength() > 0
  817.         && m_pMS && m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Running);
  818. }
  819. void CConvertDlg::OnBnClickedButton3()
  820. {
  821. if(m_pMC) m_pMC->Pause();
  822. }
  823. void CConvertDlg::OnUpdateButton3(CCmdUI* pCmdUI)
  824. {
  825. OAFilterState fs;
  826. pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs == State_Running);
  827. }
  828. void CConvertDlg::OnBnClickedButton4()
  829. {
  830. if(m_pMC) m_pMC->Stop();
  831. m_tree.EnableWindow(TRUE);
  832. }
  833. void CConvertDlg::OnUpdateButton4(CCmdUI* pCmdUI)
  834. {
  835. OAFilterState fs;
  836. pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Stopped);
  837. }
  838. //
  839. // CFilterTreeCtrl
  840. //
  841. CFilterTreeCtrl::CFilterTreeCtrl()
  842. {
  843. }
  844. void CFilterTreeCtrl::PreSubclassWindow()
  845. {
  846. EnableToolTips(TRUE);
  847. __super::PreSubclassWindow();
  848. }
  849. INT_PTR CFilterTreeCtrl::OnToolHitTest(CPoint p, TOOLINFO* pTI) const
  850. {
  851. UINT nFlags;
  852. HTREEITEM hTI = HitTest(p, &nFlags);
  853. if(nFlags & TVHT_ONITEM)
  854. {
  855. CRect r;
  856. GetItemRect(hTI, r, TRUE);
  857. pTI->hwnd = m_hWnd;
  858. pTI->uId = (UINT)hTI;
  859. pTI->lpszText = LPSTR_TEXTCALLBACK;
  860. pTI->rect = r;
  861. return pTI->uId;
  862. }
  863. return -1;
  864. }
  865. BEGIN_MESSAGE_MAP(CFilterTreeCtrl, CTreeCtrl)
  866. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
  867. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
  868. END_MESSAGE_MAP()
  869. BOOL CFilterTreeCtrl::OnToolTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
  870. {
  871. TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  872. TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  873. UINT nID = pNMHDR->idFrom;
  874. if(nID == (UINT)m_hWnd
  875. && (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND)
  876. || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND)))
  877. return FALSE;
  878. ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT)1000);
  879. HTREEITEM hTI = (HTREEITEM)nID;
  880. CString str;
  881. static CStringA m_strTipTextA;
  882. static CStringW m_strTipTextW;
  883. CConvertDlg::CTreeItem* t = (CConvertDlg::CTreeItem*)GetItemData(hTI);
  884. if(!t || !t->ToolTip(str)) return FALSE;
  885. m_strTipTextA = str;
  886. m_strTipTextW = str;
  887. if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lpszText = (LPSTR)(LPCSTR)m_strTipTextA;
  888. else pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_strTipTextW;
  889. *pResult = 0;
  890. return TRUE;    // message was handled
  891. }
  892. //
  893. // CConvertDlg::CTreeItem*
  894. //
  895. CConvertDlg::CTreeItem::CTreeItem(CTreeCtrl& tree, HTREEITEM hTIParent) 
  896. : m_tree(tree)
  897. {
  898. m_hTI = m_tree.InsertItem(_T(""), hTIParent);
  899. m_tree.SetItemData(m_hTI, (DWORD_PTR)this);
  900. Update();
  901. }
  902. CConvertDlg::CTreeItem::~CTreeItem()
  903. {
  904. }
  905. void CConvertDlg::CTreeItem::SetLabel(LPCTSTR label)
  906. {
  907. m_tree.SetItemText(m_hTI, label);
  908. }
  909. void CConvertDlg::CTreeItem::SetImage(int nImage, int nSelectedImage)
  910. {
  911. m_tree.SetItemImage(m_hTI, nImage, nSelectedImage);
  912. }
  913. // 
  914. CConvertDlg::CTreeItemFilter::CTreeItemFilter(IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent) 
  915. : CTreeItem(tree, hTIParent)
  916. , m_pBF(pBF)
  917. {
  918. Update();
  919. }
  920. void CConvertDlg::CTreeItemFilter::Update()
  921. {
  922. SetLabel(CString(GetFilterName(m_pBF)));
  923. }
  924. //
  925. CConvertDlg::CTreeItemFile::CTreeItemFile(CString fn, IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent)
  926. : CTreeItemFilter(pBF, tree, hTIParent)
  927. , m_fn(fn)
  928. {
  929. Update();
  930. }
  931. void CConvertDlg::CTreeItemFile::Update()
  932. {
  933. CPath path = m_fn;
  934. path.StripPath();
  935. SetLabel(path);
  936. }
  937. bool CConvertDlg::CTreeItemFile::ToolTip(CString& str)
  938. {
  939. str = m_fn;
  940. return true;
  941. }
  942. //
  943. CConvertDlg::CTreeItemPin::CTreeItemPin(IPin* pPin, CTreeCtrl& tree, HTREEITEM hTIParent)
  944. : CTreeItem(tree, hTIParent)
  945. , m_pPin(pPin)
  946. {
  947. Update();
  948. }
  949. void CConvertDlg::CTreeItemPin::Update()
  950. {
  951. if(!m_pPin) {ASSERT(0); return;}
  952. CString label = GetPinName(m_pPin);
  953. if(!IsConnected()) label = _T("[D] ") + label;
  954. SetLabel(label);
  955. CMediaType mt;
  956. if(S_OK == m_pPin->ConnectionMediaType(&mt))
  957. {
  958. if(mt.majortype == MEDIATYPE_Video) SetImage(1, 1);
  959. else if(mt.majortype == MEDIATYPE_Audio) SetImage(2, 2);
  960. else if(mt.majortype == MEDIATYPE_Text || mt.majortype == MEDIATYPE_Subtitle) SetImage(3, 3);
  961. }
  962. }
  963. bool CConvertDlg::CTreeItemPin::ToolTip(CString& str)
  964. {
  965. CMediaTypeEx mt;
  966. if(FAILED(m_pPin->ConnectionMediaType(&mt))) return false;
  967. str = mt.ToString(m_pPin);
  968. return true;
  969. }
  970. bool CConvertDlg::CTreeItemPin::IsConnected()
  971. {
  972. CComPtr<IPin> pPinTo;
  973. return m_pPin && SUCCEEDED(m_pPin->ConnectedTo(&pPinTo)) && pPinTo;
  974. }
  975. //
  976. CConvertDlg::CTreeItemResourceFolder::CTreeItemResourceFolder(CTreeCtrl& tree, HTREEITEM hTIParent)
  977. : CTreeItem(tree, hTIParent)
  978. {
  979. Update();
  980. }
  981. void CConvertDlg::CTreeItemResourceFolder::Update()
  982. {
  983. SetLabel(_T("Resources"));
  984. }
  985. bool CConvertDlg::CTreeItemResourceFolder::ToolTip(CString& str)
  986. {
  987. if(!m_tree.ItemHasChildren(m_hTI))
  988. return false;
  989. int files = 0;
  990. float size = 0;
  991. HTREEITEM hChildItem = m_tree.GetChildItem(m_hTI);
  992. while(hChildItem != NULL)
  993. {
  994. HTREEITEM hNextItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
  995. if(CTreeItemResource* t = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_tree.GetItemData(hChildItem)))
  996. size += t->m_res.data.GetSize(), files++;
  997. hChildItem = hNextItem;
  998. }
  999. size /= 1024;
  1000. if(size < 1024) str.Format(_T("%d file(s), %.2f KB"), files, size);
  1001. else str.Format(_T("%d file(s), %.2f MB"), files, size/1024);
  1002. return true;
  1003. }
  1004. //
  1005. CConvertDlg::CTreeItemResource::CTreeItemResource(const CDSMResource& res, CTreeCtrl& tree, HTREEITEM hTIParent)
  1006. : CTreeItem(tree, hTIParent)
  1007. {
  1008. m_res = res;
  1009. Update();
  1010. }
  1011. CConvertDlg::CTreeItemResource::~CTreeItemResource()
  1012. {
  1013. }
  1014. void CConvertDlg::CTreeItemResource::Update()
  1015. {
  1016. SetLabel(CString(m_res.name));
  1017. CStringW mime = m_res.mime;
  1018. mime.Trim();
  1019. mime.MakeLower();
  1020. if(mime == L"application/x-truetype-font") SetImage(4, 4);
  1021. else if(mime.Find(L"text/") == 0) SetImage(5, 5);
  1022. else SetImage(6, 6);
  1023. }
  1024. bool CConvertDlg::CTreeItemResource::ToolTip(CString& str)
  1025. {
  1026. if(!m_res.mime.IsEmpty()) str = CString(m_res.mime) + _T("rnrn");
  1027. if(!m_res.desc.IsEmpty()) str += CString(m_res.desc);
  1028. str.Trim();
  1029. return true;
  1030. }
  1031. //
  1032. CConvertDlg::CTreeItemChapterFolder::CTreeItemChapterFolder(CTreeCtrl& tree, HTREEITEM hTIParent)
  1033. : CTreeItem(tree, hTIParent)
  1034. {
  1035. Update();
  1036. }
  1037. void CConvertDlg::CTreeItemChapterFolder::Update()
  1038. {
  1039. SetLabel(_T("Chapters"));
  1040. }
  1041. //
  1042. CConvertDlg::CTreeItemChapter::CTreeItemChapter(const CDSMChapter& chap, CTreeCtrl& tree, HTREEITEM hTIParent)
  1043. : CTreeItem(tree, hTIParent)
  1044. {
  1045. m_chap = chap;
  1046. Update();
  1047. }
  1048. void CConvertDlg::CTreeItemChapter::Update()
  1049. {
  1050. REFERENCE_TIME rt = m_chap.rt;
  1051. rt /= 10000;
  1052. int ms = (int)(rt%1000);
  1053. rt /= 1000;
  1054. int s = (int)(rt%60);
  1055. rt /= 60;
  1056. int m = (int)(rt%60);
  1057. rt /= 60;
  1058. int h = (int)(rt);
  1059. CString label;
  1060. label.Format(_T("%02d:%02d:%02d.%03d - %s"), h, m, s, ms, CString(m_chap.name));
  1061. SetLabel(label);
  1062. SetImage(7, 7);
  1063. }