home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap16 / beepprop / beepprop.cpp next >
C/C++ Source or Header  |  1996-05-21  |  20KB  |  872 lines

  1. /*
  2.  * BEEPPROP.CPP
  3.  * Beeper Property Page Chapter 16
  4.  *
  5.  * Server module code and class code CBeeperPropertyPage class.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #define INITGUIDS
  16. #include "beepprop.h"
  17.  
  18.  
  19. //Count number of objects and number of locks.
  20. ULONG       g_cObj=0;
  21. ULONG       g_cLock=0;
  22. HINSTANCE   g_hInst=NULL;   //For resources
  23.  
  24. #ifdef WIN32
  25. TCHAR       g_szObj[]=TEXT("Object");
  26. #else
  27. TCHAR       g_szObjHi[]=TEXT("ObjectHi");
  28. TCHAR       g_szObjLo[]=TEXT("ObjectLo");
  29. #endif
  30.  
  31. /*
  32.  * LibMain(32)
  33.  *
  34.  * Purpose:
  35.  *  Entry point conditionally compiled for Win32 and Windows
  36.  *  3.1.  Provides the proper structure for each environment.
  37.  */
  38.  
  39. #ifdef WIN32
  40. BOOL WINAPI LibMain32(HINSTANCE hInstance, ULONG ulReason
  41.     , LPVOID pvReserved)
  42.     {
  43.     g_hInst=hInstance;
  44.  
  45.     if (DLL_PROCESS_DETACH==ulReason)
  46.         {
  47.         return TRUE;
  48.         }
  49.     else
  50.         {
  51.         if (DLL_PROCESS_ATTACH!=ulReason)
  52.             return TRUE;
  53.         }
  54.  
  55.     return TRUE;
  56.     }
  57. #else
  58. int PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg
  59.     , WORD cbHeapSize, LPSTR lpCmdLine)
  60.     {
  61.     if (0!=cbHeapSize)
  62.         UnlockData(0);
  63.  
  64.     g_hInst=hInstance;
  65.     return (int)hInstance;
  66.     }
  67. #endif
  68.  
  69.  
  70.  
  71. /*
  72.  * DllGetClassObject
  73.  * DllCanUnloadNow
  74.  * Standard COM exports for DLL servers.
  75.  */
  76.  
  77. HRESULT APIENTRY DllGetClassObject(REFCLSID rclsid, REFIID riid
  78.     , PPVOID ppv)
  79.     {
  80.     CBeeperPPFactory *pBF;
  81.     HRESULT         hr;
  82.  
  83.     if (CLSID_BeeperPropertyPage!=rclsid)
  84.         return ResultFromScode(E_FAIL);
  85.  
  86.     //Check that we can provide the interface
  87.     if (IID_IUnknown!=riid && IID_IClassFactory!=riid)
  88.         return ResultFromScode(E_NOINTERFACE);
  89.  
  90.     //Return our beeper factory's IClassFactory
  91.     pBF=new CBeeperPPFactory();
  92.  
  93.     if (NULL==pBF)
  94.         return ResultFromScode(E_OUTOFMEMORY);
  95.  
  96.     //If the factory hasn't the interface, delete it
  97.     hr=pBF->QueryInterface(riid, ppv);
  98.  
  99.     if (FAILED(hr))
  100.         delete pBF;
  101.     else
  102.         g_cObj++;
  103.  
  104.     return hr;
  105.     }
  106.  
  107.  
  108. STDAPI DllCanUnloadNow(void)
  109.     {
  110.     SCODE   sc;
  111.  
  112.     //Our answer is whether there are any object or locks
  113.     sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  114.     return ResultFromScode(sc);
  115.     }
  116.  
  117.  
  118.  
  119. /*
  120.  * CBeeperPPFactory::CBeeperPPFactory
  121.  * CBeeperPPFactory::~CBeeperPPFactory
  122.  * CBeeperPPFactory::QueryInterface
  123.  * CBeeperPPFactory::AddRef
  124.  * CBeeperPPFactory::Release
  125.  */
  126.  
  127. CBeeperPPFactory::CBeeperPPFactory(void)
  128.     {
  129.     m_cRef=0L;
  130.     return;
  131.     }
  132.  
  133. CBeeperPPFactory::~CBeeperPPFactory(void)
  134.     {
  135.     return;
  136.     }
  137.  
  138. STDMETHODIMP CBeeperPPFactory::QueryInterface(REFIID riid, PPVOID ppv)
  139.     {
  140.     *ppv=NULL;
  141.  
  142.     if (IID_IUnknown==riid || IID_IClassFactory==riid)
  143.         *ppv=this;
  144.  
  145.     if (NULL!=*ppv)
  146.         {
  147.         ((LPUNKNOWN)*ppv)->AddRef();
  148.         return NOERROR;
  149.         }
  150.  
  151.     return ResultFromScode(E_NOINTERFACE);
  152.     }
  153.  
  154.  
  155. STDMETHODIMP_(ULONG) CBeeperPPFactory::AddRef(void)
  156.     {
  157.     return ++m_cRef;
  158.     }
  159.  
  160.  
  161. STDMETHODIMP_(ULONG) CBeeperPPFactory::Release(void)
  162.     {
  163.     if (0!=--m_cRef)
  164.         return m_cRef;
  165.  
  166.     delete this;
  167.     g_cObj--;
  168.     return 0;
  169.     }
  170.  
  171.  
  172.  
  173. /*
  174.  * CBeeperPPFactory::CreateInstance
  175.  * CBeeperPPFactory::LockServer
  176.  */
  177.  
  178. STDMETHODIMP CBeeperPPFactory::CreateInstance(LPUNKNOWN pUnkOuter
  179.     , REFIID riid, PPVOID ppvObj)
  180.     {
  181.     PCBeeperPropPage    pObj;
  182.     HRESULT             hr;
  183.  
  184.     *ppvObj=NULL;
  185.     hr=ResultFromScode(E_OUTOFMEMORY);
  186.  
  187.     //No aggregation supported
  188.     if (NULL!=pUnkOuter)
  189.         return ResultFromScode(CLASS_E_NOAGGREGATION);
  190.  
  191.     //Create the object passing function to notify on destruction.
  192.     pObj=new CBeeperPropPage(g_hInst);
  193.  
  194.     if (NULL==pObj)
  195.         return hr;
  196.  
  197.     if (pObj->Init())
  198.         hr=pObj->QueryInterface(riid, ppvObj);
  199.  
  200.     //Kill the object if initial creation or Init failed.
  201.     if (FAILED(hr))
  202.         delete pObj;
  203.     else
  204.         g_cObj++;
  205.  
  206.     return hr;
  207.     }
  208.  
  209.  
  210. STDMETHODIMP CBeeperPPFactory::LockServer(BOOL fLock)
  211.     {
  212.     if (fLock)
  213.         g_cLock++;
  214.     else
  215.         g_cLock--;
  216.  
  217.     return NOERROR;
  218.     }
  219.  
  220.  
  221.  
  222. /***
  223.  *** CBeeperPropPage implementation
  224.  ***/
  225.  
  226.  
  227. /*
  228.  * CBeeperPropPage::CBeeperPropPage
  229.  * CBeeperPropPage::~CBeeperPropPage
  230.  *
  231.  * Constructor Parameters:
  232.  *  hInst           HINSTANCE of the module
  233.  */
  234.  
  235. CBeeperPropPage::CBeeperPropPage(HINSTANCE hInst)
  236.     {
  237.     m_cRef=0L;
  238.  
  239.     m_hInst=hInst;
  240.     m_uIDTemplate=IDD_BEEPERPROPS_0;
  241.     m_hDlg=NULL;
  242.  
  243.     //Default sizes
  244.     m_cx=300;
  245.     m_cy=100;
  246.  
  247.     m_pIPropertyPageSite=NULL;
  248.     m_ppIBeeper=NULL;
  249.     m_cObjects=0;
  250.  
  251.     m_uIDLastSound=IDC_BEEPDEFAULT;
  252.     m_fDirty=FALSE;
  253.  
  254.     m_lcid=LOCALE_USER_DEFAULT;
  255.     return;
  256.     }
  257.  
  258. CBeeperPropPage::~CBeeperPropPage(void)
  259.     {
  260.     if (NULL!=m_hDlg)
  261.         DestroyWindow(m_hDlg);
  262.  
  263.     FreeAllObjects();
  264.     ReleaseInterface(m_pIPropertyPageSite);
  265.     return;
  266.     }
  267.  
  268.  
  269. /*
  270.  * CBeeperPropPage::QueryInterface
  271.  * CBeeperPropPage::AddRef
  272.  * CBeeperPropPage::Release
  273.  */
  274.  
  275. STDMETHODIMP CBeeperPropPage::QueryInterface(REFIID riid, PPVOID ppv)
  276.     {
  277.     *ppv=NULL;
  278.  
  279.     if (IID_IUnknown==riid || IID_IPropertyPage==riid)
  280.         *ppv=this;
  281.  
  282.     if (NULL!=*ppv)
  283.         {
  284.         ((LPUNKNOWN)*ppv)->AddRef();
  285.         return NOERROR;
  286.         }
  287.  
  288.     return ResultFromScode(E_NOINTERFACE);
  289.     }
  290.  
  291.  
  292. STDMETHODIMP_(ULONG) CBeeperPropPage::AddRef(void)
  293.     {
  294.     return ++m_cRef;
  295.     }
  296.  
  297.  
  298. STDMETHODIMP_(ULONG) CBeeperPropPage::Release(void)
  299.     {
  300.     if (0!=--m_cRef)
  301.         return m_cRef;
  302.  
  303.     g_cObj--;
  304.     delete this;
  305.     return 0;
  306.     }
  307.  
  308.  
  309.  
  310.  
  311. /*
  312.  * CBeeperPropPage::Init
  313.  *
  314.  * Purpose:
  315.  *  Performs initialization operations that might fail.
  316.  *
  317.  * Parameters:
  318.  *  None
  319.  *
  320.  * Return Value:
  321.  *  BOOL            TRUE if initialization successful, FALSE
  322.  *                  otherwise.
  323.  */
  324.  
  325. BOOL CBeeperPropPage::Init(void)
  326.     {
  327.     //Nothing to do
  328.     return TRUE;
  329.     }
  330.  
  331.  
  332.  
  333.  
  334. /*
  335.  * CBeeperPropPage::FreeAllObjects
  336.  *
  337.  * Purpose:
  338.  *  Releases all the objects from IPropertyPage::SetObjects
  339.  *
  340.  * Parameters:
  341.  *  None
  342.  */
  343.  
  344. void CBeeperPropPage::FreeAllObjects(void)
  345.     {
  346.     UINT        i;
  347.  
  348.     if (NULL==m_ppIBeeper)
  349.         return;
  350.  
  351.     for (i=0; i < m_cObjects; i++)
  352.         ReleaseInterface(m_ppIBeeper[i]);
  353.  
  354.     delete [] m_ppIBeeper;
  355.     m_ppIBeeper=NULL;
  356.     m_cObjects=0;
  357.     return;
  358.     }
  359.  
  360.  
  361.  
  362. /*
  363.  * CBeeperPropPage::SetPageSite
  364.  *
  365.  * Purpose:
  366.  *  Provides the property page with the IPropertyPageSite
  367.  *  that contains it.  SetPageSite(NULL) will be called as
  368.  *  part of the close sequence.
  369.  *
  370.  * Parameters:
  371.  *  pPageSite       LPPROPERTYPAGESITE pointer to the site.
  372.  */
  373.  
  374. STDMETHODIMP CBeeperPropPage::SetPageSite
  375.     (LPPROPERTYPAGESITE pPageSite)
  376.     {
  377.     if (NULL==pPageSite)
  378.         ReleaseInterface(m_pIPropertyPageSite)
  379.     else
  380.         {
  381.         HWND        hDlg;
  382.         RECT        rc;
  383.         LCID        lcid;
  384.  
  385.         m_pIPropertyPageSite=pPageSite;
  386.         m_pIPropertyPageSite->AddRef();
  387.  
  388.         if (SUCCEEDED(m_pIPropertyPageSite->GetLocaleID(&lcid)))
  389.             m_lcid=lcid;
  390.  
  391.         /*
  392.          * Now that we know the locale we're running under, we can
  393.          * load the dialog and determine the size it will be to
  394.          * return through GetPageSize.  We just create the dialog
  395.          * here and destroy it again to retrieve the size,
  396.          * leaving Activate to create it for real.
  397.          */
  398.  
  399.         switch (PRIMARYLANGID(m_lcid))
  400.             {
  401.             case LANG_GERMAN:
  402.                 m_uIDTemplate=IDD_BEEPERPROPS_7;
  403.                 break;
  404.  
  405.             case LANG_NEUTRAL:
  406.             case LANG_ENGLISH:
  407.             default:
  408.                 m_uIDTemplate=IDD_BEEPERPROPS_0;
  409.                 break;
  410.             }
  411.  
  412.         hDlg=CreateDialogParam(m_hInst
  413.             , MAKEINTRESOURCE(m_uIDTemplate), GetDesktopWindow()
  414.             , (DLGPROC)BeepPropPageProc, 0L);
  415.  
  416.         //If creation fails, use default values set in constructor
  417.         if (NULL!=hDlg)
  418.             {
  419.             GetWindowRect(hDlg, &rc);
  420.             m_cx=rc.right-rc.left;
  421.             m_cy=rc.bottom-rc.top;
  422.  
  423.             DestroyWindow(hDlg);
  424.             }
  425.         }
  426.  
  427.     return NOERROR;
  428.     }
  429.  
  430.  
  431.  
  432. /*
  433.  * CBeeperPropPage::Activate
  434.  *
  435.  * Purpose:
  436.  *  Instructs the property page to create a window in which to
  437.  *  display its contents, using the given parent window and
  438.  *  rectangle.  The window should be initially visible.
  439.  *
  440.  * Parameters:
  441.  *  hWndParent      HWND of the parent window.
  442.  *  prc             LPCRECT of the rectangle to use.
  443.  *  fModal          BOOL indicating whether the frame is modal.
  444.  */
  445.  
  446. STDMETHODIMP CBeeperPropPage::Activate(HWND hWndParent
  447.     , LPCRECT prc, BOOL fModal)
  448.     {
  449.     if (NULL!=m_hDlg)
  450.         return ResultFromScode(E_UNEXPECTED);
  451.  
  452.     m_hDlg=CreateDialogParam(m_hInst, MAKEINTRESOURCE(m_uIDTemplate)
  453.         , hWndParent, BeepPropPageProc, (LPARAM)this);
  454.  
  455.     if (NULL==m_hDlg)
  456.         return ResultFromScode(E_OUTOFMEMORY);
  457.  
  458.     //Move the page into position and show it.
  459.     SetWindowPos(m_hDlg, NULL, prc->left, prc->top
  460.         , prc->right-prc->left, prc->bottom-prc->top, 0);
  461.  
  462.     return NOERROR;
  463.     }
  464.  
  465.  
  466.  
  467. /*
  468.  * CBeeperPropPage::Deactivate
  469.  *
  470.  * Purpose:
  471.  *  Instructs the property page to destroy its window that was
  472.  *  created in Activate.
  473.  *
  474.  * Parameters:
  475.  *  None
  476.  */
  477.  
  478. STDMETHODIMP CBeeperPropPage::Deactivate(void)
  479.     {
  480.     if (NULL==m_hDlg)
  481.         return ResultFromScode(E_UNEXPECTED);
  482.  
  483.     DestroyWindow(m_hDlg);
  484.     m_hDlg=NULL;
  485.     return NOERROR;
  486.     }
  487.  
  488.  
  489.  
  490. /*
  491.  * CBeeperPropPage::GetPageInfo
  492.  *
  493.  * Purpose:
  494.  *  Fills a PROPPAGEINFO structure describing the page's size,
  495.  *  contents, and help information.
  496.  *
  497.  * Parameters:
  498.  *  pPageInfo       LPPROPPAGEINFO to the structure to fill.
  499.  */
  500.  
  501. STDMETHODIMP CBeeperPropPage::GetPageInfo(LPPROPPAGEINFO pPageInfo)
  502.     {
  503.     IMalloc     *pIMalloc;
  504.  
  505.     if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  506.         return ResultFromScode(E_FAIL);
  507.  
  508.     pPageInfo->pszTitle=(LPOLESTR)pIMalloc->Alloc(CCHSTRINGMAX);
  509.  
  510.     if (NULL!=pPageInfo->pszTitle)
  511.         {
  512.         UINT        ids=IDS_0_PAGETITLE;
  513.  
  514.         if (PRIMARYLANGID(m_lcid)==LANG_GERMAN)
  515.             ids=IDS_7_PAGETITLE;
  516.  
  517.        #ifdef WIN32ANSI
  518.         char        szTemp[80];
  519.  
  520.         LoadString(m_hInst, ids, szTemp, CCHSTRINGMAX);
  521.         MultiByteToWideChar(CP_ACP, 0, szTemp, -1
  522.            , pPageInfo->pszTitle, 80);
  523.        #else
  524.         LoadString(m_hInst, ids, pPageInfo->pszTitle, CCHSTRINGMAX);
  525.        #endif
  526.         }
  527.  
  528.     pIMalloc->Release();
  529.  
  530.     pPageInfo->size.cx      = m_cx;
  531.     pPageInfo->size.cy      = m_cy;
  532.     pPageInfo->pszDocString = NULL;
  533.     pPageInfo->pszHelpFile  = NULL;
  534.     pPageInfo->dwHelpContext= 0;
  535.     return NOERROR;
  536.     }
  537.  
  538.  
  539.  
  540. /*
  541.  * CBeeperPropPage::SetObjects
  542.  *
  543.  * Purpose:
  544.  *  Identifies the objects that are being affected by this property
  545.  *  page (and all other pages in the frame).  These are the object
  546.  *  to which to send new property values in the Apply member.
  547.  *
  548.  * Parameters:
  549.  *  cObjects        ULONG number of objects
  550.  *  ppUnk           IUnknown ** to the array of objects being
  551.  *                  passed to the page.
  552.  */
  553.  
  554. STDMETHODIMP CBeeperPropPage::SetObjects(ULONG cObjects
  555.     , IUnknown **ppUnk)
  556.     {
  557.     BOOL        fRet=TRUE;
  558.  
  559.     FreeAllObjects();
  560.  
  561.     if (0!=cObjects)
  562.         {
  563.         UINT        i;
  564.         HRESULT     hr;
  565.  
  566.         m_ppIBeeper=new IBeeper * [(UINT)cObjects];
  567.  
  568.         for (i=0; i < cObjects; i++)
  569.             {
  570.             hr=ppUnk[i]->QueryInterface(IID_IBeeper
  571.                 , (void **)&m_ppIBeeper[i]);
  572.  
  573.             if (FAILED(hr))
  574.                 fRet=FALSE;
  575.             }
  576.         }
  577.  
  578.     //If we didn't get one of our objects, fail this call.
  579.     if (!fRet)
  580.         return ResultFromScode(E_FAIL);
  581.  
  582.     m_cObjects=cObjects;
  583.     return NOERROR;
  584.     }
  585.  
  586.  
  587.  
  588. /*
  589.  * CBeeperPropPage::Show
  590.  *
  591.  * Purpose:
  592.  *  Instructs the page to show or hide its window created in
  593.  *  Activate.
  594.  *
  595.  * Parameters:
  596.  *  nCmdShow        UINT to pass to ShowWindow.
  597.  */
  598.  
  599. STDMETHODIMP CBeeperPropPage::Show(UINT nCmdShow)
  600.     {
  601.     if (NULL==m_hDlg)
  602.         ResultFromScode(E_UNEXPECTED);
  603.  
  604.     ShowWindow(m_hDlg, nCmdShow);
  605.  
  606.     //Take the focus
  607.     if (SW_SHOWNORMAL==nCmdShow || SW_SHOW==nCmdShow)
  608.         SetFocus(m_hDlg);
  609.  
  610.     return NOERROR;
  611.     }
  612.  
  613.  
  614.  
  615. /*
  616.  * CBeeperPropPage::Move
  617.  *
  618.  * Purpose:
  619.  *  Instructs the property page to change its position.
  620.  *
  621.  * Parameters:
  622.  *  prc             LPCRECT containing the new position.
  623.  */
  624.  
  625. STDMETHODIMP CBeeperPropPage::Move(LPCRECT prc)
  626.     {
  627.     SetWindowPos(m_hDlg, NULL, prc->left, prc->top
  628.         , prc->right-prc->left, prc->bottom-prc->top, 0);
  629.  
  630.     return NOERROR;
  631.     }
  632.  
  633.  
  634.  
  635. /*
  636.  * CBeeperPropPage::IsPageDirty
  637.  *
  638.  * Purpose:
  639.  *  Asks the page if anything's changed in it, that is, if the
  640.  *  property values in the page are out of sync with the objects
  641.  *  under consideration.
  642.  *
  643.  * Parameters:
  644.  *  None
  645.  *
  646.  * Return Value:
  647.  *  HRESULT         NOERROR if dirty, S_FALSE if not.
  648.  */
  649.  
  650. STDMETHODIMP CBeeperPropPage::IsPageDirty(void)
  651.     {
  652.     return ResultFromScode(m_fDirty ? S_OK : S_FALSE);
  653.     }
  654.  
  655.  
  656.  
  657.  
  658. /*
  659.  * CBeeperPropPage::Apply
  660.  *
  661.  * Purpose:
  662.  *  Instructs the page to send changes in its page to whatever
  663.  *  objects it knows about through SetObjects.  This is the only
  664.  *  time the page should change the objects' properties, and not
  665.  *  when the value is changed on the page.
  666.  *
  667.  * Parameters:
  668.  *  None
  669.  */
  670.  
  671. STDMETHODIMP CBeeperPropPage::Apply(void)
  672.     {
  673.     UINT        i;
  674.     UINT        lSound, lSoundNew;
  675.     BOOL        fChanged;
  676.  
  677.     if (0==m_cObjects)
  678.         return NOERROR;
  679.  
  680.     /*
  681.      * The dialog's last known Sound selection is in
  682.      * m_uIDLastSound, so we can just send it via
  683.      * IBeeper::put_Sound.  Since this method has no
  684.      * return value, we have to ask for it again to
  685.      * see if it really changed because the client may
  686.      * be blocking changes through IPropertyNotifySink,
  687.      * in which case we do not clear the dirty flag.
  688.      */
  689.  
  690.     lSound=(IDC_BEEPDEFAULT==m_uIDLastSound) ? 0L : m_uIDLastSound;
  691.     fChanged=TRUE;
  692.  
  693.     for (i=0; i < m_cObjects; i++)
  694.         {
  695.         m_ppIBeeper[i]->put_Sound(lSound);
  696.         lSoundNew=m_ppIBeeper[i]->get_Sound();
  697.  
  698.         fChanged &= (lSound==lSoundNew);
  699.         }
  700.  
  701.     m_fDirty=!fChanged;
  702.     return NOERROR;
  703.     }
  704.  
  705.  
  706.  
  707. /*
  708.  * CBeeperPropPage::Help
  709.  *
  710.  * Purpose:
  711.  *  Invokes help for this property page when the user presses
  712.  *  the Help button.  If you return NULLs for the help file
  713.  *  in GetPageInfo, the button will be grayed.  Otherwise the
  714.  *  page can perform its own help here.
  715.  *
  716.  * Parameters:
  717.  *  pszHelpDir      LPCOLESTR identifying the default location of
  718.  *                  the help information
  719.  *
  720.  * Return Value:
  721.  *  HRESULT         NOERROR to tell the frame that we've done our
  722.  *                  own help.  Returning an error code or S_FALSE
  723.  *                  causes the frame to use any help information
  724.  *                  in PROPPAGEINFO.
  725.  */
  726.  
  727. STDMETHODIMP CBeeperPropPage::Help(LPCOLESTR pszHelpDir)
  728.     {
  729.     /*
  730.      * We can either provide help ourselves, or rely on the
  731.      * information in PROPPAGEINFO.
  732.      */
  733.     return ResultFromScode(S_FALSE);
  734.     }
  735.  
  736.  
  737.  
  738.  
  739. /*
  740.  * CBeeperPropPage::TranslateAccelerator
  741.  *
  742.  * Purpose:
  743.  *  Provides the page with the messages that occur in the frame.
  744.  *  This gives the page to do whatever it wants with the message,
  745.  *  such as handle keyboard mnemonics.
  746.  *
  747.  * Parameters:
  748.  *  pMsg            LPMSG containing the keyboard message.
  749.  */
  750.  
  751. STDMETHODIMP CBeeperPropPage::TranslateAccelerator(LPMSG lpMsg)
  752.     {
  753.     //No keyboard interface supported here
  754.     return ResultFromScode(E_NOTIMPL);
  755.     }
  756.  
  757.  
  758.  
  759. /*
  760.  * BeepPropPageProc
  761.  *
  762.  * Purpose:
  763.  *  Dialog procedure for the Beeper Property Page.
  764.  */
  765.  
  766. BOOL APIENTRY BeepPropPageProc(HWND hDlg, UINT iMsg
  767.     , WPARAM wParam, LPARAM lParam)
  768.     {
  769.     PCBeeperPropPage    pObj;
  770.     WORD                wID;
  771.  
  772.    #ifdef WIN32
  773.     pObj=(PCBeeperPropPage)(ULONG)GetProp(hDlg, g_szObj);
  774.    #else
  775.     pObj=(PCBeeperPropPage)MAKELONG((WORD)GetProp(hDlg, g_szObjLo)
  776.        , (WORD)GetProp(hDlg, g_szObjHi));
  777.    #endif
  778.  
  779.     switch (iMsg)
  780.         {
  781.         case WM_INITDIALOG:
  782.             pObj=(PCBeeperPropPage)(ULONG)lParam;
  783.            #ifdef WIN32
  784.             SetProp(hDlg, g_szObj, (HANDLE)lParam);
  785.            #else
  786.             SetProp(hDlg, g_szObjHi, (HANDLE)HIWORD(lParam));
  787.             SetProp(hDlg, g_szObjLo, (HANDLE)LOWORD(lParam));
  788.            #endif
  789.  
  790.             if (NULL==pObj)
  791.                 return TRUE;
  792.  
  793.             SetFocus(GetDlgItem(hDlg, IDOK));
  794.  
  795.             /*
  796.              * If we have one object then we can try to set the
  797.              * right field in the dialog box.  Otherwise we could
  798.              * ask for the value from all of the objects and see
  799.              * if they all match.
  800.              */
  801.             if (1==pObj->m_cObjects)
  802.                 {
  803.                 UINT        iButton;
  804.  
  805.                 iButton=(UINT)pObj->m_ppIBeeper[0]->get_Sound();
  806.  
  807.                 if (0==iButton)
  808.                     iButton=IDC_BEEPDEFAULT;
  809.  
  810.                 CheckRadioButton(hDlg, IDC_BEEPDEFAULT
  811.                     , IDC_BEEPASTERISK, iButton);
  812.  
  813.                 pObj->m_uIDLastSound=iButton;
  814.                 }
  815.  
  816.             return FALSE;
  817.  
  818.         case WM_DESTROY:
  819.            #ifdef WIN32
  820.             RemoveProp(hDlg, g_szObj);
  821.            #else
  822.             RemoveProp(hDlg, g_szObjHi);
  823.             RemoveProp(hDlg, g_szObjLo);
  824.            #endif
  825.             return FALSE;
  826.  
  827.         case WM_COMMAND:
  828.             wID=LOWORD(wParam);
  829.  
  830.             switch (wID)
  831.                 {
  832.                 case IDC_BEEPDEFAULT:
  833.                 case IDC_BEEPHAND:
  834.                 case IDC_BEEPQUESTION:
  835.                 case IDC_BEEPEXCLAMATION:
  836.                 case IDC_BEEPASTERISK:
  837.                     if (NULL==pObj)
  838.                         break;
  839.  
  840.                     //Selecting the same one doesn't dirty
  841.                     if (pObj->m_uIDLastSound==wID)
  842.                         break;
  843.  
  844.                     //Save the most recently selected
  845.                     pObj->m_uIDLastSound=LOWORD(wParam);
  846.                     pObj->m_fDirty=TRUE;
  847.  
  848.                     if (NULL!=pObj->m_pIPropertyPageSite)
  849.                         {
  850.                         pObj->m_pIPropertyPageSite
  851.                             ->OnStatusChange(PROPPAGESTATUS_DIRTY);
  852.                         }
  853.  
  854.                     break;
  855.  
  856.  
  857.                 case IDOK:
  858.                     /*
  859.                      * We could call the object's Beep, but
  860.                      * as it's property page, we know what
  861.                      * it will do so we can just do it.
  862.                      */
  863.                     if (NULL!=pObj)
  864.                         MessageBeep(pObj->m_uIDLastSound);
  865.  
  866.                     break;
  867.                 }
  868.             break;
  869.         }
  870.     return FALSE;
  871.     }
  872.