ConvertDlg.cpp
上传用户:tangyu_668
上传日期:2014-02-27
资源大小:678k
文件大小:32k
源码类别:

多媒体编程

开发平台:

Visual C++

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