540 lines
15 KiB
C++
540 lines
15 KiB
C++
// toolbar.cpp : Implementation of toolbars for snapin
|
|
|
|
#include "stdafx.h"
|
|
#include "cookie.h"
|
|
#include "cmponent.h"
|
|
#include "compdata.h"
|
|
#include "dataobj.h"
|
|
|
|
#include <compuuid.h> // UUIDs for Computer Management
|
|
|
|
#include "macros.h"
|
|
USE_HANDLE_MACROS("FILEMGMT(toolbar.cpp)")
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
// We keep the strings in globals because multiple IComponents will all
|
|
// have their own IToolbars. We do not keep the bitmaps in globals because
|
|
// of difficulties with the global destruction mechanism, see compdata.h.
|
|
|
|
// The MMCBUTTON structures contain resource IDs for the strings which will
|
|
// be loaded into the CString array when the first instance of the toolbar
|
|
// is loaded.
|
|
//
|
|
// CODEWORK We need a mechanism to free these strings.
|
|
|
|
MMCBUTTON g_FileMgmtSnapinButtons[] =
|
|
{
|
|
{ 0, IDS_BUTTON_NEWSHARE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
|
|
};
|
|
CString* g_astrFileMgmtButtonStrings = NULL; // dynamic array of CStrings
|
|
BOOL g_bLoadedFileMgmtStrings = FALSE;
|
|
|
|
MMCBUTTON g_SvcMgmtSnapinButtons[] =
|
|
{
|
|
// The first button will be either Start or Resume.
|
|
// One of these two entries will be removed later.
|
|
{ 0, cmServiceResume, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
|
|
{ 0, cmServiceStart, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
|
|
{ 1, cmServiceStop, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
|
|
{ 2, cmServicePause, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
|
|
{ 3, cmServiceRestart, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
|
|
};
|
|
CString* g_astrSvcMgmtButtonStrings = NULL; // dynamic array of CStrings
|
|
BOOL g_bLoadedSvcMgmtStrings = FALSE;
|
|
|
|
|
|
void LoadButtonArray(
|
|
MMCBUTTON* pButtonArray,
|
|
BOOL* pbLoadedStrings,
|
|
CString** pastrStringArray,
|
|
UINT cButtons
|
|
)
|
|
{
|
|
ASSERT( NULL != pbLoadedStrings &&
|
|
NULL != pButtonArray &&
|
|
NULL != pastrStringArray);
|
|
|
|
if ( !*pbLoadedStrings )
|
|
{
|
|
// load strings
|
|
MMCBUTTON* pLoadButtonArray = pButtonArray;
|
|
UINT cLoadButtons = cButtons;
|
|
*pastrStringArray = new CString[2*cButtons];
|
|
for (UINT i = 0; i < cButtons; i++)
|
|
{
|
|
UINT iButtonTextId = 0, iTooltipTextId = 0;
|
|
|
|
switch (pButtonArray[i].idCommand)
|
|
{
|
|
case IDS_BUTTON_NEWSHARE:
|
|
iButtonTextId = IDS_BUTTON_NEWSHARE;
|
|
iTooltipTextId = IDS_TOOLTIP_NEWSHARE;
|
|
break;
|
|
case cmServiceResume:
|
|
iButtonTextId = IDS_BUTTON_SERVICE_RESUME;
|
|
iTooltipTextId = IDS_TOOLTIP_SERVICE_RESUME;
|
|
break;
|
|
case cmServiceStart:
|
|
iButtonTextId = IDS_BUTTON_SERVICE_START;
|
|
iTooltipTextId = IDS_TOOLTIP_SERVICE_START;
|
|
break;
|
|
case cmServiceStop:
|
|
iButtonTextId = IDS_BUTTON_SERVICE_STOP;
|
|
iTooltipTextId = IDS_TOOLTIP_SERVICE_STOP;
|
|
break;
|
|
case cmServicePause:
|
|
iButtonTextId = IDS_BUTTON_SERVICE_PAUSE;
|
|
iTooltipTextId = IDS_TOOLTIP_SERVICE_PAUSE;
|
|
break;
|
|
case cmServiceRestart:
|
|
iButtonTextId = IDS_BUTTON_SERVICE_RESTART;
|
|
iTooltipTextId = IDS_TOOLTIP_SERVICE_RESTART;
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
|
|
VERIFY( (*pastrStringArray)[i*2].LoadString(iButtonTextId) );
|
|
pButtonArray[i].lpButtonText =
|
|
const_cast<BSTR>((LPCTSTR)((*pastrStringArray)[i*2]));
|
|
|
|
VERIFY( (*pastrStringArray)[(i*2)+1].LoadString(iTooltipTextId) );
|
|
pButtonArray[i].lpTooltipText =
|
|
const_cast<BSTR>((LPCTSTR)((*pastrStringArray)[(i*2)+1]));
|
|
}
|
|
|
|
*pbLoadedStrings = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT LoadToolbar(
|
|
LPTOOLBAR pToolbar,
|
|
CBitmap& refbitmap,
|
|
MMCBUTTON* pButtonArray,
|
|
UINT cButtons
|
|
)
|
|
{
|
|
ASSERT( NULL != pToolbar &&
|
|
NULL != pButtonArray );
|
|
|
|
HRESULT hr = pToolbar->AddBitmap(cButtons, refbitmap, 16, 16, RGB(255,0,255) );
|
|
if ( FAILED(hr) )
|
|
{
|
|
ASSERT(FALSE);
|
|
return hr;
|
|
}
|
|
|
|
hr = pToolbar->AddButtons(cButtons, pButtonArray);
|
|
if ( FAILED(hr) )
|
|
{
|
|
ASSERT(FALSE);
|
|
return hr;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CFileMgmtComponent::SetControlbar(LPCONTROLBAR pControlbar)
|
|
{
|
|
MFC_TRY;
|
|
|
|
SAFE_RELEASE(m_pControlbar); // just in case
|
|
|
|
if (NULL != pControlbar)
|
|
{
|
|
m_pControlbar = pControlbar; // CODEWORK should use smartpointer
|
|
m_pControlbar->AddRef();
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
MFC_CATCH;
|
|
}
|
|
|
|
STDMETHODIMP CFileMgmtComponent::ControlbarNotify(MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
|
|
{
|
|
MFC_TRY;
|
|
|
|
#ifdef SNAPIN_PROTOTYPER
|
|
return S_OK;
|
|
#endif
|
|
|
|
HRESULT hr=S_OK;
|
|
|
|
switch (event)
|
|
{
|
|
|
|
case MMCN_BTN_CLICK:
|
|
TRACE(_T("CFileMgmtComponent::ControlbarNotify - MMCN_BTN_CLICK\n"));
|
|
{
|
|
LPDATAOBJECT pDataObject = reinterpret_cast<LPDATAOBJECT>(arg);
|
|
UINT idButton = (UINT)param;
|
|
hr = OnToolbarButton( pDataObject, idButton );
|
|
}
|
|
break;
|
|
|
|
case MMCN_SELECT:
|
|
TRACE(_T("CFileMgmtComponent::ControlbarNotify - MMCN_SELECT\n"));
|
|
{
|
|
if (!(LOWORD(arg))) // bScope
|
|
{
|
|
// result pane
|
|
hr = UpdateToolbar(
|
|
reinterpret_cast<LPDATAOBJECT>(param),
|
|
!!(HIWORD(arg)) );
|
|
}
|
|
else
|
|
{
|
|
// scope pane
|
|
hr = AddToolbar( reinterpret_cast<LPDATAOBJECT>(param),
|
|
!!(HIWORD(arg)) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE); // Unhandled event
|
|
}
|
|
|
|
return hr;
|
|
|
|
MFC_CATCH;
|
|
}
|
|
|
|
HRESULT CFileMgmtComponent::ServiceToolbarButtonState(
|
|
LPDATAOBJECT pServiceDataObject,
|
|
BOOL fSelected )
|
|
{
|
|
BOOL rgfMenuFlags[iServiceActionMax];
|
|
for (INT i = 0; i < iServiceActionMax; i++)
|
|
rgfMenuFlags[i] = FALSE;
|
|
|
|
if ( fSelected )
|
|
{
|
|
CString strMachineName;
|
|
CString strServiceName;
|
|
if (!QueryComponentDataRef().Service_FGetServiceInfoFromIDataObject(
|
|
pServiceDataObject,
|
|
OUT &strMachineName,
|
|
OUT &strServiceName,
|
|
NULL))
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
else
|
|
{
|
|
if (strMachineName.IsEmpty())
|
|
strMachineName = g_strLocalMachine;
|
|
|
|
// Get the menu flags
|
|
{
|
|
ASSERT(NULL != QueryComponentDataRef().m_hScManager);
|
|
CWaitCursor wait;
|
|
if (!Service_FGetServiceButtonStatus( // this will report errors itself
|
|
QueryComponentDataRef().m_hScManager,
|
|
strServiceName,
|
|
OUT rgfMenuFlags,
|
|
NULL, // pdwCurrentState
|
|
TRUE)) // fSilentError
|
|
{
|
|
// let's not do this m_hScManager = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update toolbar
|
|
ASSERT( NULL != m_pSvcMgmtToolbar );
|
|
//
|
|
// JonN 5/2/00 106431:
|
|
// Services snapin calls DeleteButton with an index but never called InsertButton
|
|
//
|
|
// HRESULT hr = m_pSvcMgmtToolbar->DeleteButton(0);
|
|
// if ( FAILED(hr) )
|
|
// return hr;
|
|
HRESULT hr = S_OK;
|
|
|
|
// JonN 3/15/01 210065
|
|
// Services snapin: "Resume service" toolbar button stays enabled after it is first displayed
|
|
BOOL fShowResumeButton = !rgfMenuFlags[iServiceActionStart] &&
|
|
rgfMenuFlags[iServiceActionResume];
|
|
VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServiceStart, HIDDEN, fShowResumeButton)));
|
|
VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServiceResume, HIDDEN, !fShowResumeButton)));
|
|
VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServiceStart, ENABLED, rgfMenuFlags[iServiceActionStart])));
|
|
VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServiceResume, ENABLED, rgfMenuFlags[iServiceActionResume])));
|
|
|
|
hr = m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServiceStop, ENABLED, rgfMenuFlags[iServiceActionStop] );
|
|
if ( FAILED(hr) )
|
|
return hr;
|
|
hr = m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServicePause, ENABLED, rgfMenuFlags[iServiceActionPause] );
|
|
if ( FAILED(hr) )
|
|
return hr;
|
|
hr = m_pSvcMgmtToolbar->SetButtonState(
|
|
cmServiceRestart, ENABLED, rgfMenuFlags[iServiceActionRestart] );
|
|
return hr;
|
|
}
|
|
|
|
// CODEWORK The following algorithm is imperfect, but will do
|
|
// for now. We ignore the old selection, and attach
|
|
// our fixed toolbar iff the new selection is our type.
|
|
HRESULT CFileMgmtComponent::AddToolbar(LPDATAOBJECT pdoScopeIsSelected,
|
|
BOOL fSelected)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
int i = 0;
|
|
GUID guidSelectedObject;
|
|
do { // false loop
|
|
if (NULL == pdoScopeIsSelected)
|
|
{
|
|
// toolbar will be automatically detached
|
|
return S_OK;
|
|
}
|
|
|
|
if ( FAILED(ExtractObjectTypeGUID(pdoScopeIsSelected,
|
|
&guidSelectedObject)) )
|
|
{
|
|
ASSERT(FALSE); // shouldn't have given me non-MMC data object
|
|
return S_OK;
|
|
}
|
|
if (NULL == m_pControlbar)
|
|
{
|
|
ASSERT(FALSE);
|
|
return S_OK;
|
|
}
|
|
#ifdef DEBUG
|
|
if ( QueryComponentDataRef().IsExtendedNodetype(guidSelectedObject) )
|
|
{
|
|
ASSERT(FALSE && "shouldn't have given me extension parent nodetype");
|
|
return S_OK;
|
|
}
|
|
#endif
|
|
|
|
switch (CheckObjectTypeGUID( &guidSelectedObject ) )
|
|
{
|
|
case FILEMGMT_SHARES:
|
|
if (QueryComponentDataRef().GetIsSimpleUI() || IsServiceSnapin())
|
|
break;
|
|
if (NULL == m_pFileMgmtToolbar)
|
|
{
|
|
hr = m_pControlbar->Create(
|
|
TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pFileMgmtToolbar) );
|
|
if ( FAILED(hr) )
|
|
{
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
ASSERT(NULL != m_pFileMgmtToolbar);
|
|
if ( !QueryComponentDataRef().m_fLoadedFileMgmtToolbarBitmap )
|
|
{
|
|
VERIFY( QueryComponentDataRef().m_bmpFileMgmtToolbar.LoadBitmap(
|
|
IDB_FILEMGMT_TOOLBAR ) );
|
|
QueryComponentDataRef().m_fLoadedFileMgmtToolbarBitmap = TRUE;
|
|
}
|
|
LoadButtonArray(
|
|
g_FileMgmtSnapinButtons,
|
|
&g_bLoadedFileMgmtStrings,
|
|
&g_astrFileMgmtButtonStrings,
|
|
ARRAYLEN(g_FileMgmtSnapinButtons)
|
|
);
|
|
hr = LoadToolbar(
|
|
m_pFileMgmtToolbar,
|
|
QueryComponentDataRef().m_bmpFileMgmtToolbar,
|
|
g_FileMgmtSnapinButtons,
|
|
ARRAYLEN(g_FileMgmtSnapinButtons)
|
|
);
|
|
}
|
|
if (FAILED(hr))
|
|
break;
|
|
// New Share is always enabled
|
|
VERIFY( SUCCEEDED(m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pFileMgmtToolbar)) );
|
|
for (i = 0; i < ARRAYLEN(g_FileMgmtSnapinButtons); i++) {
|
|
m_pFileMgmtToolbar->SetButtonState(
|
|
g_FileMgmtSnapinButtons[i].idCommand,
|
|
ENABLED,
|
|
fSelected);
|
|
}
|
|
break;
|
|
case FILEMGMT_SERVICES:
|
|
if ( !IsServiceSnapin() )
|
|
break;
|
|
if (NULL == m_pSvcMgmtToolbar)
|
|
{
|
|
hr = m_pControlbar->Create(
|
|
TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pSvcMgmtToolbar) );
|
|
if ( FAILED(hr) )
|
|
{
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
ASSERT(NULL != m_pSvcMgmtToolbar);
|
|
if ( !QueryComponentDataRef().m_fLoadedSvcMgmtToolbarBitmap )
|
|
{
|
|
VERIFY( QueryComponentDataRef().m_bmpSvcMgmtToolbar.LoadBitmap(
|
|
IDB_SVCMGMT_TOOLBAR ) );
|
|
QueryComponentDataRef().m_fLoadedSvcMgmtToolbarBitmap = TRUE;
|
|
}
|
|
LoadButtonArray(
|
|
g_SvcMgmtSnapinButtons,
|
|
&g_bLoadedSvcMgmtStrings,
|
|
&g_astrSvcMgmtButtonStrings,
|
|
ARRAYLEN(g_SvcMgmtSnapinButtons)
|
|
);
|
|
// JonN 3/15/01 210065
|
|
// "Resume service" toolbar button stays enabled after it is first displayed
|
|
hr = LoadToolbar(
|
|
m_pSvcMgmtToolbar,
|
|
QueryComponentDataRef().m_bmpSvcMgmtToolbar,
|
|
g_SvcMgmtSnapinButtons,
|
|
ARRAYLEN(g_SvcMgmtSnapinButtons)
|
|
);
|
|
}
|
|
if (FAILED(hr))
|
|
break;
|
|
VERIFY( SUCCEEDED(m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvcMgmtToolbar)) );
|
|
break;
|
|
case FILEMGMT_ROOT:
|
|
case FILEMGMT_SESSIONS:
|
|
case FILEMGMT_RESOURCES:
|
|
if (m_pControlbar && m_pFileMgmtToolbar)
|
|
{
|
|
m_pControlbar->Detach(m_pFileMgmtToolbar);
|
|
}
|
|
break;
|
|
|
|
#ifdef SNAPIN_PROTOTYPER
|
|
case FILEMGMT_PROTOTYPER:
|
|
break; // no toolbar
|
|
case FILEMGMT_PROTOTYPER_LEAF:
|
|
break; // no toolbar
|
|
#endif
|
|
|
|
default:
|
|
ASSERT(FALSE); // unknown type
|
|
break;
|
|
}
|
|
} while (FALSE); // false loop
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CFileMgmtComponent::UpdateToolbar(
|
|
LPDATAOBJECT pdoResultIsSelected,
|
|
BOOL fSelected )
|
|
{
|
|
int i = 0;
|
|
GUID guidSelectedObject;
|
|
HRESULT hr = S_OK;
|
|
BOOL bMultiSelectObject = IsMultiSelectObject(pdoResultIsSelected);
|
|
if (bMultiSelectObject)
|
|
{
|
|
//
|
|
// pdoResultIsSelected is the composite data object (MMC_MS_DO) created by MMC.
|
|
// We need to crack it to retrieve the multiselect data object (SI_MS_DO)
|
|
// we provided to MMC in QueryDataObject().
|
|
//
|
|
IDataObject *piSIMSDO = NULL;
|
|
hr = GetSnapinMultiSelectDataObject(pdoResultIsSelected, &piSIMSDO);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CFileMgmtDataObject *pDataObj = NULL;
|
|
hr = ExtractData(piSIMSDO, CFileMgmtDataObject::m_CFInternal, &pDataObj, sizeof(pDataObj));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// get the internal list of data objects of selected items, operate on one of them.
|
|
//
|
|
CDataObjectList* pMultiSelectObjList = pDataObj->GetMultiSelectObjList();
|
|
ASSERT(!pMultiSelectObjList->empty());
|
|
hr = ExtractObjectTypeGUID(*(pMultiSelectObjList->begin()), &guidSelectedObject);
|
|
}
|
|
|
|
piSIMSDO->Release();
|
|
}
|
|
} else
|
|
{
|
|
hr = ExtractObjectTypeGUID(pdoResultIsSelected, &guidSelectedObject);
|
|
}
|
|
|
|
if (FAILED(hr)) // shouldn't have given me non-MMC data object
|
|
return hr;
|
|
|
|
int objecttype = CheckObjectTypeGUID( &guidSelectedObject );
|
|
|
|
switch (objecttype)
|
|
{
|
|
case FILEMGMT_SERVICE:
|
|
ServiceToolbarButtonState( pdoResultIsSelected, fSelected );
|
|
break;
|
|
case FILEMGMT_SHARES:
|
|
if (m_pControlbar && m_pFileMgmtToolbar && !QueryComponentDataRef().GetIsSimpleUI())
|
|
{
|
|
m_pControlbar->Attach(TOOLBAR, m_pFileMgmtToolbar);
|
|
for (i = 0; i < ARRAYLEN(g_FileMgmtSnapinButtons); i++) {
|
|
m_pFileMgmtToolbar->SetButtonState(
|
|
g_FileMgmtSnapinButtons[i].idCommand,
|
|
ENABLED,
|
|
fSelected);
|
|
}
|
|
}
|
|
break;
|
|
case FILEMGMT_SHARE:
|
|
case FILEMGMT_SESSIONS:
|
|
case FILEMGMT_RESOURCES:
|
|
if (m_pControlbar && m_pFileMgmtToolbar)
|
|
{
|
|
m_pControlbar->Detach(m_pFileMgmtToolbar);
|
|
}
|
|
case FILEMGMT_SESSION:
|
|
case FILEMGMT_RESOURCE:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CFileMgmtComponent::OnToolbarButton(LPDATAOBJECT pDataObject, UINT idButton)
|
|
{
|
|
switch (idButton)
|
|
{
|
|
case IDS_BUTTON_NEWSHARE:
|
|
{
|
|
BOOL fRefresh = QueryComponentDataRef().NewShare( pDataObject );
|
|
if (fRefresh)
|
|
{
|
|
// JonN 12/03/98 updated to use new method
|
|
VERIFY(SUCCEEDED( RefreshAllViews(pDataObject) ));
|
|
}
|
|
}
|
|
break;
|
|
case cmServiceStart:
|
|
case cmServiceStop:
|
|
case cmServicePause:
|
|
case cmServiceResume:
|
|
case cmServiceRestart:
|
|
VERIFY( SUCCEEDED(Command(idButton, pDataObject)) );
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
return S_OK;
|
|
}
|