|
|
#include "cabinet.h"
#include "rcids.h"
#include <shguidp.h>
#include "bandsite.h"
#include "shellp.h"
#include "shdguid.h"
#include "taskband.h"
#include "taskbar.h"
#include <regstr.h>
#include "util.h"
#include "strsafe.h"
extern IStream *GetDesktopViewStream(DWORD grfMode, LPCTSTR pszName);
HRESULT PersistStreamLoad(IStream *pstm, IUnknown *punk); HRESULT PersistStreamSave(IStream *pstm, BOOL fClearDirty, IUnknown *punk);
const TCHAR c_szTaskbar[] = TEXT("Taskbar");
// {69B3F106-0F04-11d3-AE2E-00C04F8EEA99}
static const GUID CLSID_TrayBandSite = { 0x69b3f106, 0xf04, 0x11d3, { 0xae, 0x2e, 0x0, 0xc0, 0x4f, 0x8e, 0xea, 0x99 } };
// {8B4A02DB-97BB-4C1B-BE75-8827A7358CD0}
static const GUID CLSID_TipBand = { 0x8B4A02DB, 0x97BB, 0x4C1B, { 0xBE, 0x75, 0x88, 0x27, 0xA7, 0x35, 0x8C, 0xD0 } };
class CTrayBandSite : public IBandSite , public IClassFactory { public: // *** IUnknown ***
virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj); virtual STDMETHODIMP_(ULONG) AddRef(void) ; virtual STDMETHODIMP_(ULONG) Release(void);
// *** IBandSite methods ***
STDMETHOD(AddBand) (THIS_ IUnknown* punk); STDMETHOD(EnumBands) (THIS_ UINT uBand, DWORD* pdwBandID); STDMETHOD(QueryBand) (THIS_ DWORD dwBandID, IDeskBand** ppstb, DWORD* pdwState, LPWSTR pszName, int cchName) ; STDMETHOD(SetBandState) (THIS_ DWORD dwBandID, DWORD dwMask, DWORD dwState) ; STDMETHOD(RemoveBand) (THIS_ DWORD dwBandID); STDMETHOD(GetBandObject) (THIS_ DWORD dwBandID, REFIID riid, void ** ppvObj); STDMETHOD(SetBandSiteInfo) (THIS_ const BANDSITEINFO * pbsinfo); STDMETHOD(GetBandSiteInfo) (THIS_ BANDSITEINFO * pbsinfo);
// *** IClassFactory methods ***
HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj) { if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
return QueryInterface(riid, ppvObj); } HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) { return S_OK; } IContextMenu3* GetContextMenu(); void SetInner(IUnknown* punk); void SetLoaded(BOOL fLoaded) {_fLoaded = fLoaded;} BOOL HandleMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plres); protected: CTrayBandSite(); virtual ~CTrayBandSite();
BOOL _CreateBandSiteMenu(IUnknown* punk); HRESULT _AddRequiredBands(); void _BroadcastExec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut); HRESULT _SetWindowTheme(LPWSTR pwzTheme); friend IBandSite* BandSite_CreateView(); friend void BandSite_HandleDelayBootStuff(IUnknown* punk); friend void BandSite_Load(); friend HRESULT BandSite_SetWindowTheme(IBandSite* pbs, LPWSTR pwzTheme); LONG _cRef; IUnknown *_punkInner; IBandSite *_pbsInner;
// bandsite context menu
IContextMenu3* _pcm; HWND _hwnd; BOOL _fLoaded; BOOL _fDelayBootStuffHandled; DWORD _dwClassObject; WCHAR* _pwzTheme; };
CTrayBandSite* IUnknownToCTrayBandSite(IUnknown* punk) { CTrayBandSite* ptbs; punk->QueryInterface(CLSID_TrayBandSite, (void **)&ptbs); ASSERT(ptbs); punk->Release();
return ptbs; }
CTrayBandSite::CTrayBandSite() : _cRef(1) { }
CTrayBandSite::~CTrayBandSite() { if (_pcm) _pcm->Release();
if (_pwzTheme) delete[] _pwzTheme; return; }
ULONG CTrayBandSite::AddRef() { return InterlockedIncrement(&_cRef); }
ULONG CTrayBandSite::Release() { ASSERT( 0 != _cRef ); ULONG cRef = InterlockedDecrement(&_cRef); if ( 0 == cRef ) { _cRef = 1000; // guard against recursion
if (_pbsInner) { AddRef(); _pbsInner->Release(); } // this must come last
if (_punkInner) _punkInner->Release(); // paired w/ CCI aggregation
ASSERT(_cRef == 1000);
delete this; } return cRef; }
HRESULT CTrayBandSite::QueryInterface(REFIID riid, LPVOID * ppvObj) { static const QITAB qit[] = { QITABENT(CTrayBandSite, IBandSite), QITABENT(CTrayBandSite, IClassFactory), { 0 }, };
HRESULT hr = QISearch(this, qit, riid, ppvObj);
if (FAILED(hr) && IsEqualIID(riid, CLSID_TrayBandSite)) { *ppvObj = this; AddRef(); hr = S_OK; }
if (FAILED(hr) && _punkInner) { hr = _punkInner->QueryInterface(riid, ppvObj); }
return hr; }
static BOOL CALLBACK SetTransparency(HWND hwnd, LPARAM lParam) { SetWindowStyleEx(hwnd, WS_EX_TRANSPARENT, (BOOL)lParam);
return TRUE; }
// *** IBandSite methods ***
HRESULT CTrayBandSite::AddBand(IUnknown* punk) { CLSID clsid; HRESULT hr = S_OK;
if (!_fDelayBootStuffHandled) { //
// Tell the band to go into "delay init" mode. When the tray
// timer goes off we'll tell the band to finish up. (See
// BandSite_HandleDelayBootStuff).
//
IUnknown_Exec(punk, &CGID_DeskBand, DBID_DELAYINIT, 0, NULL, NULL); }
if (c_tray.GetIsNoToolbarsOnTaskbarPolicyEnabled()) { hr = IUnknown_GetClassID(punk, &clsid); if (SUCCEEDED(hr)) { hr = IsEqualGUID(clsid, CLSID_TaskBand) ? S_OK : E_FAIL; } }
if (SUCCEEDED(hr)) { hr = _pbsInner->AddBand(punk);
if (SUCCEEDED(hr)) { IShellFolderBand *pisfBand; HRESULT hrInner = punk->QueryInterface(IID_PPV_ARG(IShellFolderBand, &pisfBand)); if (SUCCEEDED(hrInner)) { BANDINFOSFB bi; bi.dwMask = ISFB_MASK_STATE; hrInner = pisfBand->GetBandInfoSFB(&bi); if (SUCCEEDED(hrInner)) { bi.dwState |= ISFB_STATE_BTNMINSIZE; hrInner = pisfBand->SetBandInfoSFB(&bi); } pisfBand->Release(); }
// tell the band to use the taskbar theme
if (_pwzTheme) { VARIANTARG var; var.vt = VT_BSTR; var.bstrVal = _pwzTheme; IUnknown_Exec(punk, &CGID_DeskBand, DBID_SETWINDOWTHEME, 0, &var, NULL); }
if (GetWindowLong(_hwnd, GWL_EXSTYLE) & WS_EX_TRANSPARENT) { EnumChildWindows(_hwnd, SetTransparency, (LPARAM)TRUE); } } }
return hr; }
HRESULT CTrayBandSite::EnumBands(UINT uBand, DWORD* pdwBandID) { return _pbsInner->EnumBands(uBand, pdwBandID); }
HRESULT CTrayBandSite::QueryBand(DWORD dwBandID, IDeskBand** ppstb, DWORD* pdwState, LPWSTR pszName, int cchName) { return _pbsInner->QueryBand(dwBandID, ppstb, pdwState, pszName, cchName); }
HRESULT CTrayBandSite::SetBandState(DWORD dwBandID, DWORD dwMask, DWORD dwState) { return _pbsInner->SetBandState(dwBandID, dwMask, dwState); }
HRESULT CTrayBandSite::RemoveBand(DWORD dwBandID) { return _pbsInner->RemoveBand(dwBandID); }
HRESULT CTrayBandSite::GetBandObject(DWORD dwBandID, REFIID riid, void ** ppvObj) { return _pbsInner->GetBandObject(dwBandID, riid, ppvObj); }
HRESULT CTrayBandSite::SetBandSiteInfo (const BANDSITEINFO * pbsinfo) { return _pbsInner->SetBandSiteInfo(pbsinfo); }
HRESULT CTrayBandSite::GetBandSiteInfo (BANDSITEINFO * pbsinfo) { return _pbsInner->GetBandSiteInfo(pbsinfo); }
HRESULT CTrayBandSite::_AddRequiredBands() { IDeskBand* pdb; HRESULT hr = CoCreateInstance(CLSID_TaskBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IDeskBand, &pdb)); if (SUCCEEDED(hr)) { hr = AddBand(pdb); pdb->Release(); }
return hr; }
HRESULT CTrayBandSite::_SetWindowTheme(LPWSTR pwzTheme) { if (_pwzTheme) { delete[] _pwzTheme; _pwzTheme = NULL; }
if (pwzTheme) { int cchLen = lstrlen(pwzTheme) + 1; _pwzTheme = new WCHAR[cchLen]; if (_pwzTheme) { StringCchCopy(_pwzTheme, cchLen, pwzTheme); } }
return S_OK; }
HRESULT BandSite_TestBandCLSID(IBandSite *pbs, DWORD idBand, REFIID riid) { HRESULT hr = E_FAIL; IPersist *pp; if (pbs) { hr = pbs->GetBandObject(idBand, IID_PPV_ARG(IPersist, &pp)); if (SUCCEEDED(hr)) { CLSID clsid; hr = pp->GetClassID(&clsid); if (SUCCEEDED(hr)) { hr = IsEqualGUID(clsid, riid) ? S_OK : S_FALSE; } pp->Release(); } } return hr; }
HRESULT BandSite_SetWindowTheme(IBandSite* pbs, LPWSTR pwzTheme) { HRESULT hr = E_FAIL;
if (pbs) { CTrayBandSite* ptbs = IUnknownToCTrayBandSite(pbs); if (ptbs) { ptbs->_SetWindowTheme(pwzTheme); }
DWORD dwBandID; BOOL fFound = FALSE; for (int i = 0; !fFound && SUCCEEDED(pbs->EnumBands(i, &dwBandID)); i++) { IUnknown* punk; HRESULT hrInner = pbs->GetBandObject(dwBandID, IID_PPV_ARG(IUnknown, &punk)); if (SUCCEEDED(hrInner)) { VARIANTARG var; var.vt = VT_BSTR; var.bstrVal = pwzTheme;
IUnknown_Exec(punk, &CGID_DeskBand, DBID_SETWINDOWTHEME, 0, &var, NULL); } } } return hr; }
HRESULT BandSite_FindBand(IBandSite* pbs, REFCLSID rclsid, REFIID riid, void **ppv, int *piCount, DWORD* pdwBandID) { HRESULT hr = E_FAIL;
int iCount = 0;
if (pbs) { DWORD dwBandID; for (int i = 0; SUCCEEDED(pbs->EnumBands(i, &dwBandID)); i++) { if (BandSite_TestBandCLSID(pbs, dwBandID, rclsid) == S_OK) { iCount++;
if (pdwBandID) { *pdwBandID = dwBandID; }
if (ppv) hr = pbs->GetBandObject(dwBandID, riid, ppv); else hr = S_OK; } } }
if (piCount) { *piCount = iCount; }
return hr; }
void BandSite_Initialize(IBandSite* pbs) { HWND hwnd = v_hwndTray; CTaskBar *pow = new CTaskBar(); if (pow) { IDeskBarClient* pdbc; if (SUCCEEDED(pbs->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pdbc)))) { // we need to set a dummy tray IOleWindow
pdbc->SetDeskBarSite(SAFECAST(pow, IOleWindow*)); pdbc->GetWindow(&hwnd); if (hwnd) { // taskbar windows are themed under Taskbar subapp name
SendMessage(hwnd, RB_SETWINDOWTHEME, 0, (LPARAM)c_wzTaskbarTheme); pow->_hwndRebar = hwnd; } pdbc->Release(); } pow->Release(); } }
IContextMenu3* CTrayBandSite::GetContextMenu() { if (!_pcm) { if (SUCCEEDED(CoCreateInstance(CLSID_BandSiteMenu, NULL,CLSCTX_INPROC_SERVER, IID_PPV_ARG(IContextMenu3, &_pcm)))) { IShellService* pss; if (SUCCEEDED(_pcm->QueryInterface(IID_PPV_ARG(IShellService, &pss)))) { pss->SetOwner(SAFECAST(this, IBandSite*)); pss->Release(); } } } if (_pcm) _pcm->AddRef(); return _pcm; }
HRESULT BandSite_AddMenus(IUnknown* punk, HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast) { HRESULT hr = E_FAIL;
CTrayBandSite* ptbs = IUnknownToCTrayBandSite(punk); IContextMenu3* pcm = ptbs->GetContextMenu(); if (pcm) { hr = pcm->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, CMF_ICM3); pcm->Release(); }
return hr; }
void BandSite_HandleMenuCommand(IUnknown* punk, UINT idCmd) { CTrayBandSite* ptbs = IUnknownToCTrayBandSite(punk); IContextMenu3* pcm = ptbs->GetContextMenu();
if (pcm) { CMINVOKECOMMANDINFOEX ici = { sizeof(CMINVOKECOMMANDINFOEX), 0L, NULL, (LPSTR)MAKEINTRESOURCE(idCmd), NULL, NULL, SW_NORMAL, };
pcm->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici); pcm->Release(); } }
void CTrayBandSite::SetInner(IUnknown* punk) { _punkInner = punk; _punkInner->QueryInterface(IID_PPV_ARG(IBandSite, &_pbsInner)); Release(); ASSERT(_pbsInner); }
IBandSite* BandSite_CreateView() { IUnknown *punk; HRESULT hr = E_FAIL;
// aggregate a TrayBandSite (from a RebarBandSite)
CTrayBandSite *ptbs = new CTrayBandSite; if (ptbs) { hr = CoCreateInstance(CLSID_RebarBandSite, (IBandSite*)ptbs, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IUnknown, &punk)); if (SUCCEEDED(hr)) { ptbs->SetInner(punk); // paired w/ Release in outer (TBS::Release)
BandSite_Initialize(ptbs); return SAFECAST(ptbs, IBandSite*); } else { delete ptbs; return NULL; } } return NULL; }
HRESULT BandSite_SaveView(IUnknown *pbs) { HRESULT hr = E_FAIL;
IStream *pstm = GetDesktopViewStream(STGM_WRITE, c_szTaskbar); if (pstm) { hr = PersistStreamSave(pstm, TRUE, pbs); pstm->Release(); }
return hr; }
BOOL CTrayBandSite::HandleMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plres) { if (!_hwnd) { IUnknown_GetWindow(SAFECAST(this, IBandSite*), &_hwnd); }
switch (uMsg) { case WM_INITMENUPOPUP: case WM_MEASUREITEM: case WM_DRAWITEM: case WM_MENUCHAR: if (_pcm) { _pcm->HandleMenuMsg2(uMsg, wParam, lParam, plres); return TRUE; } break;
case WM_NOTIFY: switch (((LPNMHDR)lParam)->code) { case NM_NCHITTEST: { NMMOUSE *pnm = (LPNMMOUSE)lParam; if (_hwnd == pnm->hdr.hwndFrom) { if (pnm->dwHitInfo == RBHT_CLIENT || pnm->dwItemSpec == -1) { if (plres) *plres = HTTRANSPARENT; } return TRUE; } } break;
case RBN_MINMAX: *plres = SHRestricted(REST_NOMOVINGBAND); return TRUE; } break; } IWinEventHandler *pweh; if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IWinEventHandler, &pweh)))) { HRESULT hr = pweh->OnWinEvent(hwnd, uMsg, wParam, lParam, plres); pweh->Release(); return SUCCEEDED(hr); } ASSERT(0); // we know we support IWinEventHandler
return FALSE; }
void CTrayBandSite::_BroadcastExec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvarargIn, VARIANTARG *pvarargOut) { // Broadcast an Exec to all child bands
DWORD dwBandID; UINT uBand = 0; while (SUCCEEDED(EnumBands(uBand, &dwBandID))) { IOleCommandTarget* pct; if (SUCCEEDED(GetBandObject(dwBandID, IID_PPV_ARG(IOleCommandTarget, &pct)))) { pct->Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvarargIn, pvarargOut); pct->Release(); } uBand++; } }
void BandSite_HandleDelayBootStuff(IUnknown* punk) { if (punk) { CTrayBandSite* pbs = IUnknownToCTrayBandSite(punk); pbs->_fDelayBootStuffHandled = TRUE; pbs->_BroadcastExec(&CGID_DeskBand, DBID_FINISHINIT, 0, NULL, NULL); } }
// returns true or false whether it handled it
BOOL BandSite_HandleMessage(IUnknown *punk, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plres) { if (punk) { CTrayBandSite* pbs = IUnknownToCTrayBandSite(punk); return pbs->HandleMessage(hwnd, uMsg, wParam, lParam, plres); } return FALSE; }
void BandSite_SetMode(IUnknown *punk, DWORD dwMode) { IBandSite* pbs = (IBandSite*)punk; if (pbs) { IDeskBarClient *pdbc; if (SUCCEEDED(pbs->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pdbc)))) { pdbc->SetModeDBC(dwMode); pdbc->Release(); } } }
void BandSite_Update(IUnknown *punk) { IBandSite* pbs = (IBandSite*)punk; if (pbs) { IOleCommandTarget *pct; if (SUCCEEDED(pbs->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &pct)))) { pct->Exec(&CGID_DeskBand, DBID_BANDINFOCHANGED, 0, NULL, NULL); pct->Release(); } } }
void BandSite_UIActivateDBC(IUnknown *punk, DWORD dwState) { IBandSite* pbs = (IBandSite*)punk; if (pbs) { IDeskBarClient *pdbc; if (SUCCEEDED(pbs->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pdbc)))) { pdbc->UIActivateDBC(dwState); pdbc->Release(); } } }
//*** PersistStreamLoad, PersistStreamSave
// NOTES
// we don't insist on finding IPersistStream iface; absence of it is
// assumed to mean there's nothing to init.
HRESULT PersistStreamLoad(IStream *pstm, IUnknown *punk) { IPersistStream *pps; HRESULT hr = punk->QueryInterface(IID_PPV_ARG(IPersistStream, &pps)); if (SUCCEEDED(hr)) { hr = pps->Load(pstm); pps->Release(); } else hr = S_OK; // n.b. S_OK not hr (don't insist on IID_IPS)
return hr; }
HRESULT PersistStreamSave(IStream *pstm, BOOL fClearDirty, IUnknown *punk) { HRESULT hr = E_FAIL; if (punk) { hr = S_OK;// n.b. S_OK not hr (don't insist on IID_IPS)
IPersistStream *pps; if (SUCCEEDED(punk->QueryInterface(IID_PPV_ARG(IPersistStream, &pps)))) { hr = pps->Save(pstm, fClearDirty); pps->Release(); } } return hr; }
HRESULT IUnknown_SimulateDrop(IUnknown* punk, IDataObject* pdtobj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { HRESULT hr = E_FAIL; if (punk) { IDropTarget* pdt; hr = punk->QueryInterface(IID_PPV_ARG(IDropTarget, &pdt)); if (SUCCEEDED(hr)) { hr = pdt->DragEnter(pdtobj, grfKeyState, pt, pdwEffect); if (*pdwEffect) { hr = pdt->Drop(pdtobj, grfKeyState, pt, pdwEffect); } else { pdt->DragLeave(); } pdt->Release(); } }
return hr; }
LRESULT BandSite_OnMarshallBS(WPARAM wParam, LPARAM lParam) { GUID *riid = (GUID *) wParam; IStream *pstm = NULL;
// paired w/ matching Unmarshal in shdocvw (TM_MARSHALBS)
HRESULT hr = CoMarshalInterThreadInterfaceInStream(*riid, c_tray._ptbs, &pstm); ASSERT(SUCCEEDED(hr));
return (LRESULT) pstm; }
IStream *GetDesktopViewStream(DWORD grfMode, LPCTSTR pszName) { HKEY hkStreams;
ASSERT(g_hkeyExplorer);
if (RegCreateKey(g_hkeyExplorer, TEXT("Streams"), &hkStreams) == ERROR_SUCCESS) { IStream *pstm = OpenRegStream(hkStreams, TEXT("Desktop"), pszName, grfMode); RegCloseKey(hkStreams); return pstm; } return NULL; }
BOOL Reg_GetString(HKEY hkey, LPCTSTR pszSubKey, LPCTSTR pszValue, LPTSTR psz, DWORD cb) { BOOL fRet = FALSE; if (!g_fCleanBoot) { fRet = ERROR_SUCCESS == SHGetValue(hkey, pszSubKey, pszValue, NULL, psz, &cb); } return fRet; }
void BandSite_Load() { CTrayBandSite* ptbs = IUnknownToCTrayBandSite(c_tray._ptbs); HRESULT hr = E_FAIL; // 1st, try persisted state
IStream *pstm = GetDesktopViewStream(STGM_READ, c_szTaskbar); if (pstm) { hr = PersistStreamLoad(pstm, (IBandSite*)ptbs); pstm->Release(); }
// 2nd, if there is none (or if version mismatch or other failure),
// try settings from setup
if (FAILED(hr)) { LPTSTR pszValue; if (IsOS(OS_PERSONAL) || IsOS(OS_PROFESSIONAL) || SHRestricted(REST_CLASSICSHELL)) { // use the no-quick-launch stream
pszValue = TEXT("Default Taskbar (Personal)"); } else { pszValue = TEXT("Default Taskbar"); }
// n.b. HKLM not HKCU
// like GetDesktopViewStream but for HKLM
pstm = OpenRegStream(HKEY_LOCAL_MACHINE, REGSTR_PATH_EXPLORER TEXT("\\Streams\\Desktop"), pszValue, STGM_READ);
if (pstm) { hr = PersistStreamLoad(pstm, (IBandSite *)ptbs); pstm->Release(); } }
// o.w., throw up our hands and force some hard-coded defaults
// this is needed for a) unexpected failures; b) debug bootstrap;
int iCount = 0; DWORD dwBandID; if (FAILED(hr) || FAILED(BandSite_FindBand(ptbs, CLSID_TaskBand, CLSID_NULL, NULL, &iCount, &dwBandID))) { //
// note that for the CheckBands case, we're assuming that
// a) AddBands adds only the missing guys (for now there's
// only 1 [TaskBand] so we're ok); and b) AddBands doesn't
// create dups if only some are missing (again for now there's
// only 1 so no pblm)
ptbs->_AddRequiredBands(); }
hr = BandSite_FindBand(ptbs, CLSID_TaskBand, CLSID_NULL, NULL, &iCount, &dwBandID); while ((iCount > 1) && SUCCEEDED(hr)) { ptbs->RemoveBand(dwBandID); hr = BandSite_FindBand(ptbs, CLSID_TaskBand, CLSID_NULL, NULL, &iCount, &dwBandID); }
// And one more: this is needed for the TipBand deskband for the TabletPC.
iCount = 0; if (FAILED(hr) || FAILED(BandSite_FindBand(ptbs, CLSID_TipBand, CLSID_NULL, NULL, &iCount, &dwBandID))) { IDeskBand* pdb; HRESULT hr = CoCreateInstance(CLSID_TipBand, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IDeskBand, &pdb)); if (SUCCEEDED(hr)) { hr = ptbs->AddBand(pdb); pdb->Release(); } } hr = BandSite_FindBand(ptbs, CLSID_TipBand, CLSID_NULL, NULL, &iCount, &dwBandID); while ((iCount > 1) && SUCCEEDED(hr)) { ptbs->RemoveBand(dwBandID); hr = BandSite_FindBand(ptbs, CLSID_TipBand, CLSID_NULL, NULL, &iCount, &dwBandID); }
ptbs->SetLoaded(TRUE); }
HRESULT CTrayBandSiteService_CreateInstance(IUnknown* punkOuter, IUnknown** ppunk) { if (punkOuter) return CLASS_E_NOAGGREGATION;
if (c_tray._ptbs) { *ppunk = c_tray._ptbs; c_tray._ptbs->AddRef(); return S_OK; }
return E_OUTOFMEMORY; }
|