📄 beeper.cpp
字号:
/*
* BEEPER.CPP
* Beeper Object #6 with Property Pages Chapter 16
*
* Implementation of the CBeeper class which supports property
* pages through ISpecifyPropertyPages and data binding through
* IPropertyNotifySink. See also CONNPT.CPP for connection
* point business.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "beeper.h"
extern HINSTANCE g_hInst;
/*
* CBeeper::CBeeper
* CBeeper::~CBeeper
*
* Parameters (Constructor):
* pUnkOuter LPUNKNOWN of a controlling unknown.
* pfnDestroy PFNDESTROYED to call when an object
* is destroyed.
*/
CBeeper::CBeeper(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy)
{
m_cRef=0;
m_pUnkOuter=pUnkOuter;
m_pfnDestroy=pfnDestroy;
m_lSound=0;
m_pImpIDispatch=NULL;
//CHPATER16MOD
m_pImpISpecifyPP=NULL;
m_pImpIConnPtCont=NULL;
//Connection point
m_pIPropNotifySink=NULL;
m_pConnPt=NULL;
//End CHAPTER16MOD
return;
}
CBeeper::~CBeeper(void)
{
//CHAPTER16MOD
DeleteInterfaceImp(m_pImpIConnPtCont);
DeleteInterfaceImp(m_pImpISpecifyPP );
ReleaseInterface(m_pConnPt);
//End CHAPTER16MOD
DeleteInterfaceImp(m_pImpIDispatch);
return;
}
/*
* CBeeper::Init
*
* Purpose:
* Performs any intiailization of a CBeeper that's prone to failure
* that we also use internally before exposing the object outside.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if the function is successful,
* FALSE otherwise.
*/
BOOL CBeeper::Init(void)
{
LPUNKNOWN pIUnknown=this;
if (NULL!=m_pUnkOuter)
pIUnknown=m_pUnkOuter;
m_pImpIDispatch=new CImpIDispatch(this, pIUnknown);
if (NULL==m_pImpIDispatch)
return FALSE;
//CHAPTER16MOD
m_pImpISpecifyPP=new CImpISpecifyPP(this, pIUnknown);
if (NULL==m_pImpISpecifyPP)
return FALSE;
m_pImpIConnPtCont=new CImpIConnPtCont(this, pIUnknown);
if (NULL==m_pImpIConnPtCont)
return FALSE;
m_pConnPt=new CConnectionPoint(this);
if (NULL==m_pConnPt)
return FALSE;
m_pConnPt->AddRef(); //Reversed in destructor
//End CHAPTER16MOD
return TRUE;
}
/*
* CBeeper::QueryInterface
* CBeeper::AddRef
* CBeeper::Release
*/
STDMETHODIMP CBeeper::QueryInterface(REFIID riid, PPVOID ppv)
{
*ppv=NULL;
if (IID_IUnknown==riid || IID_IBeeper==riid)
*ppv=this;
if (IID_IDispatch==riid || DIID_DIBeeper==riid)
*ppv=m_pImpIDispatch;
//CHAPTER16MOD
if (IID_ISpecifyPropertyPages==riid)
*ppv=m_pImpISpecifyPP;
if (IID_IConnectionPointContainer==riid)
*ppv=m_pImpIConnPtCont;
//End CHAPTER16MOD
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CBeeper::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CBeeper::Release(void)
{
if (0L!=--m_cRef)
return m_cRef;
if (NULL!=m_pfnDestroy)
(*m_pfnDestroy)();
delete this;
return 0L;
}
//IBeeper interface functions
/*
* CBeeper::get_Sound
* CBeeper::put_Sound
*
* Purpose:
* Functions called from DispInvoke to handle the Sound property.
*
* Parameters (Set only):
* lSound long, new sound to save after validation
*
* Return Value: (Get only):
* long Current sound.
*/
STDMETHODIMP_(long) CBeeper::get_Sound(void)
{
return m_lSound;
}
STDMETHODIMP_(void) CBeeper::put_Sound(long lSound)
{
if (MB_OK!=lSound && MB_ICONEXCLAMATION!=lSound
&& MB_ICONQUESTION!=lSound && MB_ICONHAND!=lSound
&& MB_ICONASTERISK!=lSound)
{
/*
* Since we cannot return a value to ITypeInfo::Invoke to
* indicate an exception condition, we'll use
* m_pImpIDispatch->Exception to raise them. Before
* CImpIDispatch::Invoke calls ITypeInfo::Invoke, it clears
* the exception. CImpIDispatch::Exception sets an
* exception, so when ITypeInfo::Invoke returns, our Invoke
* can store exception information as necessary.
*/
m_pImpIDispatch->Exception(EXCEPTION_INVALIDSOUND);
return;
}
//CHAPTER16MOD
/*
* We marked the "Sound" property as bindable and as
* requestedit in our type information, so we have to
* call any sink's OnRequestEdit first, and if that
* succeeds with S_OK then we have to call OnChanged.
*/
if (NULL!=m_pIPropNotifySink)
{
//If we didn't get permission, stop now
if (NOERROR!=m_pIPropNotifySink->OnRequestEdit(PROPERTY_SOUND))
return;
}
//End CHAPTER16MOD
m_lSound=lSound;
//CHAPTER16MOD
if (NULL!=m_pIPropNotifySink)
m_pIPropNotifySink->OnChanged(PROPERTY_SOUND);
//End CHAPTER16MOD
return;
}
/*
* CBeeper::Beep
*
* Purpose:
* Function called from DispInvoke to invoke the Beep method.
*
* Return Value:
* long The sound played.
*/
STDMETHODIMP_(long) CBeeper::Beep(void)
{
MessageBeep((UINT)m_lSound);
return m_lSound;
}
//CHAPTER16MOD
//ISpecifyPropertyPages interface implementation
/*
* CImpISpecifyPP::CImpISpecifyPP
* CImpISpecifyPP::~CImpISpecifyPP
*
* Parameters (Constructor):
* pObj PCBeeper of the object we're in.
* pUnkOuter LPUNKNOWN to which we delegate.
*/
CImpISpecifyPP::CImpISpecifyPP(PCBeeper pObj, LPUNKNOWN pUnkOuter)
{
m_cRef=0;
m_pObj=pObj;
m_pUnkOuter=pUnkOuter;
return;
}
CImpISpecifyPP::~CImpISpecifyPP(void)
{
return;
}
/*
* CImpISpecifyPP::QueryInterface
* CImpISpecifyPP::AddRef
* CImpISpecifyPP::Release
*/
STDMETHODIMP CImpISpecifyPP::QueryInterface(REFIID riid
, LPVOID *ppv)
{
return m_pUnkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CImpISpecifyPP::AddRef(void)
{
++m_cRef;
return m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) CImpISpecifyPP::Release(void)
{
--m_cRef;
return m_pUnkOuter->Release();
}
/*
* CImpISpecifyPP::GetPages
*
* Purpose:
* Returns an array of GUIDs identifying the indivudual property
* pages used for this object.
*
* Parameters:
* pPages CAUUID * pointing to a counted array of GUIDs.
* This function allocates the array elements
* and stores them in this structure.
*/
STDMETHODIMP CImpISpecifyPP::GetPages(CAUUID *pPages)
{
IMalloc *pIMalloc;
GUID *pGUID;
pPages->cElems=0;
pPages->pElems=NULL;
if (FAILED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
return ResultFromScode(E_OUTOFMEMORY);
pGUID=(GUID *)pIMalloc->Alloc(CPROPPAGES*sizeof(GUID));
if (NULL!=pGUID)
{
//Fill the array now that we allocated it.
pGUID[0]=CLSID_BeeperPropertyPage;
//Fill the structure and return.
pPages->cElems=CPROPPAGES;
pPages->pElems=pGUID;
}
pIMalloc->Release();
return (NULL!=pGUID) ? NOERROR
: ResultFromScode(E_OUTOFMEMORY);
}
//End CHAPTER16MOD
//IDispatch interface implementation
/*
* CImpIDispatch::CImpIDispatch
* CImpIDispatch::~CImpIDispatch
*
* Parameters (Constructor):
* pObj PCBeeper of the object we're in.
* pUnkOuter LPUNKNOWN to which we delegate.
*/
CImpIDispatch::CImpIDispatch(PCBeeper pObj, LPUNKNOWN pUnkOuter)
{
m_cRef=0;
m_pObj=pObj;
m_pUnkOuter=pUnkOuter;
//These are created as needed in GetTypeInfo
m_pITINeutral=NULL;
m_pITIGerman=NULL;
return;
}
CImpIDispatch::~CImpIDispatch(void)
{
ReleaseInterface(m_pITIGerman);
ReleaseInterface(m_pITINeutral);
return;
}
/*
* CImpIDispatch::QueryInterface
* CImpIDispatch::AddRef
* CImpIDispatch::Release
*
* Purpose:
* IUnknown members for CImpIDispatch object.
*/
STDMETHODIMP CImpIDispatch::QueryInterface(REFIID riid, PPVOID ppv)
{
return m_pUnkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CImpIDispatch::AddRef(void)
{
++m_cRef;
return m_pUnkOuter->AddRef();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -