?? beeper.cpp
字號:
* pExcepInfo EXCEPINFO * to exception information.
* puArgErr UINT * in which to store the index of an
* invalid parameter if DISP_E_TYPEMISMATCH
* is returned.
*
* Return Value:
* HRESULT NOERROR or a general error code.
*/
STDMETHODIMP CBeeper::Invoke(DISPID dispID, REFIID riid
, LCID lcid, unsigned short wFlags, DISPPARAMS *pDispParams
, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
HRESULT hr;
ITypeInfo *pTI;
LANGID langID=PRIMARYLANGID(lcid);
//riid is supposed to be IID_NULL always
if (IID_NULL!=riid)
return ResultFromScode(DISP_E_UNKNOWNINTERFACE);
//Get the ITypeInfo for lcid
hr=GetTypeInfo(0, lcid, &pTI);
if (FAILED(hr))
return hr;
#ifdef WIN32
//This saves the language ID for this thread
TlsSetValue(g_dwTLS, &langID);
#endif
//Clear exceptions
SetErrorInfo(0L, NULL);
//This is exactly what DispInvoke does--so skip the overhead.
hr=pTI->Invoke((IBeeper *)this, dispID, wFlags
, pDispParams, pVarResult, pExcepInfo, puArgErr);
//Exception handling is done within ITypeInfo::Invoke
pTI->Release();
return hr;
}
//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
*
* Out Parameters: (Get only):
* plSound long *, the current sound.
*/
STDMETHODIMP CBeeper::get_Sound(long *plSound)
{
if (NULL==plSound)
return ResultFromScode(E_POINTER);
*plSound=m_lSound;
return NOERROR;
}
STDMETHODIMP 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 our Exception
* function to raise them through the error info mechanism.
*/
Exception(EXCEPTION_INVALIDSOUND);
return ResultFromScode(DISP_E_EXCEPTION);
}
m_lSound=lSound;
return NOERROR;
}
/*
* CBeeper::Beep
*
* Purpose:
* Function called from DispInvoke to invoke the Beep method.
*
* Out Parameter:
* plSoundPlayed long *, the sound played.
*/
STDMETHODIMP CBeeper::Beep(long *plSoundPlayed)
{
if (NULL==plSoundPlayed)
return ResultFromScode(E_POINTER);
*plSoundPlayed=m_lSound;
MessageBeep((UINT)m_lSound);
return NOERROR;
}
/*
* CBeeper::Exception
*
* Purpose:
* Raises an exception for Invoke from within ITypeInfo::Invoke
* using the CreateErrorInfo API and the ICreateErrorInfo interface.
* This is part of CBeeper since CBeeper derives from IDispatch
* as well.
*
* Parameters:
* wException WORD exception code.
*/
void CBeeper::Exception(WORD wException)
{
HRESULT hr;
ICreateErrorInfo *pICreateErr;
BOOL fSuccess;
LPTSTR psz;
LPOLESTR pszHelp;
UINT idsSource;
UINT idsException;
DWORD dwHelpID;
LANGID langID=LANG_NEUTRAL;
#ifdef WIN32
LANGID *pLangID;
#endif
#ifdef WIN32
pLangID=(LANGID *)TlsGetValue(g_dwTLS);
if (NULL!=pLangID)
langID=*pLangID;
#endif
/*
* Thread-safe exception handling means that we call
* CreateErrorInfo which gives us an ICreateErrorInfo pointer
* that we then use to set the error information (basically
* to set the fields of an EXCEPINFO structure. We then
* call SetErrorInfo to attach this error to the current
* thread. ITypeInfo::Invoke will look for this when it
* returns from whatever function was invokes by calling
* GetErrorInfo.
*/
//Not much we can do if this fails.
if (FAILED(CreateErrorInfo(&pICreateErr)))
return;
psz=(LPTSTR)malloc(1024*sizeof(TCHAR));
if (NULL==psz)
{
pICreateErr->Release();
return;
}
fSuccess=FALSE;
switch (wException)
{
case EXCEPTION_INVALIDSOUND:
pICreateErr->SetGUID(IID_IBeeper);
dwHelpID=HID_SOUND_PROPERTY_LIMITATIONS;
pszHelp=OLETEXT("beep0000.hlp");
idsSource=IDS_0_EXCEPTIONSOURCE;
idsException=IDS_0_EXCEPTIONINVALIDSOUND;
switch (langID)
{
case LANG_GERMAN:
idsSource=IDS_7_EXCEPTIONSOURCE;
idsException=IDS_7_EXCEPTIONINVALIDSOUND;
pszHelp=OLETEXT("beep0007.hlp");
break;
case LANG_ENGLISH:
case LANG_NEUTRAL:
default:
break;
}
fSuccess=TRUE;
break;
default:
break;
}
if (fSuccess)
{
IErrorInfo *pIErr;
/*
* If you have a help file, call the functions
* ICreateErrorInfo::SetHelpFile and
* ICreateErrorInfo::SetHelpContext as well. If you
* set the help file to NULL the context is ignored.
*/
pICreateErr->SetHelpFile(pszHelp);
pICreateErr->SetHelpContext(dwHelpID);
#ifdef WIN32ANSI
OLECHAR szTemp[256];
LoadString(g_hInst, idsSource, psz, 256);
MultiByteToWideChar(CP_ACP, 0, psz, -1, szTemp, 256);
pICreateErr->SetSource(szTemp);
LoadString(g_hInst, idsException, psz, 256);
MultiByteToWideChar(CP_ACP, 0, psz, -1, szTemp, 256);
pICreateErr->SetDescription(szTemp);
#else
LoadString(g_hInst, idsSource, psz, 1024);
pICreateErr->SetSource(psz);
LoadString(g_hInst, idsException, psz, 1024);
pICreateErr->SetDescription(psz);
#endif
hr=pICreateErr->QueryInterface(IID_IErrorInfo
, (PPVOID)&pIErr);
if (SUCCEEDED(hr))
{
SetErrorInfo(0L, pIErr);
pIErr->Release();
}
}
free(psz);
//SetErrorInfo holds the object's IErrorInfo
pICreateErr->Release();
return;
}
//ISupportErrorInfo interface implementation
/*
* CImpISupportErrorInfo::CImpISupportErrorInfo
* CImpISupportErrorInfo::~CImpISupportErrorInfo
*
* Parameters (Constructor):
* pObj PCBeeper of the object we're in.
* pUnkOuter LPUNKNOWN to which we delegate.
*/
CImpISupportErrorInfo::CImpISupportErrorInfo(PCBeeper pObj
, LPUNKNOWN pUnkOuter)
{
m_cRef=0;
m_pObj=pObj;
m_pUnkOuter=pUnkOuter;
return;
}
CImpISupportErrorInfo::~CImpISupportErrorInfo(void)
{
return;
}
/*
* CImpISupportErrorInfo::QueryInterface
* CImpISupportErrorInfo::AddRef
* CImpISupportErrorInfo::Release
*
* Purpose:
* IUnknown members for CImpISupportErrorInfo object.
*/
STDMETHODIMP CImpISupportErrorInfo::QueryInterface(REFIID riid
, PPVOID ppv)
{
return m_pUnkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CImpISupportErrorInfo::AddRef(void)
{
++m_cRef;
return m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) CImpISupportErrorInfo::Release(void)
{
--m_cRef;
return m_pUnkOuter->Release();
}
/*
* CImpISupportErrorInfo::InterfaceSupportsErrorInfo
*
* Purpose:
* Informs a caller whether or not a specific interface
* supports exceptions through the Set/GetErrorInfo mechanism.
*
* Parameters:
* riid REFIID of the interface in question.
*
* Return Value:
* HRESULT NOERROR if a call to GetErrorInfo will succeed
* for callers of riid. S_FALSE if not.
*/
STDMETHODIMP CImpISupportErrorInfo::InterfaceSupportsErrorInfo
(REFIID riid)
{
if (IID_IBeeper==riid)
return NOERROR;
return ResultFromScode(S_FALSE);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -