UNKNOWN.H
//******************************************************************************************* 
// 
// Filename : Unknown.h 
// 
//Definitions for some customized routines 
// 
// Copyright 1994 - 1998 Microsoft Corporation. All rights reserved 
// 
//******************************************************************************************* 
 
 
#ifndef _UNKNOWN_H_ 
#define _UNKNOWN_H_ 
 
class CUnknown 
{ 
public: 
CUnknown() {} 
virtual ~CUnknown();// virtual destructor called from Release 
 
HRESULT QIHelper(REFIID riid, LPVOID *ppvObj, const IID *apiid[], LPUNKNOWN aobj[]); 
ULONG AddRefHelper(); 
ULONG ReleaseHelper(); 
 
private: 
CRefCount m_cRef; 
CRefDll m_cRefDll; 
} ; 
 
// Only for ensuring Release in all control paths 
class CEnsureRelease 
{ 
public: 
CEnsureRelease(IUnknown *pUnk) : m_pUnk(pUnk) {} 
~CEnsureRelease() {if (m_pUnk) m_pUnk->Release();} 
 
operator IUnknown*() {return(m_pUnk);} 
 
void Attach(IUnknown *pUnk) {m_pUnk = pUnk;} 
 
private: 
IUnknown *m_pUnk; 
} ; 
 
class CObjTemp 
{ 
public: 
CObjTemp() : m_hObj(0) {} 
~CObjTemp() {} 
 
operator HANDLE() const {return(m_hObj);} 
 
HANDLE Attach(HANDLE hObjNew) {HANDLE hObj=m_hObj; m_hObj=hObjNew; return(hObj);} 
HANDLE Detach() {return(Attach(0));} 
 
protected: 
HANDLE m_hObj; 
} ; 
 
class CMenuTemp : public CObjTemp 
{ 
public: 
CMenuTemp() : CObjTemp() {} 
CMenuTemp(HMENU hm) : CObjTemp() {Attach(hm);} 
~CMenuTemp() {if (m_hObj) DestroyMenu(Detach());} 
 
operator HMENU() const {return((HMENU)m_hObj);} 
 
HMENU Attach(HMENU hObjNew) {return((HMENU)CObjTemp::Attach((HANDLE)hObjNew));} 
HMENU Detach() {return((HMENU)CObjTemp::Detach());} 
 
BOOL CreatePopupMenu() {Attach(::CreatePopupMenu()); return(m_hObj!=NULL);} 
} ; 
 
class CGotGlobal : public CObjTemp 
{ 
public: 
CGotGlobal(HGLOBAL hData, IUnknown *pUnk) : m_erData(pUnk) {Attach(hData);} 
~CGotGlobal() {if (!(IUnknown*)m_erData) GlobalFree(m_hObj);} 
 
private: 
CEnsureRelease m_erData; 
} ; 
 
class CHIDA : public CGotGlobal 
{ 
public: 
CHIDA(HGLOBAL hIDA, IUnknown *pUnk) : CGotGlobal(hIDA, pUnk) 
{ 
m_lpIDA = (LPIDA)GlobalLock(hIDA); 
} 
~CHIDA() {GlobalUnlock(m_hObj);} 
 
LPCITEMIDLIST operator [](UINT nIndex) 
{ 
if (!m_lpIDA || nIndex>m_lpIDA->cidl) 
{ 
return(NULL); 
} 
 
return((LPCITEMIDLIST)(((LPSTR)m_lpIDA)+m_lpIDA->aoffset[nIndex])); 
} 
 
int GetCount() {return(m_lpIDA ? m_lpIDA->cidl : 0);} 
 
private: 
LPIDA m_lpIDA; 
} ; 
 
#endif // _UNKNOWN_H_