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_