//==============================================================; // // This source code is only intended as a supplement to // existing Microsoft documentation. // // // // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. // // // //==============================================================; #include #include "DataObj.h" #include "Space.h" #include "Comp.h" const GUID CSpaceFolder::thisGuid = { 0x29743810, 0x4c4b, 0x11d2, { 0x89, 0xd8, 0x0, 0x0, 0x21, 0x47, 0x31, 0x28 } }; const GUID CSpaceStation::thisGuid = { 0x62273a12, 0x1914, 0x11d3, { 0x9a, 0x38, 0x0, 0x80, 0xc7, 0x25, 0x80, 0x72 } }; const GUID CRocket::thisGuid = { 0x29743811, 0x4c4b, 0x11d2, { 0x89, 0xd8, 0x0, 0x0, 0x21, 0x47, 0x31, 0x28 } }; //============================================================== // // CSpaceFolder implementation // // CSpaceFolder::CSpaceFolder() { for (int n = 0; n < NUMBER_OF_CHILDREN; n++) { children[n] = new CSpaceStation(); } } CSpaceFolder::~CSpaceFolder() { for (int n = 0; n < NUMBER_OF_CHILDREN; n++) if (children[n]) { delete children[n]; } } HRESULT CSpaceFolder::OnExpand(IConsoleNameSpace *pConsoleNameSpace, IConsole *pConsole, HSCOPEITEM parent) { SCOPEDATAITEM sdi; if (!bExpanded) { // create the child nodes, then expand them for (int n = 0; n < NUMBER_OF_CHILDREN; n++) { ZeroMemory(&sdi, sizeof(SCOPEDATAITEM) ); sdi.mask = SDI_STR | // Displayname is valid SDI_PARAM | // lParam is valid SDI_IMAGE | // nImage is valid SDI_OPENIMAGE | // nOpenImage is valid SDI_PARENT | SDI_CHILDREN; sdi.relativeID = (HSCOPEITEM)parent; sdi.nImage = children[n]->GetBitmapIndex(); sdi.nOpenImage = INDEX_OPENFOLDER; sdi.displayname = MMC_CALLBACK; sdi.lParam = (LPARAM)children[n]; // The cookie sdi.cChildren = 0; HRESULT hr = pConsoleNameSpace->InsertItem( &sdi ); _ASSERT( SUCCEEDED(hr) ); children[n]->SetHandle((HANDLE)sdi.ID); } } return S_OK; } //============================================================== // // CSpaceStation implementation // // CSpaceStation::CSpaceStation() : m_cChildSpaceStations(0) { for (int n = 0; n < MAX_CHILDREN; n++) { children[n] = NULL; } for (n = 0; n < NUMBER_OF_CHILDREN; n++) { children[n] = new CRocket(this, _T("Rocket"), n, 350115, 320, 52300); } } CSpaceStation::~CSpaceStation() { for (int n = 0; n < MAX_CHILDREN; n++) if (children[n]) { delete children[n]; } } HRESULT CSpaceStation::Expand(IConsoleNameSpace *pConsoleNameSpace) { //Expand the CSpaceStation if necessary. //This method is called by the object's OnPaste method during paste operations. HRESULT hr = S_FALSE; //First, need the IConsoleNameSpace2 interface to call Expand. IConsoleNameSpace2 *pConsoleNamespace2 = NULL; hr = pConsoleNameSpace->QueryInterface(IID_IConsoleNameSpace2, (void **)&pConsoleNamespace2); _ASSERT( SUCCEEDED(hr) ); hr = pConsoleNamespace2->Expand((HSCOPEITEM)GetHandle()); pConsoleNamespace2->Release(); return hr; } HRESULT CSpaceStation::GetResultViewType(LPOLESTR *ppViewType, long *pViewOptions) { return S_FALSE; } HRESULT CSpaceStation::OnShow(IConsole *pConsole, BOOL bShow, HSCOPEITEM scopeitem) { HRESULT hr = S_OK; IHeaderCtrl *pHeaderCtrl = NULL; IResultData *pResultData = NULL; if (bShow) { hr = pConsole->QueryInterface(IID_IHeaderCtrl, (void **)&pHeaderCtrl); _ASSERT( SUCCEEDED(hr) ); hr = pConsole->QueryInterface(IID_IResultData, (void **)&pResultData); _ASSERT( SUCCEEDED(hr) ); // Set the column headers in the results pane hr = pHeaderCtrl->InsertColumn( 0, L"Rocket Class", 0, MMCLV_AUTO ); _ASSERT( S_OK == hr ); hr = pHeaderCtrl->InsertColumn( 1, L"Rocket Weight", 0, MMCLV_AUTO ); _ASSERT( S_OK == hr ); hr = pHeaderCtrl->InsertColumn( 2, L"Rocket Height", 0, MMCLV_AUTO ); _ASSERT( S_OK == hr ); hr = pHeaderCtrl->InsertColumn( 3, L"Rocket Payload", 0, MMCLV_AUTO ); _ASSERT( S_OK == hr ); hr = pHeaderCtrl->InsertColumn( 4, L"Status", 0, MMCLV_AUTO ); _ASSERT( S_OK == hr ); // insert items here RESULTDATAITEM rdi; hr = pResultData->DeleteAllRsltItems(); _ASSERT( SUCCEEDED(hr) ); if (!bExpanded) { // create the child nodes, then expand them for (int n = 0; n < MAX_CHILDREN; n++) { if (NULL == children[n]) //No more children to insert, so exit for loop break; BOOL childDeleteStatus = children[n]->getDeletedStatus(); if ( !childDeleteStatus) { ZeroMemory(&rdi, sizeof(RESULTDATAITEM) ); rdi.mask = RDI_STR | // Displayname is valid RDI_IMAGE | RDI_PARAM; // nImage is valid rdi.nImage = children[n]->GetBitmapIndex(); rdi.str = MMC_CALLBACK; rdi.nCol = 0; rdi.lParam = (LPARAM)children[n]; hr = pResultData->InsertItem( &rdi ); _ASSERT( SUCCEEDED(hr) ); children[n]->SetHandle((HANDLE)rdi.itemID); } } } pHeaderCtrl->Release(); pResultData->Release(); } return hr; } HRESULT CSpaceStation::OnSelect(IConsole *pConsole, BOOL bScope, BOOL bSelect) { IConsoleVerb *pConsoleVerb; HRESULT hr = pConsole->QueryConsoleVerb(&pConsoleVerb); _ASSERT(SUCCEEDED(hr)); hr = pConsoleVerb->SetVerbState(MMC_VERB_CUT, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_CUT, HIDDEN, FALSE); hr = pConsoleVerb->SetVerbState(MMC_VERB_COPY, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_COPY, HIDDEN, FALSE); hr = pConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, FALSE); hr = pConsoleVerb->SetVerbState(MMC_VERB_PASTE, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_PASTE, HIDDEN, FALSE); pConsoleVerb->Release(); return S_OK; } HRESULT CSpaceStation::OnPaste(IConsole *pConsole, CComponentData *pComponentData, CDelegationBase *pPasted) { CRocket *pRocket = dynamic_cast(pPasted); HRESULT hr = S_OK; if (NULL == pRocket) { // See if this is CSpaceStation, if so paste it into this item. // This sample simply creates a new CSpaceStation // and inserts it as a child of the destination of the paste. // It does not paste the cut/copied CSpaceStation and the // current state of its result items. CSpaceStation* pSpaceStn = dynamic_cast(pPasted); if ( (NULL != pSpaceStn) && (pSpaceStn != this) ) { // Regardless of whether this item is expanded or not // always try to expand this scopeitem (so that paste can // succeed). hr = Expand(pComponentData->GetConsoleNameSpace()); CSpaceStation* pNewStation = new CSpaceStation(); SCOPEDATAITEM sdi; ZeroMemory(&sdi, sizeof(SCOPEDATAITEM) ); sdi.mask = SDI_STR| // Displayname is valid SDI_PARAM | // lParam is valid SDI_IMAGE | // nImage is valid SDI_OPENIMAGE | // nOpenImage is valid SDI_PARENT | SDI_CHILDREN; sdi.relativeID = (HSCOPEITEM)GetHandle(); sdi.nImage = pNewStation->GetBitmapIndex(); sdi.nOpenImage = INDEX_OPENFOLDER; sdi.displayname = MMC_CALLBACK; sdi.lParam = (LPARAM)pNewStation; // The cookie sdi.cChildren = 0; hr = pComponentData->GetConsoleNameSpace()->InsertItem( &sdi ); _ASSERT( SUCCEEDED(hr) ); pNewStation->SetHandle((HANDLE)sdi.ID); } //increment count of child space stations m_cChildSpaceStations++; return hr; } if (pRocket->m_pSpaceStation == this) return S_FALSE; //Create a new CRocket for the destination CSpaceStation CRocket *myRocket = new CRocket(pRocket->m_pSpaceStation, pRocket->szName, pRocket->nId, pRocket->lWeight, pRocket->lHeight, pRocket->lPayload); for (int n = 0; n < MAX_CHILDREN; n++) { if (NULL == children[n]) { // put it here children[n] = myRocket; children[n]->isDeleted = FALSE; children[n]->nId = n; children[n]->m_pSpaceStation = this; return S_OK; } } return S_FALSE; } HRESULT CSpaceStation::OnQueryPaste(CDelegationBase *pPasted) { CRocket *pRocket = dynamic_cast(pPasted); if (NULL == pRocket) { // See if this is CSpaceStation. CSpaceStation* pSpaceStn = dynamic_cast(pPasted); if ( (NULL != pSpaceStn) && (pSpaceStn != this) ) { return S_OK; } return S_FALSE; } if (pRocket->m_pSpaceStation != this) for (int n = 0; n < MAX_CHILDREN; n++) { if (NULL == children[n]) { return S_OK; } } return S_FALSE; } HRESULT CSpaceStation::OnUpdateItem(IConsole *pConsole, long item, ITEM_TYPE itemtype) { HRESULT hr = S_OK; _ASSERT(item); _ASSERT(SCOPE == itemtype); //refresh all result pane views hr = pConsole->SelectScopeItem( (HSCOPEITEM)item ); _ASSERT( S_OK == hr); return hr; } HRESULT CSpaceStation::OnDeleteScopeItem (IConsoleNameSpace *pConsoleNameSpace) { HRESULT hr = S_FALSE; HSCOPEITEM hCutItem = (HSCOPEITEM)GetHandle(); //Get handle and cookie of parent scope item. We need these to //remove the "+" sign if the parent's m_cChildSpaceStations goes to zero. HSCOPEITEM hParentItem; MMC_COOKIE cookieParentItem; HRESULT hr1 = pConsoleNameSpace->GetParentItem(hCutItem, &hParentItem, (long *)&cookieParentItem); //Delete the cut item hr = pConsoleNameSpace->DeleteItem(hCutItem, TRUE); _ASSERT(S_OK == hr); if (SUCCEEDED(hr1)) { //Decrement parent's m_cChildSpaceStations count and //remove "+" sign if necessary CSpaceStation* pParentSpaceStn = reinterpret_cast(cookieParentItem); pParentSpaceStn->DecrementCountChildSpaceStations(); if ( !pParentSpaceStn->GetCountChildSpaceStations() ) { SCOPEDATAITEM sdi; ZeroMemory(&sdi, sizeof(SCOPEDATAITEM) ); sdi.mask = SDI_CHILDREN; //cChildren is valid sdi.ID = (HSCOPEITEM)hParentItem; sdi.cChildren = 0; hr = pConsoleNameSpace->SetItem( &sdi ); _ASSERT( SUCCEEDED(hr) ); } } return hr; } //============================================================== // // CRocket implementation // // CRocket::CRocket(CSpaceStation *pSpaceStation, _TCHAR *szName, int id, LONG lWeight, LONG lHeight, LONG lPayload) : m_pSpaceStation(pSpaceStation), szName(NULL), lWeight(0), lHeight(0), lPayload(0), iStatus(STOPPED) { if (szName) { this->szName = new _TCHAR[(_tcslen(szName) + 1) * sizeof(_TCHAR)]; _tcscpy(this->szName, szName); } this->nId = id; this->lWeight = lWeight; this->lHeight = lHeight; this->lPayload = lPayload; isDeleted = FALSE; } CRocket::~CRocket() { if (szName) delete [] szName; } const _TCHAR *CRocket::GetDisplayName(int nCol) { static _TCHAR buf[128]; switch (nCol) { case 0: _stprintf(buf, _T("%s (#%d)"), szName ? szName : _T(""), nId); break; case 1: _stprintf(buf, _T("%ld metric tons"), lWeight); break; case 2: _stprintf(buf, _T("%ld meters"), lHeight); break; case 3: _stprintf(buf, _T("%ld kilos"), lPayload); break; case 4: _stprintf(buf, _T("%s"), iStatus == RUNNING ? _T("running") : iStatus == PAUSED ? _T("paused") : iStatus == STOPPED ? _T("stopped") : _T("unknown")); break; } return buf; } HRESULT CRocket::OnSelect(IConsole *pConsole, BOOL bScope, BOOL bSelect) { IConsoleVerb *pConsoleVerb; HRESULT hr = pConsole->QueryConsoleVerb(&pConsoleVerb); _ASSERT(SUCCEEDED(hr)); hr = pConsoleVerb->SetVerbState(MMC_VERB_RENAME, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_CUT, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_COPY, ENABLED, TRUE); hr = pConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, TRUE); pConsoleVerb->Release(); return S_OK; } HRESULT CRocket::OnRefresh(IConsole *pConsole) { //Call IConsole::UpdateAllViews to redraw all views //owned by the parent scope item IDataObject *pDummy = NULL; HANDLE handle = m_pSpaceStation->GetHandle(); HRESULT hr; hr = pConsole->UpdateAllViews(pDummy, (long)handle, UPDATE_SCOPEITEM); _ASSERT( S_OK == hr); return hr; } HRESULT CRocket::OnDelete(IConsole *pConsole) { _ASSERT( NULL != this ); HRESULT hr = S_OK; //Delete the item. The IConsole that is passed into DeleteChild //is from the child result item, so we can use it to QI for IResultData IResultData *pResultData = NULL; hr = pConsole->QueryInterface(IID_IResultData, (void **)&pResultData); _ASSERT( SUCCEEDED(hr) ); HRESULTITEM childresultitem; _ASSERT( NULL != &childresultitem ); //lparam == this. See CSpaceStation::OnShow hr = pResultData->FindItemByLParam( (LPARAM)this, &childresultitem ); _ASSERT( SUCCEEDED(hr) ); hr = pResultData->DeleteItem( childresultitem, 0 ); _ASSERT( SUCCEEDED(hr) ); pResultData->Release(); //Now set child's isDeleted member to true so that the parent doesn't try to //to insert it again in CSpaceVehicle::OnShow. Admittedly, a hack... isDeleted = TRUE; return hr; } HRESULT CRocket::OnRename(LPOLESTR pszNewName) { HRESULT hr = S_FALSE; if (szName) { delete [] szName; szName = NULL; } MAKE_TSTRPTR_FROMWIDE(ptrname, pszNewName); szName = new _TCHAR[(_tcslen(ptrname) + 1) * sizeof(_TCHAR)]; _tcscpy(szName, ptrname); return hr; } HRESULT CRocket::OnUpdateItem(IConsole *pConsole, long item, ITEM_TYPE itemtype) { HRESULT hr = S_FALSE; _ASSERT(NULL != this || isDeleted || RESULT == itemtype); //redraw the item IResultData *pResultData = NULL; hr = pConsole->QueryInterface(IID_IResultData, (void **)&pResultData); _ASSERT( SUCCEEDED(hr) ); HRESULTITEM myhresultitem; _ASSERT(NULL != &myhresultitem); //lparam == this. See CSpaceStation::OnShow hr = pResultData->FindItemByLParam( (LPARAM)this, &myhresultitem ); if ( FAILED(hr) ) { //there is no HRESULTITEM for the item, because //the item is not inserted in the current view. Exit gracefully hr = S_FALSE; } else { hr = pResultData->UpdateItem( myhresultitem ); _ASSERT( SUCCEEDED(hr) ); } pResultData->Release(); return hr; }