cprop.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:10k
源码类别:

P2P编程

开发平台:

Visual C++

  1. //------------------------------------------------------------------------------
  2. // File: CProp.cpp
  3. //
  4. // Desc: DirectShow base classes - implements CBasePropertyPage class.
  5. //
  6. // Copyright (c) Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8. #include <streams.h>
  9. // Constructor for the base property page class. As described in the header
  10. // file we must be initialised with dialog and title resource identifiers.
  11. // The class supports IPropertyPage and overrides AddRef and Release calls
  12. // to keep track of the reference counts. When the last count is released
  13. // we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces
  14. // previously obtained by the property page when it had SetObjects called
  15. CBasePropertyPage::CBasePropertyPage(TCHAR *pName,      // Debug only name
  16.                                      LPUNKNOWN pUnk,    // COM Delegator
  17.                                      int DialogId,      // Resource ID
  18.                                      int TitleId) :     // To get tital
  19.     CUnknown(pName,pUnk),
  20.     m_DialogId(DialogId),
  21.     m_TitleId(TitleId),
  22.     m_hwnd(NULL),
  23.     m_Dlg(NULL),
  24.     m_pPageSite(NULL),
  25.     m_bObjectSet(FALSE),
  26.     m_bDirty(FALSE)
  27. {
  28. }
  29. #ifdef UNICODE
  30. CBasePropertyPage::CBasePropertyPage(CHAR *pName,      // Debug only name
  31.                                      LPUNKNOWN pUnk,    // COM Delegator
  32.                                      int DialogId,      // Resource ID
  33.                                      int TitleId) :     // To get tital
  34.     CUnknown(pName,pUnk),
  35.     m_DialogId(DialogId),
  36.     m_TitleId(TitleId),
  37.     m_hwnd(NULL),
  38.     m_Dlg(NULL),
  39.     m_pPageSite(NULL),
  40.     m_bObjectSet(FALSE),
  41.     m_bDirty(FALSE)
  42. {
  43. }
  44. #endif
  45. // Increment our reference count
  46. STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef()
  47. {
  48.     LONG lRef = InterlockedIncrement(&m_cRef);
  49.     ASSERT(lRef > 0);
  50.     return max(ULONG(m_cRef),1ul);
  51. }
  52. // Release a reference count and protect against reentrancy
  53. STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease()
  54. {
  55.     // If the reference count drops to zero delete ourselves
  56.     if (InterlockedDecrement(&m_cRef) == 0) {
  57.         m_cRef++;
  58.         SetPageSite(NULL);
  59.         SetObjects(0,NULL);
  60.         delete this;
  61.         return ULONG(0);
  62.     } else {
  63.         return max(ULONG(m_cRef),1ul);
  64.     }
  65. }
  66. // Expose our IPropertyPage interface
  67. STDMETHODIMP
  68. CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,void **ppv)
  69. {
  70.     if (riid == IID_IPropertyPage) {
  71.         return GetInterface((IPropertyPage *)this,ppv);
  72.     } else {
  73.         return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  74.     }
  75. }
  76. // Get the page info so that the page site can size itself
  77. STDMETHODIMP CBasePropertyPage::GetPageInfo(LPPROPPAGEINFO pPageInfo)
  78. {
  79.     CheckPointer(pPageInfo,E_POINTER);
  80.     WCHAR wszTitle[STR_MAX_LENGTH];
  81.     WideStringFromResource(wszTitle,m_TitleId);
  82.     // Allocate dynamic memory for the property page title
  83.     LPOLESTR pszTitle;
  84.     HRESULT hr = AMGetWideString(wszTitle, &pszTitle);
  85.     if (FAILED(hr)) {
  86.         NOTE("No caption memory");
  87.         return hr;
  88.     }
  89.     pPageInfo->cb               = sizeof(PROPPAGEINFO);
  90.     pPageInfo->pszTitle         = pszTitle;
  91.     pPageInfo->pszDocString     = NULL;
  92.     pPageInfo->pszHelpFile      = NULL;
  93.     pPageInfo->dwHelpContext    = 0;
  94.     // Set defaults in case GetDialogSize fails
  95.     pPageInfo->size.cx          = 340;
  96.     pPageInfo->size.cy          = 150;
  97.     GetDialogSize(m_DialogId, DialogProc,0L,&pPageInfo->size);
  98.     return NOERROR;
  99. }
  100. // Handles the messages for our property window
  101. INT_PTR CALLBACK CBasePropertyPage::DialogProc(HWND hwnd,
  102.                                             UINT uMsg,
  103.                                             WPARAM wParam,
  104.                                             LPARAM lParam)
  105. {
  106.     CBasePropertyPage *pPropertyPage;
  107.     switch (uMsg) {
  108.         case WM_INITDIALOG:
  109.             SetWindowLongPtr(hwnd, DWLP_USER, lParam);
  110.             // This pointer may be NULL when calculating size
  111.             pPropertyPage = (CBasePropertyPage *) lParam;
  112.             if (pPropertyPage == NULL) {
  113.                 return (LRESULT) 1;
  114.             }
  115.             pPropertyPage->m_Dlg = hwnd;
  116.     }
  117.     // This pointer may be NULL when calculating size
  118.     pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER);
  119.     if (pPropertyPage == NULL) {
  120.         return (LRESULT) 1;
  121.     }
  122.     return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
  123. }
  124. // Tells us the object that should be informed of the property changes
  125. STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,LPUNKNOWN *ppUnk)
  126. {
  127.     if (cObjects == 1) {
  128.         if ((ppUnk == NULL) || (*ppUnk == NULL)) {
  129.             return E_POINTER;
  130.         }
  131.         // Set a flag to say that we have set the Object
  132.         m_bObjectSet = TRUE ;
  133.         return OnConnect(*ppUnk);
  134.     } else if (cObjects == 0) {
  135.         // Set a flag to say that we have not set the Object for the page
  136.         m_bObjectSet = FALSE ;
  137.         return OnDisconnect();
  138.     }
  139.     DbgBreak("No support for more than one object");
  140.     return E_UNEXPECTED;
  141. }
  142. // Create the window we will use to edit properties
  143. STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent,
  144.                                          LPCRECT pRect,
  145.                                          BOOL fModal)
  146. {
  147.     CheckPointer(pRect,E_POINTER);
  148.     // Return failure if SetObject has not been called.
  149.     if (m_bObjectSet == FALSE) {
  150.         return E_UNEXPECTED;
  151.     }
  152.     if (m_hwnd) {
  153.         return E_UNEXPECTED;
  154.     }
  155.     m_hwnd = CreateDialogParam(g_hInst,
  156.                                MAKEINTRESOURCE(m_DialogId),
  157.                                hwndParent,
  158.                                DialogProc,
  159.                                (LPARAM) this);
  160.     if (m_hwnd == NULL) {
  161.         return E_OUTOFMEMORY;
  162.     }
  163.     OnActivate();
  164.     Move(pRect);
  165.     return Show(SW_SHOWNORMAL);
  166. }
  167. // Set the position of the property page
  168. STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect)
  169. {
  170.     CheckPointer(pRect,E_POINTER);
  171.     if (m_hwnd == NULL) {
  172.         return E_UNEXPECTED;
  173.     }
  174.     MoveWindow(m_hwnd,              // Property page handle
  175.                pRect->left,         // x coordinate
  176.                pRect->top,          // y coordinate
  177.                WIDTH(pRect),        // Overall window width
  178.                HEIGHT(pRect),       // And likewise height
  179.                TRUE);               // Should we repaint it
  180.     return NOERROR;
  181. }
  182. // Display the property dialog
  183. STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow)
  184. {
  185.    // Have we been activated yet
  186.     if (m_hwnd == NULL) {
  187.         return E_UNEXPECTED;
  188.     }
  189.     // Ignore wrong show flags
  190.     if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) {
  191.         return E_INVALIDARG;
  192.     }
  193.     ShowWindow(m_hwnd,nCmdShow);
  194.     InvalidateRect(m_hwnd,NULL,TRUE);
  195.     return NOERROR;
  196. }
  197. // Destroy the property page dialog
  198. STDMETHODIMP CBasePropertyPage::Deactivate(void)
  199. {
  200.     if (m_hwnd == NULL) {
  201.         return E_UNEXPECTED;
  202.     }
  203.     // Remove WS_EX_CONTROLPARENT before DestroyWindow call
  204.     DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE);
  205.     dwStyle = dwStyle & (~WS_EX_CONTROLPARENT);
  206.     //  Set m_hwnd to be NULL temporarily so the message handler
  207.     //  for WM_STYLECHANGING doesn't add the WS_EX_CONTROLPARENT
  208.     //  style back in
  209.     HWND hwnd = m_hwnd;
  210.     m_hwnd = NULL;
  211.     SetWindowLong(hwnd, GWL_EXSTYLE, dwStyle);
  212.     m_hwnd = hwnd;
  213.     OnDeactivate();
  214.     // Destroy the dialog window
  215.     DestroyWindow(m_hwnd);
  216.     m_hwnd = NULL;
  217.     return NOERROR;
  218. }
  219. // Tells the application property page site
  220. STDMETHODIMP CBasePropertyPage::SetPageSite(LPPROPERTYPAGESITE pPageSite)
  221. {
  222.     if (pPageSite) {
  223.         if (m_pPageSite) {
  224.             return E_UNEXPECTED;
  225.         }
  226.         m_pPageSite = pPageSite;
  227.         m_pPageSite->AddRef();
  228.     } else {
  229.         if (m_pPageSite == NULL) {
  230.             return E_UNEXPECTED;
  231.         }
  232.         m_pPageSite->Release();
  233.         m_pPageSite = NULL;
  234.     }
  235.     return NOERROR;
  236. }
  237. // Apply any changes so far made
  238. STDMETHODIMP CBasePropertyPage::Apply()
  239. {
  240.     // In ActiveMovie 1.0 we used to check whether we had been activated or
  241.     // not. This is too constrictive. Apply should be allowed as long as
  242.     // SetObject was called to set an object. So we will no longer check to
  243.     // see if we have been activated (ie., m_hWnd != NULL), but instead
  244.     // make sure that m_bObjectSet is TRUE (ie., SetObject has been called).
  245.     if (m_bObjectSet == FALSE) {
  246.         return E_UNEXPECTED;
  247.     }
  248.     // Must have had a site set
  249.     if (m_pPageSite == NULL) {
  250.         return E_UNEXPECTED;
  251.     }
  252.     // Has anything changed
  253.     if (m_bDirty == FALSE) {
  254.         return NOERROR;
  255.     }
  256.     // Commit derived class changes
  257.     HRESULT hr = OnApplyChanges();
  258.     if (SUCCEEDED(hr)) {
  259.         m_bDirty = FALSE;
  260.     }
  261.     return hr;
  262. }
  263. // Base class definition for message handling
  264. INT_PTR CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  265. {
  266.     // we would like the TAB key to move around the tab stops in our property
  267.     // page, but for some reason OleCreatePropertyFrame clears the CONTROLPARENT
  268.     // style behind our back, so we need to switch it back on now behind its
  269.     // back.  Otherwise the tab key will be useless in every page.
  270.     //
  271.     CBasePropertyPage *pPropertyPage;
  272.     {
  273.         pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER);
  274.         if (pPropertyPage->m_hwnd == NULL) {
  275.             return 0;
  276.         }
  277.         switch (uMsg) {
  278.           case WM_STYLECHANGING:
  279.               if (wParam == GWL_EXSTYLE) {
  280.                   LPSTYLESTRUCT lpss = (LPSTYLESTRUCT)lParam;
  281.                   lpss->styleNew |= WS_EX_CONTROLPARENT;
  282.                   return 0;
  283.               }
  284.         }
  285.     }
  286.     return DefWindowProc(hwnd,uMsg,wParam,lParam);
  287. }