123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- //------------------------------------------------------------------------------
- // 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);
- }
|