home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow_WinXP / VMR / VMRMix / VMRMixDlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  14.3 KB  |  512 lines

  1. //------------------------------------------------------------------------------
  2. // File: VMRMixDlg.cpp
  3. //
  4. // Desc: DirectShow sample code
  5. //       Implementation of the settings dialog
  6. //
  7. // Copyright (c) 2000-2001 Microsoft Corporation.  All rights reserved.
  8. //------------------------------------------------------------------------------
  9.  
  10. #include "stdafx.h"
  11. #include "VMRMix.h"
  12. #include "VMRMixDlg.h"
  13. #include "DlgWait.h"
  14. #include "Demonstration.h"
  15.  
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. class CDemonstration;
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CAboutDlg dialog used for App About
  25.  
  26. class CAboutDlg : public CDialog
  27. {
  28. public:
  29.     CAboutDlg();
  30.  
  31. // Dialog Data
  32.     //{{AFX_DATA(CAboutDlg)
  33.     enum { IDD = IDD_ABOUTBOX };
  34.     //}}AFX_DATA
  35.  
  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.  
  42. // Implementation
  43. protected:
  44.     //{{AFX_MSG(CAboutDlg)
  45.     //}}AFX_MSG
  46.     DECLARE_MESSAGE_MAP()
  47. };
  48.  
  49. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  50. {
  51.     //{{AFX_DATA_INIT(CAboutDlg)
  52.     //}}AFX_DATA_INIT
  53. }
  54.  
  55. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  56. {
  57.     CDialog::DoDataExchange(pDX);
  58.     //{{AFX_DATA_MAP(CAboutDlg)
  59.     //}}AFX_DATA_MAP
  60. }
  61.  
  62. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  63.     //{{AFX_MSG_MAP(CAboutDlg)
  64.         // No message handlers
  65.     //}}AFX_MSG_MAP
  66. END_MESSAGE_MAP()
  67.  
  68. /////////////////////////////////////////////////////////////////////////////
  69. // CVMRMixDlg dialog
  70.  
  71. CVMRMixDlg::CVMRMixDlg(CWnd* pParent /*=NULL*/)
  72.     : CDialog(CVMRMixDlg::IDD, pParent)
  73. {
  74.     //{{AFX_DATA_INIT(CVMRMixDlg)
  75.         // NOTE: the ClassWizard will add member initialization here
  76.     //}}AFX_DATA_INIT
  77.     // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  78.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  79.  
  80.     m_bFullScreen = true;
  81.     m_bUseBitmap = true;
  82.     m_nMaxSources = 16;
  83.     m_nStreams = 5;         // Initial number of streams
  84.     m_eState = eStop;
  85.     strcpy(m_szFolder,"");
  86. }
  87.  
  88. void CVMRMixDlg::DoDataExchange(CDataExchange* pDX)
  89. {
  90.     CDialog::DoDataExchange(pDX);
  91.     //{{AFX_DATA_MAP(CVMRMixDlg)
  92.     DDX_Control(pDX, IDC_CHECK_FULLSCREEN, m_chkFullScreen);
  93.     DDX_Control(pDX, IDC_CHECK_APPLYBITMAP, m_chkBitmap);
  94.     DDX_Control(pDX, IDC_SLIDER, m_Slider);
  95.     DDX_Control(pDX, IDOK, m_btnOK);
  96.     DDX_Control(pDX, IDC_BUTTON_PLAY, m_btnPlay);
  97.     //}}AFX_DATA_MAP
  98. }
  99.  
  100. BEGIN_MESSAGE_MAP(CVMRMixDlg, CDialog)
  101.     //{{AFX_MSG_MAP(CVMRMixDlg)
  102.     ON_WM_SYSCOMMAND()
  103.     ON_WM_PAINT()
  104.     ON_WM_QUERYDRAGICON()
  105.     ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
  106.     ON_COMMAND(ID_FILE_SELECTMEDIAFOLDER, SelectFolder)
  107.     ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER, OnReleasedcaptureSlider)
  108.     ON_BN_CLICKED(IDC_CHECK_APPLYBITMAP, OnCheckApplybitmap)
  109.     ON_BN_CLICKED(IDC_CHECK_FULLSCREEN, OnCheckFullscreen)
  110.     //}}AFX_MSG_MAP
  111. END_MESSAGE_MAP()
  112.  
  113. /////////////////////////////////////////////////////////////////////////////
  114. // CVMRMixDlg message handlers
  115.  
  116. BOOL CVMRMixDlg::OnInitDialog()
  117. {
  118.     CDialog::OnInitDialog();
  119.  
  120.     // Add "About..." menu item to system menu.
  121.  
  122.     // IDM_ABOUTBOX must be in the system command range.
  123.     ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  124.     ASSERT(IDM_ABOUTBOX < 0xF000);
  125.  
  126.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  127.     if (pSysMenu != NULL)
  128.     {
  129.         CString strAboutMenu;
  130.         strAboutMenu.LoadString(IDS_ABOUTBOX);
  131.         if (!strAboutMenu.IsEmpty())
  132.         {
  133.             pSysMenu->AppendMenu(MF_SEPARATOR);
  134.             pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  135.         }
  136.     }
  137.  
  138.     // Set the icon for this dialog.  The framework does this automatically
  139.     //  when the application's main window is not a dialog
  140.     SetIcon(m_hIcon, TRUE);         // Set big icon
  141.     SetIcon(m_hIcon, FALSE);        // Set small icon
  142.  
  143.  
  144.     SetNumberOfStreams(m_nStreams);
  145.  
  146.     // upon initialization, ask user to specify media folder
  147.     // if failed, app cannot continue and quits
  148.     while( !strlen(m_szFolder) )
  149.     {
  150.         SelectFolder();
  151.         if( !strlen(m_szFolder) )
  152.         {
  153.             // If no media directory was specified, just exit
  154.             PostQuitMessage(0);
  155.             return FALSE;
  156.         }
  157.         m_MediaList.Initialize( m_szFolder );
  158.         if( 0 == m_MediaList.Size() )
  159.         {
  160.             AfxMessageBox("Selected folder does not contain any media file");
  161.             strcpy( m_szFolder, "");
  162.         }
  163.     }
  164.  
  165.     // Read settings for the selected media file
  166.     BOOL bRes = GetMediaSettings();
  167.  
  168.     if( bRes )
  169.     {
  170.         m_nMaxSources = (m_MediaList.Size() > 16) ? 16 : m_MediaList.Size();
  171.         m_Slider.SetRange(1, m_nMaxSources);
  172.  
  173.         if( m_nStreams > m_nMaxSources)
  174.         {
  175.             SetNumberOfStreams( m_nMaxSources );
  176.         }
  177.     }
  178.  
  179.     m_chkFullScreen.SetCheck( m_bFullScreen);
  180.     m_chkBitmap.SetCheck( m_bUseBitmap);
  181.  
  182.     RECT rSlider;
  183.     m_Slider.GetWindowRect( &rSlider );
  184.     LPARAM lparam = MAKELPARAM( (rSlider.left + rSlider.right)/2, (rSlider.top + rSlider.bottom)/2);
  185.     m_Slider.SendMessage(WM_LBUTTONUP, NULL, lparam);
  186.  
  187.     return bRes;  // return TRUE  unless you set the focus to a control
  188. }
  189.  
  190. //-------------------------------------------------------------
  191. // Windows message processing for CVMRMixDlg
  192. //-------------------------------------------------------------
  193.  
  194. void CVMRMixDlg::OnSysCommand(UINT nID, LPARAM lParam)
  195. {
  196.     if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  197.     {
  198.         CAboutDlg dlgAbout;
  199.         dlgAbout.DoModal();
  200.     }
  201.     else
  202.     {
  203.         CDialog::OnSysCommand(nID, lParam);
  204.     }
  205. }
  206.  
  207. // If you add a minimize button to your dialog, you will need the code below
  208. //  to draw the icon.  For MFC applications using the document/view model,
  209. //  this is automatically done for you by the framework.
  210.  
  211. void CVMRMixDlg::OnPaint()
  212. {
  213.     if (IsIconic())
  214.     {
  215.         CPaintDC dc(this); // device context for painting
  216.  
  217.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  218.  
  219.         // Center icon in client rectangle
  220.         int cxIcon = GetSystemMetrics(SM_CXICON);
  221.         int cyIcon = GetSystemMetrics(SM_CYICON);
  222.         CRect rect;
  223.         GetClientRect(&rect);
  224.         int x = (rect.Width() - cxIcon + 1) / 2;
  225.         int y = (rect.Height() - cyIcon + 1) / 2;
  226.  
  227.         // Draw the icon
  228.         dc.DrawIcon(x, y, m_hIcon);
  229.     }
  230.     else
  231.     {
  232.         CDialog::OnPaint();
  233.     }
  234. }
  235.  
  236. // The system calls this to obtain the cursor to display while the user drags
  237. //  the minimized window.
  238. HCURSOR CVMRMixDlg::OnQueryDragIcon()
  239. {
  240.     return (HCURSOR) m_hIcon;
  241. }
  242.  
  243. void CVMRMixDlg::OnButtonPlay()
  244. {
  245.     ShowWindow(SW_HIDE);
  246.     RunDemonstration();
  247.     ShowWindow(SW_SHOW);
  248. }
  249.  
  250. void CVMRMixDlg::OnCheckApplybitmap()
  251. {
  252.     m_bUseBitmap = ( m_chkBitmap.GetCheck() ) ? true : false;
  253. }
  254.  
  255. void CVMRMixDlg::OnCheckFullscreen()
  256. {
  257.     m_bFullScreen = ( m_chkFullScreen.GetCheck() ) ? true : false;
  258. }
  259.  
  260. void CVMRMixDlg::OnReleasedcaptureSlider(NMHDR* pNMHDR, LRESULT* pResult)
  261. {
  262.     int nPos = m_Slider.GetPos();
  263.  
  264.     SetNumberOfStreams( nPos);
  265.  
  266.     *pResult = 0;
  267. }
  268.  
  269.  
  270. //-------------------------------------------------------------
  271. // CVMRMixDlg::SetNumberOfStreams
  272. // Desc: Sets number of source streams for presentation (m_nStreams)
  273. //       and positions slider
  274. // Return: true if successful and false otherwise
  275. //-------------------------------------------------------------
  276. bool CVMRMixDlg::SetNumberOfStreams( int n)
  277. {
  278.     if( n<1 || n>m_nMaxSources )
  279.         return false;
  280.  
  281.     char szMsg[MAX_PATH];
  282.     m_nStreams = n;
  283.     sprintf( szMsg, "%d", m_nStreams);
  284.     GetDlgItem(IDC_STATIC_NSRC)->SetWindowText(szMsg);
  285.     m_Slider.SetPos( n);
  286.  
  287.     return true;
  288. }
  289.  
  290.  
  291. void CVMRMixDlg::SelectFolder()
  292. {
  293.     OPENFILENAME ofn;
  294.     TCHAR  szBuffer[MAX_PATH];
  295.     bool bFolderIsBad = true;
  296.  
  297.     lstrcpy(szBuffer, TEXT(""));
  298.  
  299.     static char szFilter[]  = "Video Files (.MOV, .AVI, .MPG, .VOB, .QT)\0*.AVI;*.MOV;*.MPG;*.VOB;*.QT\0" \
  300.                               "All Files (*.*)\0*.*\0\0";
  301.  
  302.     ofn.lStructSize         = sizeof(OPENFILENAME);
  303.     ofn.hwndOwner           = NULL;
  304.     ofn.hInstance           = NULL;
  305.     ofn.lpstrFilter         = szFilter;
  306.     ofn.nFilterIndex        = 1;
  307.     ofn.lpstrCustomFilter   = NULL;
  308.     ofn.nMaxCustFilter      = 0;
  309.     ofn.lpstrFile           = szBuffer;
  310.     ofn.nMaxFile            = _MAX_PATH;
  311.     ofn.lpstrFileTitle      = NULL;
  312.     ofn.nMaxFileTitle       = 0;
  313.     ofn.lpstrInitialDir     = NULL;
  314.     ofn.lpstrTitle          = "Please open any video file to select the folder...";
  315.     ofn.Flags               = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
  316.     ofn.nFileOffset         = 0;
  317.     ofn.nFileExtension      = 0;
  318.     ofn.lpstrDefExt         = NULL;//"";
  319.     ofn.lCustData           = 0L;
  320.     ofn.lpfnHook            = NULL;
  321.     ofn.lpTemplateName  = NULL;
  322.  
  323.     while( bFolderIsBad )
  324.     {
  325.         if (GetOpenFileName (&ofn))  // user specified a file
  326.         {
  327.             char szTmp[MAX_PATH];
  328.             char *psz = NULL;
  329.             lstrcpy(szTmp, ofn.lpstrFile);
  330.  
  331.             // write a profile string to test
  332.             strrev(szTmp);
  333.             psz = strstr(szTmp,"\\");
  334.             if( !psz )
  335.             {
  336.                 if(MB_OK != AfxMessageBox("You must select a file folder with at least one media file. Continue?"))
  337.                 {
  338.                     bFolderIsBad = false;
  339.                 }
  340.                 else
  341.                 {
  342.                     continue;
  343.                 }
  344.  
  345.             }
  346.             strcpy( m_szFolder, psz);
  347.             strrev( m_szFolder );
  348.             return;
  349.         }// if
  350.         else
  351.         {
  352.             break;
  353.         }
  354.     }// while( bFolderIsBad )
  355.  
  356.     if( bFolderIsBad )
  357.     {
  358.         strcpy( m_szFolder, "\0");
  359.     }
  360.     return;
  361. }
  362.  
  363. void CVMRMixDlg::PostNcDestroy()
  364. {
  365.     CDialog::PostNcDestroy();
  366. }
  367.  
  368. //---------------------------------------------------------------
  369. // CVMRMixDlg::GetMediaSettings
  370. // Desc: scans media settings list, verifies media files,
  371. //       and reads duration info
  372. // return: true if success and false otherwise
  373. //---------------------------------------------------------------
  374. bool CVMRMixDlg::GetMediaSettings()
  375. {
  376.     HRESULT hr;
  377.     int n;
  378.     char szMsg[MAX_PATH];
  379.     char szInfo[MAX_PATH];
  380.     bool bRes;
  381.  
  382.     CMediaList * pML = NULL;
  383.     CMediaList MLClone; // cloned and verified copy of the media list
  384.     CMediaList mlDirty;
  385.  
  386.     if( 2 > m_MediaList.Size())
  387.     {
  388.         AfxMessageBox("You must select a folder with at least two valid media files.\r\n\r\nPlease try again.", MB_OK);
  389.         exit(-1);
  390.     }
  391.  
  392.     CDlgWait dlgWait(m_MediaList.Size());
  393.  
  394.     m_MediaList.Clone(m_MediaList.Size(), &mlDirty, 0);
  395.     m_MediaList.Clean();
  396.  
  397.     pML = &mlDirty;
  398.     ASSERT(pML);
  399.  
  400.     dlgWait.Create(IDD_DIALOG_PROGRESS);
  401.     dlgWait.ShowWindow( SW_SHOW);
  402.  
  403.     for(n=0; n<pML->Size(); n++)
  404.     {
  405.         MLClone.Clean();
  406.         bRes = pML->Clone(1, &MLClone, n);
  407.         if( false == bRes )
  408.         {
  409.             sprintf( szMsg, "CVMRModule::GetMediaSettings(): failed to clone element %ld, setting source for 5 sec",n);
  410.             OutputDebugString( szMsg);
  411.             pML->GetItem(n)->m_llDuration = (5L * 10000000L);
  412.             continue;
  413.         }
  414.  
  415.         IMediaSeeking * pMediaSeeking = NULL;
  416.         LONGLONG llDuration = 0L;
  417.  
  418.         CVMRCore core(this, VMRMode_Renderless, NULL, &MLClone);
  419.  
  420.         hr = core.Play(true);
  421.         if( FAILED(hr) )
  422.         {
  423.             sprintf( szMsg, "*** failed to render source %s, method returned %s",
  424.                 pML->GetItem(n)->m_szPath, hresultNameLookup(hr));
  425.             OutputDebugString( szMsg);
  426.             continue;
  427.         }
  428.  
  429.         hr = core.GetIGraphBuilder()->QueryInterface(__uuidof(IMediaSeeking), reinterpret_cast<void**>(&pMediaSeeking));
  430.         if( FAILED(hr))
  431.         {
  432.             OutputDebugString("Cannot find IMediaSeeking interface\n");
  433.             dlgWait.EndDialog(IDOK);
  434.             continue;
  435.         }
  436.  
  437.         // get source parameters
  438.         core.GetMediaControl()->Stop();
  439.         hr = pMediaSeeking->GetDuration( &llDuration);
  440.         if( FAILED(hr) || llDuration < 100L)
  441.         {
  442.             OutputDebugString("Failed to obtain sample duration, setting to 5 sec\n");
  443.             llDuration = 5L * 10000000L;
  444.         }
  445.  
  446.         pML->GetItem(n)->m_llDuration = llDuration;
  447.  
  448.         sprintf( szInfo, "Source %d: name:%s, duration: %ld\n",
  449.                  n, pML->GetItem(n)->m_szPath, llDuration);
  450.         OutputDebugString(szInfo);
  451.  
  452.         SAFERELEASE(pMediaSeeking);
  453.  
  454.         // this media file is valid, we can add it to the media list
  455.         SourceInfo * psi = NULL;
  456.         psi = new SourceInfo;
  457.         pML->GetItem(n)->CopyTo( psi);
  458.         m_MediaList.Add(psi);
  459.         dlgWait.SetPos(n);
  460.     }
  461.  
  462.     dlgWait.EndDialog(IDOK);
  463.     if( 1 > m_MediaList.Size() )
  464.     {
  465.         AfxMessageBox("Some media sources are not supported with this application\r\n\r\nPlease try again with other sources.", MB_OK);
  466.         exit(-1);
  467.     }
  468.     m_MediaList.AdjustDuration();
  469.     return true;
  470. }
  471.  
  472. //---------------------------------------------------------------
  473. // CVMRMixDlg::RunDemonstration
  474. // Desc: runs demonstration module
  475. // return: HRESULT code
  476. //---------------------------------------------------------------
  477. HRESULT CVMRMixDlg::RunDemonstration()
  478. {
  479.     HRESULT hr = S_OK;
  480.  
  481.     m_MediaList.Shuffle();
  482.  
  483.     CDemonstration demo(this, &m_MediaList, m_nStreams, &hr);
  484.     if( FAILED(hr))
  485.     {
  486.         OutputDebugString("Failed to initialize class CDemonstration\n");
  487.         return FNS_FAIL;
  488.     }
  489.     clock_t tStart = clock();
  490.     hr = demo.Perform();
  491.  
  492.     char szMsg[MAX_PATH];
  493.     sprintf( szMsg, "TIME:: Actual: %ld ms, Expected: %ld ms\n",
  494.             (clock() - tStart) * 1000 / CLOCKS_PER_SEC, m_MediaList.GetAvgDuration() / 10000);
  495.     OutputDebugString( szMsg);
  496.  
  497.     if( FAILED(hr))
  498.     {
  499.         OutputDebugString("Failed to Perform() demonstration\n");
  500.     }
  501.  
  502.     if( FAILED(hr))
  503.     {
  504.         return FNS_FAIL;
  505.     }
  506.     else
  507.     {
  508.         return FNS_PASS;
  509.     }
  510. }
  511.  
  512.