home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / cprop.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-26  |  8.6 KB  |  333 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11.  
  12. #include <streams.h>
  13.  
  14. // Constructor for the base property page class. As described in the header
  15. // file we must be initialised with dialog and title resource identifiers.
  16. // The class supports IPropertyPage and overrides AddRef and Release calls
  17. // to keep track of the reference counts. When the last count is released
  18. // we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces
  19. // previously obtained by the property page when it had SetObjects called
  20.  
  21. CBasePropertyPage::CBasePropertyPage(TCHAR *pName,      // Debug only name
  22.                                      LPUNKNOWN pUnk,    // COM Delegator
  23.                                      HRESULT *phr,      // Return code
  24.                                      int DialogId,      // Resource ID
  25.                                      int TitleId) :     // To get tital
  26.     CUnknown(pName,pUnk,phr),
  27.     m_DialogId(DialogId),
  28.     m_TitleId(TitleId),
  29.     m_hwnd(NULL),
  30.     m_Dlg(NULL),
  31.     m_pPageSite(NULL),
  32.     m_bDirty(FALSE)
  33. {
  34.     ASSERT(phr);
  35. }
  36.  
  37.  
  38. // Increment our reference count
  39.  
  40. STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef()
  41. {
  42.     LONG lRef = InterlockedIncrement(&m_cRef);
  43.     ASSERT(lRef > 0);
  44.     return max(ULONG(m_cRef),1ul);
  45. }
  46.  
  47.  
  48. // Release a reference count and protect against reentrancy
  49.  
  50. STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease()
  51. {
  52.     // If the reference count drops to zero delete ourselves
  53.  
  54.     if (InterlockedDecrement(&m_cRef) == 0) {
  55.         m_cRef++;
  56.         SetPageSite(NULL);
  57.         SetObjects(0,NULL);
  58.         delete this;
  59.         return ULONG(0);
  60.     } else {
  61.         return max(ULONG(m_cRef),1ul);
  62.     }
  63. }
  64.  
  65.  
  66. // Expose our IPropertyPage interface
  67.  
  68. STDMETHODIMP
  69. CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,void **ppv)
  70. {
  71.     CheckPointer(ppv,E_POINTER);
  72.  
  73.     if (riid == IID_IPropertyPage) {
  74.         return GetInterface((IPropertyPage *)this,ppv);
  75.     } else {
  76.         return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  77.     }
  78. }
  79.  
  80.  
  81. // Get the page info so that the page site can size itself
  82.  
  83. STDMETHODIMP CBasePropertyPage::GetPageInfo(LPPROPPAGEINFO pPageInfo)
  84. {
  85.     CheckPointer(pPageInfo,E_POINTER);
  86.     WCHAR wszTitle[STR_MAX_LENGTH];
  87.     WideStringFromResource(wszTitle,m_TitleId);
  88.     int Length = (lstrlenW(wszTitle) + 1) * sizeof(WCHAR);
  89.  
  90.     // Allocate dynamic memory for the property page title
  91.  
  92.     LPOLESTR pszTitle = (LPOLESTR) QzTaskMemAlloc(Length);
  93.     if (pszTitle == NULL) {
  94.         NOTE("No caption memory");
  95.         return E_OUTOFMEMORY;
  96.     }
  97.  
  98.     CopyMemory(pszTitle,wszTitle,Length);
  99.  
  100.     pPageInfo->cb               = sizeof(PROPPAGEINFO);
  101.     pPageInfo->pszTitle         = pszTitle;
  102.     pPageInfo->pszDocString     = NULL;
  103.     pPageInfo->pszHelpFile      = NULL;
  104.     pPageInfo->dwHelpContext    = 0;
  105.  
  106.     // Set defaults in case GetDialogSize fails
  107.     pPageInfo->size.cx          = 340;
  108.     pPageInfo->size.cy          = 150;
  109.  
  110.     GetDialogSize(m_DialogId,(DLGPROC) DialogProc,0L,&pPageInfo->size);
  111.     return NOERROR;
  112. }
  113.  
  114.  
  115. // Handles the messages for our property window
  116.  
  117. BOOL CALLBACK CBasePropertyPage::DialogProc(HWND hwnd,
  118.                                             UINT uMsg,
  119.                                             WPARAM wParam,
  120.                                             LPARAM lParam)
  121. {
  122.     CBasePropertyPage *pPropertyPage;
  123.  
  124.     switch (uMsg) {
  125.  
  126.         case WM_INITDIALOG:
  127.  
  128.             SetWindowLong(hwnd, DWL_USER, lParam);
  129.  
  130.             // This pointer may be NULL when calculating size
  131.  
  132.             pPropertyPage = (CBasePropertyPage *) lParam;
  133.             if (pPropertyPage == NULL) {
  134.                 return (LRESULT) 1;
  135.             }
  136.             pPropertyPage->m_Dlg = hwnd;
  137.     }
  138.  
  139.     // This pointer may be NULL when calculating size
  140.  
  141.     pPropertyPage = (CBasePropertyPage *) GetWindowLong(hwnd, DWL_USER);
  142.     if (pPropertyPage == NULL) {
  143.         return (LRESULT) 1;
  144.     }
  145.     return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam);
  146. }
  147.  
  148.  
  149. // Tells us the object that should be informed of the property changes
  150.  
  151. STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,LPUNKNOWN *ppUnk)
  152. {
  153.     if (cObjects == 1) {
  154.  
  155.         if ((ppUnk == NULL) || (*ppUnk == NULL)) {
  156.             return E_POINTER;
  157.         }
  158.         return OnConnect(*ppUnk);
  159.  
  160.     } else if (cObjects == 0) {
  161.         return OnDisconnect();
  162.     }
  163.  
  164.     DbgBreak("No support for more than one object");
  165.     return E_UNEXPECTED;
  166. }
  167.  
  168.  
  169. // Create the window we will use to edit properties
  170.  
  171. STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent,
  172.                                          LPCRECT pRect,
  173.                                          BOOL fModal)
  174. {
  175.     CheckPointer(pRect,E_POINTER);
  176.     if (m_hwnd) {
  177.         return E_UNEXPECTED;
  178.     }
  179.  
  180.     m_hwnd = CreateDialogParam(g_hInst,
  181.                                MAKEINTRESOURCE(m_DialogId),
  182.                                hwndParent,
  183.                                DialogProc,
  184.                                (LPARAM) this);
  185.     if (m_hwnd == NULL) {
  186.         return E_OUTOFMEMORY;
  187.     }
  188.  
  189.     // Parent should control us so the user can tab out of property page
  190.  
  191.     DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE);
  192.     dwStyle = dwStyle | WS_EX_CONTROLPARENT;
  193.     SetWindowLong(m_hwnd, GWL_EXSTYLE, dwStyle);
  194.  
  195.     OnActivate();
  196.     Move(pRect);
  197.     return Show(SW_SHOWNORMAL);
  198. }
  199.  
  200.  
  201. // Set the position of the property page
  202.  
  203. STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect)
  204. {
  205.     CheckPointer(pRect,E_POINTER);
  206.  
  207.     if (m_hwnd == NULL) {
  208.         return E_UNEXPECTED;
  209.     }
  210.  
  211.     MoveWindow(m_hwnd,              // Property page handle
  212.                pRect->left,         // x coordinate
  213.                pRect->top,          // y coordinate
  214.                WIDTH(pRect),        // Overall window width
  215.                HEIGHT(pRect),       // And likewise height
  216.                TRUE);               // Should we repaint it
  217.  
  218.     return NOERROR;
  219. }
  220.  
  221.  
  222. // Display the property dialog
  223.  
  224. STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow)
  225. {
  226.    // Have we been activated yet
  227.  
  228.     if (m_hwnd == NULL) {
  229.         return E_UNEXPECTED;
  230.     }
  231.  
  232.     // Ignore wrong show flags
  233.  
  234.     if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) {
  235.         return E_INVALIDARG;
  236.     }
  237.  
  238.     ShowWindow(m_hwnd,nCmdShow);
  239.     InvalidateRect(m_hwnd,NULL,TRUE);
  240.     return NOERROR;
  241. }
  242.  
  243.  
  244. // Destroy the property page dialog
  245.  
  246. STDMETHODIMP CBasePropertyPage::Deactivate(void)
  247. {
  248.     if (m_hwnd == NULL) {
  249.         return E_UNEXPECTED;
  250.     }
  251.  
  252.     // Remove WS_EX_CONTROLPARENT before DestroyWindow call
  253.  
  254.     DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE);
  255.     dwStyle = dwStyle & (~WS_EX_CONTROLPARENT);
  256.     SetWindowLong(m_hwnd, GWL_EXSTYLE, dwStyle);
  257.  
  258.     OnDeactivate();
  259.  
  260.     // Destroy the dialog window
  261.  
  262.     DestroyWindow(m_hwnd);
  263.     m_hwnd = NULL;
  264.     return NOERROR;
  265. }
  266.  
  267.  
  268. // Tells the application property page site
  269.  
  270. STDMETHODIMP CBasePropertyPage::SetPageSite(LPPROPERTYPAGESITE pPageSite)
  271. {
  272.     if (pPageSite) {
  273.  
  274.         if (m_pPageSite) {
  275.             return E_UNEXPECTED;
  276.         }
  277.  
  278.         m_pPageSite = pPageSite;
  279.         m_pPageSite->AddRef();
  280.  
  281.     } else {
  282.  
  283.         if (m_pPageSite == NULL) {
  284.             return E_UNEXPECTED;
  285.         }
  286.  
  287.         m_pPageSite->Release();
  288.         m_pPageSite = NULL;
  289.     }
  290.     return NOERROR;
  291. }
  292.  
  293.  
  294. // Apply any changes so far made
  295.  
  296. STDMETHODIMP CBasePropertyPage::Apply()
  297. {
  298.     // Have we been activated yet
  299.  
  300.     if (m_hwnd == NULL) {
  301.         return E_UNEXPECTED;
  302.     }
  303.  
  304.     // Must have had a site set
  305.  
  306.     if (m_pPageSite == NULL) {
  307.         return E_UNEXPECTED;
  308.     }
  309.  
  310.     // Has anything changed
  311.  
  312.     if (m_bDirty == FALSE) {
  313.         return NOERROR;
  314.     }
  315.  
  316.     // Commit derived class changes
  317.  
  318.     HRESULT hr = OnApplyChanges();
  319.     if (SUCCEEDED(hr)) {
  320.         m_bDirty = FALSE;
  321.     }
  322.     return hr;
  323. }
  324.  
  325.  
  326. // Base class definition for message handling
  327.  
  328. BOOL CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  329. {
  330.     return DefWindowProc(hwnd,uMsg,wParam,lParam);
  331. }
  332.  
  333.