summaryrefslogtreecommitdiff
path: root/third_party/BaseClasses/cprop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/BaseClasses/cprop.cpp')
-rw-r--r--third_party/BaseClasses/cprop.cpp383
1 files changed, 383 insertions, 0 deletions
diff --git a/third_party/BaseClasses/cprop.cpp b/third_party/BaseClasses/cprop.cpp
new file mode 100644
index 00000000..7bd76b4e
--- /dev/null
+++ b/third_party/BaseClasses/cprop.cpp
@@ -0,0 +1,383 @@
+//------------------------------------------------------------------------------
+// File: CProp.cpp
+//
+// Desc: DirectShow base classes - implements CBasePropertyPage class.
+//
+// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------------------------
+
+
+#include <streams.h>
+
+// Constructor for the base property page class. As described in the header
+// file we must be initialised with dialog and title resource identifiers.
+// The class supports IPropertyPage and overrides AddRef and Release calls
+// to keep track of the reference counts. When the last count is released
+// we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces
+// previously obtained by the property page when it had SetObjects called
+
+CBasePropertyPage::CBasePropertyPage(__in_opt LPCTSTR pName, // Debug only name
+ __inout_opt LPUNKNOWN pUnk, // COM Delegator
+ int DialogId, // Resource ID
+ int TitleId) : // To get tital
+ CUnknown(pName,pUnk),
+ m_DialogId(DialogId),
+ m_TitleId(TitleId),
+ m_hwnd(NULL),
+ m_Dlg(NULL),
+ m_pPageSite(NULL),
+ m_bObjectSet(FALSE),
+ m_bDirty(FALSE)
+{
+}
+
+#ifdef UNICODE
+CBasePropertyPage::CBasePropertyPage(__in_opt LPCSTR pName, // Debug only name
+ __inout_opt LPUNKNOWN pUnk, // COM Delegator
+ int DialogId, // Resource ID
+ int TitleId) : // To get tital
+ CUnknown(pName,pUnk),
+ m_DialogId(DialogId),
+ m_TitleId(TitleId),
+ m_hwnd(NULL),
+ m_Dlg(NULL),
+ m_pPageSite(NULL),
+ m_bObjectSet(FALSE),
+ m_bDirty(FALSE)
+{
+}
+#endif
+
+// Increment our reference count
+
+STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef()
+{
+ LONG lRef = InterlockedIncrement(&m_cRef);
+ ASSERT(lRef > 0);
+ return max(ULONG(m_cRef),1ul);
+}
+
+
+// Release a reference count and protect against reentrancy
+
+STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease()
+{
+ // If the reference count drops to zero delete ourselves
+
+ LONG lRef = InterlockedDecrement(&m_cRef);
+ if (lRef == 0) {
+ m_cRef++;
+ SetPageSite(NULL);
+ SetObjects(0,NULL);
+ delete this;
+ return ULONG(0);
+ } else {
+ // Don't touch m_cRef again here!
+ return max(ULONG(lRef),1ul);
+ }
+}
+
+
+// Expose our IPropertyPage interface
+
+STDMETHODIMP
+CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv)
+{
+ if (riid == IID_IPropertyPage) {
+ return GetInterface((IPropertyPage *)this,ppv);
+ } else {
+ return CUnknown::NonDelegatingQueryInterface(riid,ppv);
+ }
+}
+
+
+// Get the page info so that the page site can size itself
+
+STDMETHODIMP CBasePropertyPage::GetPageInfo(__out LPPROPPAGEINFO pPageInfo)
+{
+ CheckPointer(pPageInfo,E_POINTER);
+ WCHAR wszTitle[STR_MAX_LENGTH];
+ WideStringFromResource(wszTitle,m_TitleId);
+
+ // Allocate dynamic memory for the property page title
+
+ LPOLESTR pszTitle;
+ HRESULT hr = AMGetWideString(wszTitle, &pszTitle);
+ if (FAILED(hr)) {
+ NOTE("No caption memory");
+ return hr;
+ }
+
+ pPageInfo->cb = sizeof(PROPPAGEINFO);
+ pPageInfo->pszTitle = pszTitle;
+ pPageInfo->pszDocString = NULL;
+ pPageInfo->pszHelpFile = NULL;
+ pPageInfo->dwHelpContext = 0;
+
+ // Set defaults in case GetDialogSize fails
+ pPageInfo->size.cx = 340;
+ pPageInfo->size.cy = 150;
+
+ GetDialogSize(m_DialogId, DialogProc,0L,&pPageInfo->size);
+ return NOERROR;
+}
+
+
+// Handles the messages for our property window
+
+INT_PTR CALLBACK CBasePropertyPage::DialogProc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ CBasePropertyPage *pPropertyPage;
+
+ switch (uMsg) {
+
+ case WM_INITDIALOG:
+
+ _SetWindowLongPtr(hwnd, DWLP_USER, lParam);
+
+ // This pointer may be NULL when calculating size
+
+ pPropertyPage = (CBasePropertyPage *) lParam;
+ if (pPropertyPage == NULL) {
+ return (LRESULT) 1;
+ }
+ pPropertyPage->m_Dlg = hwnd;
+ }
+
+ // This pointer may be NULL when calculating size
+
+ pPropertyPage = _GetWindowLongPtr<CBasePropertyPage*>(hwnd, DWLP_USER);
+ if (pPropertyPage == NULL) {
+ return (LRESULT) 1;
+ }
+ return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
+}
+
+
+// Tells us the object that should be informed of the property changes
+
+STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,__in_ecount_opt(cObjects) LPUNKNOWN *ppUnk)
+{
+ if (cObjects == 1) {
+
+ if ((ppUnk == NULL) || (*ppUnk == NULL)) {
+ return E_POINTER;
+ }
+
+ // Set a flag to say that we have set the Object
+ m_bObjectSet = TRUE ;
+ return OnConnect(*ppUnk);
+
+ } else if (cObjects == 0) {
+
+ // Set a flag to say that we have not set the Object for the page
+ m_bObjectSet = FALSE ;
+ return OnDisconnect();
+ }
+
+ DbgBreak("No support for more than one object");
+ return E_UNEXPECTED;
+}
+
+
+// Create the window we will use to edit properties
+
+STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent,
+ LPCRECT pRect,
+ BOOL fModal)
+{
+ CheckPointer(pRect,E_POINTER);
+
+ // Return failure if SetObject has not been called.
+ if (m_bObjectSet == FALSE) {
+ return E_UNEXPECTED;
+ }
+
+ if (m_hwnd) {
+ return E_UNEXPECTED;
+ }
+
+ m_hwnd = CreateDialogParam(g_hInst,
+ MAKEINTRESOURCE(m_DialogId),
+ hwndParent,
+ DialogProc,
+ (LPARAM) this);
+ if (m_hwnd == NULL) {
+ return E_OUTOFMEMORY;
+ }
+
+ OnActivate();
+ Move(pRect);
+ return Show(SW_SHOWNORMAL);
+}
+
+
+// Set the position of the property page
+
+STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect)
+{
+ CheckPointer(pRect,E_POINTER);
+
+ if (m_hwnd == NULL) {
+ return E_UNEXPECTED;
+ }
+
+ MoveWindow(m_hwnd, // Property page handle
+ pRect->left, // x coordinate
+ pRect->top, // y coordinate
+ WIDTH(pRect), // Overall window width
+ HEIGHT(pRect), // And likewise height
+ TRUE); // Should we repaint it
+
+ return NOERROR;
+}
+
+
+// Display the property dialog
+
+STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow)
+{
+ // Have we been activated yet
+
+ if (m_hwnd == NULL) {
+ return E_UNEXPECTED;
+ }
+
+ // Ignore wrong show flags
+
+ if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) {
+ return E_INVALIDARG;
+ }
+
+ ShowWindow(m_hwnd,nCmdShow);
+ InvalidateRect(m_hwnd,NULL,TRUE);
+ return NOERROR;
+}
+
+
+// Destroy the property page dialog
+
+STDMETHODIMP CBasePropertyPage::Deactivate(void)
+{
+ if (m_hwnd == NULL) {
+ return E_UNEXPECTED;
+ }
+
+ // Remove WS_EX_CONTROLPARENT before DestroyWindow call
+
+ DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE);
+ dwStyle = dwStyle & (~WS_EX_CONTROLPARENT);
+
+ // Set m_hwnd to be NULL temporarily so the message handler
+ // for WM_STYLECHANGING doesn't add the WS_EX_CONTROLPARENT
+ // style back in
+ HWND hwnd = m_hwnd;
+ m_hwnd = NULL;
+ SetWindowLong(hwnd, GWL_EXSTYLE, dwStyle);
+ m_hwnd = hwnd;
+
+ OnDeactivate();
+
+ // Destroy the dialog window
+
+ DestroyWindow(m_hwnd);
+ m_hwnd = NULL;
+ return NOERROR;
+}
+
+
+// Tells the application property page site
+
+STDMETHODIMP CBasePropertyPage::SetPageSite(__in_opt LPPROPERTYPAGESITE pPageSite)
+{
+ if (pPageSite) {
+
+ if (m_pPageSite) {
+ return E_UNEXPECTED;
+ }
+
+ m_pPageSite = pPageSite;
+ m_pPageSite->AddRef();
+
+ } else {
+
+ if (m_pPageSite == NULL) {
+ return E_UNEXPECTED;
+ }
+
+ m_pPageSite->Release();
+ m_pPageSite = NULL;
+ }
+ return NOERROR;
+}
+
+
+// Apply any changes so far made
+
+STDMETHODIMP CBasePropertyPage::Apply()
+{
+ // In ActiveMovie 1.0 we used to check whether we had been activated or
+ // not. This is too constrictive. Apply should be allowed as long as
+ // SetObject was called to set an object. So we will no longer check to
+ // see if we have been activated (ie., m_hWnd != NULL), but instead
+ // make sure that m_bObjectSet is TRUE (ie., SetObject has been called).
+
+ if (m_bObjectSet == FALSE) {
+ return E_UNEXPECTED;
+ }
+
+ // Must have had a site set
+
+ if (m_pPageSite == NULL) {
+ return E_UNEXPECTED;
+ }
+
+ // Has anything changed
+
+ if (m_bDirty == FALSE) {
+ return NOERROR;
+ }
+
+ // Commit derived class changes
+
+ HRESULT hr = OnApplyChanges();
+ if (SUCCEEDED(hr)) {
+ m_bDirty = FALSE;
+ }
+ return hr;
+}
+
+
+// Base class definition for message handling
+
+INT_PTR CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
+{
+ // we would like the TAB key to move around the tab stops in our property
+ // page, but for some reason OleCreatePropertyFrame clears the CONTROLPARENT
+ // style behind our back, so we need to switch it back on now behind its
+ // back. Otherwise the tab key will be useless in every page.
+ //
+
+ CBasePropertyPage *pPropertyPage;
+ {
+ pPropertyPage = _GetWindowLongPtr<CBasePropertyPage*>(hwnd, DWLP_USER);
+
+ if (pPropertyPage->m_hwnd == NULL) {
+ return 0;
+ }
+ switch (uMsg) {
+ case WM_STYLECHANGING:
+ if (wParam == GWL_EXSTYLE) {
+ LPSTYLESTRUCT lpss = (LPSTYLESTRUCT)lParam;
+ lpss->styleNew |= WS_EX_CONTROLPARENT;
+ return 0;
+ }
+ }
+ }
+
+ return DefWindowProc(hwnd,uMsg,wParam,lParam);
+}
+