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

多媒体编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "AviReportWnd.h"
  3. #define IDC_DONOTSHOWAGAINCHECK 1000
  4. #define TITLE _T("AVI Chunk Viewer")
  5. #define GRAPHFOOTER 10
  6. CAviReportWnd::CAviReportWnd()
  7. {
  8. m_font.CreateFont(12, 0, 0, 0, 400, 0, 0, 0, 1, 0, 0, 0, 0, _T("MS Shell Dlg"));
  9. }
  10. bool CAviReportWnd::DoModal(CAviFile* pAF, bool fHideChecked, bool fShowWarningText)
  11. {
  12. m_nChunks = 0;
  13. m_rtDur = 0;
  14. for(int i = 0; i < (int)pAF->m_avih.dwStreams; i++)
  15. {
  16. int cnt = pAF->m_strms[i]->cs2.GetCount();
  17. if(cnt <= 0) continue;
  18. CAviFile::strm_t::chunk2& c2 = pAF->m_strms[i]->cs2[cnt-1];
  19. m_nChunks = max(m_nChunks, c2.n);
  20. m_rtDur = max(m_rtDur, (REFERENCE_TIME)c2.t<<13);
  21. }
  22. CRect r, r2;
  23. GetDesktopWindow()->GetWindowRect(r);
  24. r.DeflateRect(r.Width()/4, r.Height()/4);
  25. LPCTSTR wndclass = AfxRegisterWndClass(
  26. CS_VREDRAW|CS_HREDRAW|CS_DBLCLKS, 
  27. AfxGetApp()->LoadStandardCursor(IDC_ARROW), 
  28. (HBRUSH)(COLOR_BTNFACE + 1), 0);
  29. CreateEx(0, wndclass, TITLE, WS_POPUPWINDOW|WS_CAPTION|WS_CLIPCHILDREN, r, NULL, 0);
  30. CRect cr;
  31. GetClientRect(cr);
  32. cr.DeflateRect(10, 10);
  33. SetFont(&m_font, FALSE);
  34. CDC* pDC = GetDC();
  35. CFont* pOldFont = pDC->SelectObject(&m_font);
  36. //
  37. CString str(
  38. _T("This AVI file was not prepared for sequential reading, the alternative ")
  39. _T("'Avi Splitter' will now let the default one handle it. ")
  40. _T("The complete reinterleaving of this file is strongly recommended before ")
  41. _T("burning it onto a slow media like cd-rom."));
  42. r = cr;
  43. pDC->DrawText(str, r, DT_WORDBREAK|DT_CALCRECT);
  44. r.right = cr.right;
  45. m_message.Create(str, WS_CHILD|WS_VISIBLE, r, this);
  46. m_message.SetFont(&m_font, FALSE);
  47. //
  48. r.SetRect(cr.left, r.bottom + 10, cr.right, cr.bottom);
  49. str = _T("Do not show this dialog again (hold Shift to re-enable it)");
  50. pDC->DrawText(str, r, DT_WORDBREAK|DT_CALCRECT);
  51. r.right = cr.right;
  52. m_checkbox.Create(str, WS_CHILD|WS_VISIBLE|BS_CHECKBOX|BS_AUTOCHECKBOX, r, this, IDC_DONOTSHOWAGAINCHECK);
  53. m_checkbox.SetFont(&m_font, FALSE);
  54. CheckDlgButton(IDC_DONOTSHOWAGAINCHECK, fHideChecked?BST_CHECKED:BST_UNCHECKED);
  55. //
  56. if(!fShowWarningText)
  57. {
  58. m_message.ShowWindow(SW_HIDE);
  59. m_checkbox.ShowWindow(SW_HIDE);
  60. r = cr;
  61. }
  62. else
  63. {
  64. r.SetRect(cr.left, r.bottom + 10, cr.right, cr.bottom);
  65. }
  66. m_graph.Create(pAF, r, this);
  67. //
  68. pDC->SelectObject(pOldFont);
  69. ReleaseDC(pDC);
  70. SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  71. SetForegroundWindow();
  72. ShowWindow(SW_SHOWNORMAL);
  73. return !!RunModalLoop();
  74. }
  75. IMPLEMENT_DYNCREATE(CAviReportWnd, CWnd)
  76. BEGIN_MESSAGE_MAP(CAviReportWnd, CWnd)
  77. ON_WM_CLOSE()
  78. ON_WM_MOUSEMOVE()
  79. END_MESSAGE_MAP()
  80. void CAviReportWnd::OnClose()
  81. {
  82. EndModalLoop(IsDlgButtonChecked(IDC_DONOTSHOWAGAINCHECK));
  83. __super::OnClose();
  84. }
  85. void CAviReportWnd::OnMouseMove(UINT nFlags, CPoint p)
  86. {
  87. MapWindowPoints(&m_graph, &p, 1);
  88. CRect r, r2;
  89. m_graph.GetClientRect(r);
  90. r2 = r;
  91. r.bottom -= GRAPHFOOTER;
  92. r2.top = r.bottom;
  93. if(r.PtInRect(p))
  94. {
  95. SetCapture();
  96. int x = p.x - r.left;
  97. int y = r.bottom - p.y;
  98. REFERENCE_TIME rt = m_rtDur * x / r.Width();
  99. int chunk = (int)(1.0 * m_nChunks * y / r.Height());
  100. rt /= 10000;
  101. int ms = (int)(rt%1000);
  102. rt /= 1000;
  103. int s = (int)(rt%60);
  104. rt /= 60;
  105. int m = (int)(rt%60);
  106. rt /= 60;
  107. int h = (int)(rt);
  108. CString str;
  109. str.Format(_T("%s (%d - %d:%02d:%02d.%03d)"), TITLE, chunk, h, m, s, ms);
  110. SetWindowText(str);
  111. }
  112. else if(r2.PtInRect(p))
  113. {
  114. SetCapture();
  115. int dist = m_graph.GetChunkDist(p.x - r2.left);
  116. CString str;
  117. str.Format(_T("%s (chunk distance: %d"), TITLE, dist);
  118. if(dist >= 1000) str += _T(" - over the limit!");
  119. str += ")";
  120. SetWindowText(str);
  121. }
  122. else if(GetCapture() == this)
  123. {
  124. SetWindowText(TITLE);
  125. ReleaseCapture();
  126. }
  127. __super::OnMouseMove(nFlags, p);
  128. }
  129. //////////////
  130. CAviPlotterWnd::CAviPlotterWnd()
  131. {
  132. }
  133. bool CAviPlotterWnd::Create(CAviFile* pAF, CRect r, CWnd* pParentWnd)
  134. {
  135. if(!CreateEx(WS_EX_CLIENTEDGE, _T("STATIC"), _T(""), WS_CHILD|WS_VISIBLE, r, pParentWnd, 0))
  136. return(false);
  137. GetClientRect(r);
  138. int w = r.Width();
  139. int h = r.Height() - GRAPHFOOTER;
  140. CDC* pDC = GetDC();
  141. m_dc.CreateCompatibleDC(pDC);
  142. m_bm.CreateCompatibleBitmap(pDC, r.Width(), r.Height());
  143. ReleaseDC(pDC);
  144. CBitmap* pOldBitmap = m_dc.SelectObject(&m_bm);
  145. m_dc.FillSolidRect(r, 0);
  146. {
  147. CPen pen(PS_DOT, 1, 0x008000);
  148. CPen* pOldPen = m_dc.SelectObject(&pen);
  149. for(int y = 0, dy = max(h/10,1); y < h; y += dy) {if(y == 0) continue; m_dc.MoveTo(0, y); m_dc.LineTo(w, y);}
  150. for(int x = 0, dx = max(w/10,1); x < w; x += dx) {if(x == 0) continue; m_dc.MoveTo(x, 0); m_dc.LineTo(x, w);}
  151. m_dc.SelectObject(pOldPen);
  152. }
  153. {
  154. CPen pen(PS_SOLID, 1, 0x00ff00);
  155. CPen* pOldPen = m_dc.SelectObject(&pen);
  156. m_dc.MoveTo(15, 30);
  157. m_dc.LineTo(15, 2);
  158. m_dc.LineTo(19, 10);
  159. m_dc.LineTo(11, 10);
  160. m_dc.LineTo(15, 2);
  161. m_dc.MoveTo(w-30-10, h-15); 
  162. m_dc.LineTo(w-2-10, h-15);
  163. m_dc.LineTo(w-10-10, h-19);
  164. m_dc.LineTo(w-10-10, h-11);
  165. m_dc.LineTo(w-2-10, h-15);
  166. m_dc.SelectObject(pOldPen);
  167. m_dc.SetTextColor(0x008000);
  168. m_dc.TextOut(20, 10, _T("Chunk"));
  169. CSize size = m_dc.GetTextExtent(_T("Time"));
  170. m_dc.TextOut(w - size.cx - 10, h - size.cy - 20, _T("Time"));
  171. }
  172. COLORREF clr[] = {0x0000ff,0xff0000,0x40ffff,0xff40ff,0xffff40,0xffffff};
  173. for(int i = 0, y = 40, dy = m_dc.GetTextExtent(_T("Stream N")).cy + 1; i < (int)pAF->m_avih.dwStreams; i++, y += dy)
  174. {
  175. m_dc.SetTextColor(clr[i%pAF->m_avih.dwStreams]);
  176. m_dc.SetBkMode(TRANSPARENT);
  177. CString str;
  178. str.Format(_T("Stream %d"), i);
  179. m_dc.TextOut(10, y, str);
  180. }
  181. DWORD nmax = 0, tmax = 0;
  182. for(int i = 0; i < (int)pAF->m_avih.dwStreams; i++)
  183. {
  184. int cnt = pAF->m_strms[i]->cs2.GetCount();
  185. if(cnt <= 0) continue;
  186. CAviFile::strm_t::chunk2& c2 = pAF->m_strms[i]->cs2[cnt-1];
  187. nmax = max(nmax, c2.n);
  188. tmax = max(tmax, c2.t);
  189. }
  190. if(nmax > 0 && tmax > 0)
  191. {
  192. CArray<CPen> pen;
  193. pen.SetSize(pAF->m_avih.dwStreams);
  194. for(int i = 0; i < pen.GetSize(); i++)
  195. pen[i].CreatePen(PS_SOLID, 2, clr[i]);
  196. CArray<CPoint> pp;
  197. pp.SetSize(pAF->m_avih.dwStreams);
  198. for(int i = 0; i < pen.GetSize(); i++)
  199. pp[i].SetPoint(-1, -1);
  200. m_chunkdist.SetSize(w);
  201. memset(m_chunkdist.GetData(), 0, sizeof(int)*w);
  202. DWORD* curchunks = new DWORD[pAF->m_avih.dwStreams];
  203. memset(curchunks, 0, sizeof(DWORD)*pAF->m_avih.dwStreams);
  204. CAviFile::strm_t::chunk2 cs2last = {-1, 0};
  205. while(1)
  206. {
  207. CAviFile::strm_t::chunk2 cs2min = {LONG_MAX, LONG_MAX};
  208. int n = -1;
  209. for(int i = 0; i < (int)pAF->m_avih.dwStreams; i++)
  210. {
  211. int curchunk = curchunks[i];
  212. if(curchunk >= pAF->m_strms[i]->cs2.GetSize()) continue;
  213. CAviFile::strm_t::chunk2& cs2 = pAF->m_strms[i]->cs2[curchunk];
  214. if(cs2.t < cs2min.t) {cs2min = cs2; n = i;}
  215. }
  216. if(n == -1) break;
  217. CPoint p;
  218. p.x = (int)(1.0 * w * cs2min.t / tmax);
  219. p.y = (int)(h - 1.0 * h * cs2min.n / nmax);
  220. if(pp[n] != p)
  221. {
  222. CPen* pOldPen = m_dc.SelectObject(&pen[n]);
  223. if(pp[n] == CPoint(-1, -1)) m_dc.MoveTo(p);
  224. else {m_dc.MoveTo(pp[n]); m_dc.LineTo(p);}
  225. m_dc.SelectObject(pOldPen);
  226. pp[n] = p;
  227. }
  228. int dist = abs(cs2min.n - cs2last.n);
  229. if(cs2last.t >= 0 /*&& dist >= 1000*/)
  230. {
  231. if(p.x >= 0 && p.x < w)
  232. {
  233. m_chunkdist[p.x] = max(m_chunkdist[p.x], dist);
  234. }
  235. }
  236. curchunks[n]++;
  237. cs2last = cs2min;
  238. }
  239. CPen red(PS_SOLID, 1, 0x0000ff);
  240. CPen green(PS_SOLID, 1, 0x00ff00);
  241. for(int x = 0; x < w; x++)
  242. {
  243. CPen* pOldPen = m_dc.SelectObject(m_chunkdist[x] >= 1000 ? &red : &green);
  244. m_dc.MoveTo(x, h);
  245. m_dc.LineTo(x, h + GRAPHFOOTER);
  246. m_dc.SelectObject(pOldPen);
  247. }
  248. delete [] curchunks;
  249. }
  250. m_dc.SelectObject(pOldBitmap);
  251. return(true);
  252. }
  253. IMPLEMENT_DYNCREATE(CAviPlotterWnd, CWnd)
  254. BEGIN_MESSAGE_MAP(CAviPlotterWnd, CWnd)
  255. ON_WM_PAINT()
  256. END_MESSAGE_MAP()
  257. void CAviPlotterWnd::OnPaint()
  258. {
  259. CPaintDC dc(this); // device context for painting
  260. CRect r;
  261. GetClientRect(r);
  262. CBitmap* pOld = m_dc.SelectObject(&m_bm);
  263. dc.BitBlt(0, 0, r.Width(), r.Height(), &m_dc, 0, 0, SRCCOPY);
  264. m_dc.SelectObject(pOld);
  265. }