GraphBuildingDlg.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:14k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // GraphBuildingDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "GraphBuilding.h"
  5. #include "GraphBuildingDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CGraphBuildingDlg dialog
  13. CGraphBuildingDlg::CGraphBuildingDlg(CWnd* pParent /*=NULL*/)
  14. : CDialog(CGraphBuildingDlg::IDD, pParent)
  15. {
  16. //{{AFX_DATA_INIT(CGraphBuildingDlg)
  17. // NOTE: the ClassWizard will add member initialization here
  18. //}}AFX_DATA_INIT
  19. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  20. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  21. }
  22. void CGraphBuildingDlg::DoDataExchange(CDataExchange* pDX)
  23. {
  24. CDialog::DoDataExchange(pDX);
  25. //{{AFX_DATA_MAP(CGraphBuildingDlg)
  26. // NOTE: the ClassWizard will add DDX and DDV calls here
  27. //}}AFX_DATA_MAP
  28. }
  29. BEGIN_MESSAGE_MAP(CGraphBuildingDlg, CDialog)
  30. //{{AFX_MSG_MAP(CGraphBuildingDlg)
  31. ON_WM_PAINT()
  32. ON_WM_QUERYDRAGICON()
  33. ON_BN_CLICKED(IDC_BUTTON_TEST, OnButtonTest)
  34. //}}AFX_MSG_MAP
  35. END_MESSAGE_MAP()
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CGraphBuildingDlg message handlers
  38. BOOL CGraphBuildingDlg::OnInitDialog()
  39. {
  40. CDialog::OnInitDialog();
  41. // Set the icon for this dialog.  The framework does this automatically
  42. //  when the application's main window is not a dialog
  43. SetIcon(m_hIcon, TRUE); // Set big icon
  44. SetIcon(m_hIcon, FALSE); // Set small icon
  45. // TODO: Add extra initialization here
  46. return TRUE;  // return TRUE  unless you set the focus to a control
  47. }
  48. // If you add a minimize button to your dialog, you will need the code below
  49. //  to draw the icon.  For MFC applications using the document/view model,
  50. //  this is automatically done for you by the framework.
  51. void CGraphBuildingDlg::OnPaint() 
  52. {
  53. if (IsIconic())
  54. {
  55. CPaintDC dc(this); // device context for painting
  56. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  57. // Center icon in client rectangle
  58. int cxIcon = GetSystemMetrics(SM_CXICON);
  59. int cyIcon = GetSystemMetrics(SM_CYICON);
  60. CRect rect;
  61. GetClientRect(&rect);
  62. int x = (rect.Width() - cxIcon + 1) / 2;
  63. int y = (rect.Height() - cyIcon + 1) / 2;
  64. // Draw the icon
  65. dc.DrawIcon(x, y, m_hIcon);
  66. }
  67. else
  68. {
  69. CDialog::OnPaint();
  70. }
  71. }
  72. // The system calls this to obtain the cursor to display while the user drags
  73. //  the minimized window.
  74. HCURSOR CGraphBuildingDlg::OnQueryDragIcon()
  75. {
  76. return (HCURSOR) m_hIcon;
  77. }
  78. //////////////////////////////////////////////////////////////////////////////
  79. ///////////////////// Graph building methods /////////////////////////////////
  80. HRESULT AddFilterByCLSID(
  81.     IGraphBuilder *pGraph,  // Pointer to the Filter Graph Manager.
  82.     const GUID& clsid,      // CLSID of the filter to create.
  83.     LPCWSTR wszName,        // A name for the filter.
  84.     IBaseFilter **ppF)      // Receives a pointer to the filter.
  85. {
  86.     if (!pGraph || ! ppF) return E_POINTER;
  87.     *ppF = 0;
  88.     IBaseFilter *pF = 0;
  89.     HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
  90.         IID_IBaseFilter, reinterpret_cast<void**>(&pF));
  91.     if (SUCCEEDED(hr))
  92.     {
  93.         hr = pGraph->AddFilter(pF, wszName);
  94.         if (SUCCEEDED(hr))
  95.             *ppF = pF;
  96.         else
  97.             pF->Release();
  98.     }
  99.     return hr;
  100. }
  101. HRESULT GetUnconnectedPin(
  102.     IBaseFilter *pFilter,   // Pointer to the filter.
  103.     PIN_DIRECTION PinDir,   // Direction of the pin to find.
  104.     IPin **ppPin)           // Receives a pointer to the pin.
  105. {
  106.     *ppPin = 0;
  107.     IEnumPins *pEnum = 0;
  108.     IPin *pPin = 0;
  109.     HRESULT hr = pFilter->EnumPins(&pEnum);
  110.     if (FAILED(hr))
  111.     {
  112.         return hr;
  113.     }
  114.     while (pEnum->Next(1, &pPin, NULL) == S_OK)
  115.     {
  116.         PIN_DIRECTION ThisPinDir;
  117.         pPin->QueryDirection(&ThisPinDir);
  118.         if (ThisPinDir == PinDir)
  119.         {
  120.             IPin *pTmp = 0;
  121.             hr = pPin->ConnectedTo(&pTmp);
  122.             if (SUCCEEDED(hr))  // Already connected, not the pin we want.
  123.             {
  124.                 pTmp->Release();
  125.             }
  126.             else  // Unconnected, this is the pin we want.
  127.             {
  128.                 pEnum->Release();
  129.                 *ppPin = pPin;
  130.                 return S_OK;
  131.             }
  132.         }
  133.         pPin->Release();
  134.     }
  135.     pEnum->Release();
  136.     // Did not find a matching pin.
  137.     return E_FAIL;
  138. }
  139. HRESULT ConnectFilters(
  140.     IGraphBuilder *pGraph, // Filter Graph Manager.
  141.     IPin *pOut,            // Output pin on the upstream filter.
  142.     IBaseFilter *pDest)    // Downstream filter.
  143. {
  144.     if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
  145.     {
  146.         return E_POINTER;
  147.     }
  148. #ifdef debug
  149.         PIN_DIRECTION PinDir;
  150.         pOut->QueryDirection(&PinDir);
  151.         _ASSERTE(PinDir == PINDIR_OUTPUT);
  152. #endif
  153.     // Find an input pin on the downstream filter.
  154.     IPin *pIn = 0;
  155.     HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
  156.     if (FAILED(hr))
  157.     {
  158.         return hr;
  159.     }
  160.     // Try to connect them.
  161.     hr = pGraph->Connect(pOut, pIn);
  162.     pIn->Release();
  163.     return hr;
  164. }
  165. HRESULT ConnectFilters(
  166.     IGraphBuilder *pGraph, 
  167.     IBaseFilter *pSrc, 
  168.     IBaseFilter *pDest)
  169. {
  170.     if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
  171.     {
  172.         return E_POINTER;
  173.     }
  174.     // Find an output pin on the first filter.
  175.     IPin *pOut = 0;
  176.     HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
  177.     if (FAILED(hr)) 
  178.     {
  179.         return hr;
  180.     }
  181.     hr = ConnectFilters(pGraph, pOut, pDest);
  182.     pOut->Release();
  183.     return hr;
  184. }
  185. HRESULT FindFilterInterface(
  186.     IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.
  187.     REFGUID iid,           // IID of the interface to retrieve.
  188.     void **ppUnk)          // Receives the interface pointer.
  189. {
  190.     if (!pGraph || !ppUnk) return E_POINTER;
  191.     HRESULT hr = E_FAIL;
  192.     IEnumFilters *pEnum = NULL;
  193.     IBaseFilter *pF = NULL;
  194.     if (FAILED(pGraph->EnumFilters(&pEnum)))
  195.     {
  196.         return E_FAIL;
  197.     }
  198.     // Query every filter for the interface.
  199.     while (S_OK == pEnum->Next(1, &pF, 0))
  200.     {
  201.         hr = pF->QueryInterface(iid, ppUnk);
  202.         pF->Release();
  203.         if (SUCCEEDED(hr))
  204.         {
  205.             break;
  206.         }
  207.     }
  208.     pEnum->Release();
  209.     return hr;
  210. }
  211. HRESULT FindPinInterface(
  212.     IBaseFilter *pFilter,  // Pointer to the filter to search.
  213.     REFGUID iid,           // IID of the interface.
  214.     void **ppUnk)          // Receives the interface pointer.
  215. {
  216.     if (!pFilter || !ppUnk) return E_POINTER;
  217.     HRESULT hr = E_FAIL;
  218.     IEnumPins *pEnum = 0;
  219.     if (FAILED(pFilter->EnumPins(&pEnum)))
  220.     {
  221.         return E_FAIL;
  222.     }
  223.     // Query every pin for the interface.
  224.     IPin *pPin = 0;
  225.     while (S_OK == pEnum->Next(1, &pPin, 0))
  226.     {
  227.         hr = pPin->QueryInterface(iid, ppUnk);
  228.         pPin->Release();
  229.         if (SUCCEEDED(hr))
  230.         {
  231.             break;
  232.         }
  233.     }
  234.     pEnum->Release();
  235.     return hr;
  236. }
  237. HRESULT FindInterfaceAnywhere(
  238.     IGraphBuilder *pGraph, 
  239.     REFGUID iid, 
  240.     void **ppUnk)
  241. {
  242.     if (!pGraph || !ppUnk) return E_POINTER;
  243.     HRESULT hr = E_FAIL;
  244.     IEnumFilters *pEnum = 0;
  245.     if (FAILED(pGraph->EnumFilters(&pEnum)))
  246.     {
  247.         return E_FAIL;
  248.     }
  249.     // Loop through every filter in the graph.
  250.     IBaseFilter *pF = 0;
  251.     while (S_OK == pEnum->Next(1, &pF, 0))
  252.     {
  253.         hr = pF->QueryInterface(iid, ppUnk);
  254.         if (FAILED(hr))
  255.         {
  256.             // The filter does not expose the interface, but maybe
  257.             // one of its pins does.
  258.             hr = FindPinInterface(pF, iid, ppUnk);
  259.         }
  260.         pF->Release();
  261.         if (SUCCEEDED(hr))
  262.         {
  263.             break;
  264.         }
  265.     }
  266.     pEnum->Release();
  267.     return hr;
  268. }
  269. // Get the first upstream or downstream filter
  270. HRESULT GetNextFilter(
  271.     IBaseFilter *pFilter, // Pointer to the starting filter
  272.     PIN_DIRECTION Dir,    // Direction to search (upstream or downstream)
  273.     IBaseFilter **ppNext) // Receives a pointer to the next filter.
  274. {
  275.     if (!pFilter || !ppNext) return E_POINTER;
  276.     IEnumPins *pEnum = 0;
  277.     IPin *pPin = 0;
  278.     HRESULT hr = pFilter->EnumPins(&pEnum);
  279.     if (FAILED(hr)) return hr;
  280.     while (S_OK == pEnum->Next(1, &pPin, 0))
  281.     {
  282.         // See if this pin matches the specified direction.
  283.         PIN_DIRECTION ThisPinDir;
  284.         hr = pPin->QueryDirection(&ThisPinDir);
  285.         if (FAILED(hr))
  286.         {
  287.             // Something strange happened.
  288.             hr = E_UNEXPECTED;
  289.             pPin->Release();
  290.             break;
  291.         }
  292.         if (ThisPinDir == Dir)
  293.         {
  294.             // Check if the pin is connected to another pin.
  295.             IPin *pPinNext = 0;
  296.             hr = pPin->ConnectedTo(&pPinNext);
  297.             if (SUCCEEDED(hr))
  298.             {
  299.                 // Get the filter that owns that pin.
  300.                 PIN_INFO PinInfo;
  301.                 hr = pPinNext->QueryPinInfo(&PinInfo);
  302.                 pPinNext->Release();
  303.                 pPin->Release();
  304.                 pEnum->Release();
  305.                 if (FAILED(hr) || (PinInfo.pFilter == NULL))
  306.                 {
  307.                     // Something strange happened.
  308.                     return E_UNEXPECTED;
  309.                 }
  310.                 // This is the filter we're looking for.
  311.                 *ppNext = PinInfo.pFilter; // Client must release.
  312.                 return S_OK;
  313.             }
  314.         }
  315.         pPin->Release();
  316.     }
  317.     pEnum->Release();
  318.     // Did not find a matching filter.
  319.     return E_FAIL;
  320. }
  321. // Define a typedef for a list of filters.
  322. typedef CGenericList<IBaseFilter> CFilterList;
  323. // Forward declaration. Adds a filter to the list unless it's a duplicate.
  324. void AddFilterUnique(CFilterList &FilterList, IBaseFilter *pNew);
  325. // Find all the immediate upstream or downstream peers of a filter.
  326. HRESULT GetPeerFilters(
  327.     IBaseFilter *pFilter, // Pointer to the starting filter
  328.     PIN_DIRECTION Dir,    // Direction to search (upstream or downstream)
  329.     CFilterList &FilterList)  // Collect the results in this list.
  330. {
  331.     if (!pFilter) return E_POINTER;
  332.     IEnumPins *pEnum = 0;
  333.     IPin *pPin = 0;
  334.     HRESULT hr = pFilter->EnumPins(&pEnum);
  335.     if (FAILED(hr)) return hr;
  336.     while (S_OK == pEnum->Next(1, &pPin, 0))
  337.     {
  338.         // See if this pin matches the specified direction.
  339.         PIN_DIRECTION ThisPinDir;
  340.         hr = pPin->QueryDirection(&ThisPinDir);
  341.         if (FAILED(hr))
  342.         {
  343.             // Something strange happened.
  344.             hr = E_UNEXPECTED;
  345.             pPin->Release();
  346.             break;
  347.         }
  348.         if (ThisPinDir == Dir)
  349.         {
  350.             // Check if the pin is connected to another pin.
  351.             IPin *pPinNext = 0;
  352.             hr = pPin->ConnectedTo(&pPinNext);
  353.             if (SUCCEEDED(hr))
  354.             {
  355.                 // Get the filter that owns that pin.
  356.                 PIN_INFO PinInfo;
  357.                 hr = pPinNext->QueryPinInfo(&PinInfo);
  358.                 pPinNext->Release();
  359.                 if (FAILED(hr) || (PinInfo.pFilter == NULL))
  360.                 {
  361.                     // Something strange happened.
  362.                     pPin->Release();
  363.                     pEnum->Release();
  364.                     return E_UNEXPECTED;
  365.                 }
  366.                 // Insert the filter into the list.
  367.                 AddFilterUnique(FilterList, PinInfo.pFilter);
  368.                 PinInfo.pFilter->Release();
  369.             }
  370.         }
  371.         pPin->Release();
  372.     }
  373.     pEnum->Release();
  374.     return S_OK;
  375. }
  376. void AddFilterUnique(CFilterList &FilterList, IBaseFilter *pNew)
  377. {
  378.     if (pNew == NULL) return;
  379.     POSITION pos = FilterList.GetHeadPosition();
  380.     while (pos)
  381.     {
  382.         IBaseFilter *pF = FilterList.GetNext(pos);
  383.         if (IsEqualObject(pF, pNew))
  384.         {
  385.             return;
  386.         }
  387.     }
  388.     pNew->AddRef();  // The caller must release everything in the list.
  389.     FilterList.AddTail(pNew);
  390. }
  391. // Tear down everything downstream of a given filter
  392. void NukeDownstream(IGraphBuilder * inGraph, IBaseFilter * inFilter) 
  393. {
  394. if (inGraph && inFilter)
  395. {
  396. IEnumPins * pinEnum = 0;
  397. if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
  398. {
  399. pinEnum->Reset();
  400. IPin * pin = 0;
  401. ULONG cFetched = 0;
  402. bool pass = true;
  403. while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &cFetched)))
  404. {
  405. if (pin && cFetched)
  406. {
  407. IPin * connectedPin = 0;
  408. pin->ConnectedTo(&connectedPin);
  409. if(connectedPin) 
  410. {
  411. PIN_INFO pininfo;
  412. if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo)))
  413. {
  414. if(pininfo.dir == PINDIR_INPUT) 
  415. {
  416. NukeDownstream(inGraph, pininfo.pFilter);
  417. inGraph->Disconnect(connectedPin);
  418. inGraph->Disconnect(pin);
  419. inGraph->RemoveFilter(pininfo.pFilter);
  420. }
  421. pininfo.pFilter->Release();
  422. }
  423. connectedPin->Release();
  424. }
  425. pin->Release();
  426. }
  427. else
  428. {
  429. pass = false;
  430. }
  431. }
  432. pinEnum->Release();
  433. }
  434. }
  435. }
  436. // Tear down everything upstream of a given filter
  437. void NukeUpstream(IGraphBuilder * inGraph, IBaseFilter * inFilter) 
  438. {
  439. if (inGraph && inFilter)
  440. {
  441. IEnumPins * pinEnum = 0;
  442. if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
  443. {
  444. pinEnum->Reset();
  445. IPin * pin = 0;
  446. ULONG cFetched = 0;
  447. bool pass = true;
  448. while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &cFetched)))
  449. {
  450. if (pin && cFetched)
  451. {
  452. IPin * connectedPin = 0;
  453. pin->ConnectedTo(&connectedPin);
  454. if(connectedPin) 
  455. {
  456. PIN_INFO pininfo;
  457. if (SUCCEEDED(connectedPin->QueryPinInfo(&pininfo)))
  458. {
  459. if(pininfo.dir == PINDIR_OUTPUT) 
  460. {
  461. NukeUpstream(inGraph, pininfo.pFilter);
  462. inGraph->Disconnect(connectedPin);
  463. inGraph->Disconnect(pin);
  464. inGraph->RemoveFilter(pininfo.pFilter);
  465. }
  466. pininfo.pFilter->Release();
  467. }
  468. connectedPin->Release();
  469. }
  470. pin->Release();
  471. }
  472. else
  473. {
  474. pass = false;
  475. }
  476. }
  477. pinEnum->Release();
  478. }
  479. }
  480. }
  481. /////////////////////////////////////////////////////////////////////////////
  482. void CGraphBuildingDlg::OnButtonTest() 
  483. {
  484. // TODO: Add your control notification handler code here
  485. }