// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved //*************************************************************************** // // (c) 1996, 1997 by Microsoft Corporation // // hmmvctl.cpp // // This file contains the implementation of the main view container as well // as the generic view. // // a-larryf 17-Sept-96 Created. // //*************************************************************************** #include "precomp.h" #include #include #include "hmmv.h" #include "HmmvCtl.h" #include "HmmvPpg.h" #include "utils.h" #include "resource.h" #include "titlebar.h" #include "globals.h" #include "filters.h" #include "mv.h" #include "vwstack.h" #include "sv.h" #include "PolyView.h" #include "hmomutil.h" #include "htmlhelp.h" #include #include "wbemRegistry.h" #include "coloredt.h" #include "DlgHelpBox.h" #include "DlgExecQuery.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CGenericViewContext::~CGenericViewContext() { if (m_psv!=NULL && m_lContextHandle != NULL) { m_psv->ReleaseContext(m_lContextHandle); } } #define GENERIC_VIEW_INDEX 0 #define CY_TAB_FONT 15 #define CX_VIEW_DEFAULT_LEFT_MARGIN 8 #define CX_VIEW_DEFAULT_RIGHT_MARGIN 8 #define CY_VIEW_DEFAULT_TOP_MARGIN 8 #define CY_VIEW_DEFAULT_BOTTOM_MARGIN 8 #define CY_TITLE_DEFAULT_TOP_MARGIN 4 IMPLEMENT_DYNCREATE(CWBEMViewContainerCtrl, COleControl) ///////////////////////////////////////////////////////////////////////////// // Message map BEGIN_MESSAGE_MAP(CWBEMViewContainerCtrl, COleControl) ON_WM_CONTEXTMENU() //{{AFX_MSG_MAP(CWBEMViewContainerCtrl) ON_WM_SIZE() ON_WM_CREATE() ON_WM_DESTROY() ON_COMMAND(ID_CMD_SHOW_OBJECT_ATTRIBUTES, OnCmdShowObjectAttributes) ON_WM_SETFOCUS() ON_WM_KILLFOCUS() ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit) ON_WM_ERASEBKGND() //}}AFX_MSG_MAP ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Dispatch map BEGIN_DISPATCH_MAP(CWBEMViewContainerCtrl, COleControl) //{{AFX_DISPATCH_MAP(CWBEMViewContainerCtrl) DISP_PROPERTY_NOTIFY(CWBEMViewContainerCtrl, "StatusCode", m_sc, OnStatusCodeChanged, VT_I4) DISP_PROPERTY_EX(CWBEMViewContainerCtrl, "ObjectPath", GetObjectPath, SetObjectPath, VT_VARIANT) DISP_PROPERTY_EX(CWBEMViewContainerCtrl, "NameSpace", GetNameSpace, SetNameSpace, VT_BSTR) DISP_PROPERTY_EX(CWBEMViewContainerCtrl, "StudioModeEnabled", GetStudioModeEnabled, SetStudioModeEnabled, VT_I4) DISP_PROPERTY_EX(CWBEMViewContainerCtrl, "PropertyFilter", GetPropertyFilter, SetPropertyFilter, VT_I4) DISP_FUNCTION(CWBEMViewContainerCtrl, "ShowInstances", ShowInstances, VT_EMPTY, VTS_BSTR VTS_VARIANT) DISP_FUNCTION(CWBEMViewContainerCtrl, "SaveState", SaveState, VT_I4, VTS_I4 VTS_I4) DISP_FUNCTION(CWBEMViewContainerCtrl, "QueryViewInstances", QueryViewInstances, VT_EMPTY, VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR) DISP_STOCKPROP_READYSTATE() //}}AFX_DISPATCH_MAP END_DISPATCH_MAP() ///////////////////////////////////////////////////////////////////////////// // Event map BEGIN_EVENT_MAP(CWBEMViewContainerCtrl, COleControl) //{{AFX_EVENT_MAP(CWBEMViewContainerCtrl) EVENT_CUSTOM("GetIWbemServices", FireGetIWbemServices, VTS_BSTR VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT) EVENT_CUSTOM("NOTIFYChangeRootOrNamespace", FireNOTIFYChangeRootOrNamespace, VTS_BSTR VTS_I4 VTS_I4) EVENT_CUSTOM("RequestUIActive", FireRequestUIActive, VTS_NONE) EVENT_STOCK_READYSTATECHANGE() //}}AFX_EVENT_MAP END_EVENT_MAP() ///////////////////////////////////////////////////////////////////////////// // Property pages // TODO: Add more property pages as needed. Remember to increase the count! BEGIN_PROPPAGEIDS(CWBEMViewContainerCtrl, 1) PROPPAGEID(CWBEMViewContainerPropPage::guid) END_PROPPAGEIDS(CWBEMViewContainerCtrl) ///////////////////////////////////////////////////////////////////////////// // Initialize class factory and guid IMPLEMENT_OLECREATE_EX(CWBEMViewContainerCtrl, "WBEM.ObjViewerCtrl.1", 0x5b3572ab, 0xd344, 0x11cf, 0x99, 0xcb, 0, 0xc0, 0x4f, 0xd6, 0x44, 0x97) ///////////////////////////////////////////////////////////////////////////// // Type library ID and version IMPLEMENT_OLETYPELIB(CWBEMViewContainerCtrl, _tlid, _wVerMajor, _wVerMinor) ///////////////////////////////////////////////////////////////////////////// // Interface IDs const IID BASED_CODE IID_DWBEMViewContainer = { 0x5b3572a9, 0xd344, 0x11cf, { 0x99, 0xcb, 0, 0xc0, 0x4f, 0xd6, 0x44, 0x97 } }; const IID BASED_CODE IID_DWBEMViewContainerEvents = { 0x5b3572aa, 0xd344, 0x11cf, { 0x99, 0xcb, 0, 0xc0, 0x4f, 0xd6, 0x44, 0x97 } }; ///////////////////////////////////////////////////////////////////////////// // Control type information static const DWORD BASED_CODE _dwWBEMViewContainerOleMisc = OLEMISC_SIMPLEFRAME | OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CWBEMViewContainerCtrl, IDS_HMMV, _dwWBEMViewContainerOleMisc) ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl::CWBEMViewContainerCtrlFactory::UpdateRegistry - // Adds or removes system registry entries for CWBEMViewContainerCtrl BOOL CWBEMViewContainerCtrl::CWBEMViewContainerCtrlFactory::UpdateRegistry(BOOL bRegister) { // TODO: Verify that your control follows apartment-model threading rules. // Refer to MFC TechNote 64 for more information. // If your control does not conform to the apartment-model rules, then // you must modify the code below, changing the 6th parameter from // afxRegInsertable | afxRegApartmentThreading to 0. if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_HMMV, IDB_HMMV, afxRegInsertable | afxRegApartmentThreading, _dwWBEMViewContainerOleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl::CWBEMViewContainerCtrl - Constructor CWBEMViewContainerCtrl::CWBEMViewContainerCtrl() { m_bCreationFinished = FALSE; InitializeIIDs(&IID_DWBEMViewContainer, &IID_DWBEMViewContainerEvents); EnableSimpleFrame(); SetModifiedFlag(FALSE); AfxEnableControlContainer(); m_htmlHelpInst = 0; m_bDelayToolbarUpdate = FALSE; m_bInStudioMode = TRUE; m_bEmptyContainer = TRUE; m_bSingleViewNeedsRefresh = FALSE; m_bDidInitialDraw = FALSE; m_bPathIsClass = TRUE; m_bObjectIsNewlyCreated = FALSE; m_bFiredReadyStateChange = FALSE; m_lPropFilters = (PROPFILTER_SYSTEM | PROPFILTER_INHERITED | PROPFILTER_LOCAL); // The instance paths from ShowInstances m_varObjectPath = L""; m_cxViewLeftMargin = CX_VIEW_DEFAULT_LEFT_MARGIN; m_cxViewRightMargin = CX_VIEW_DEFAULT_RIGHT_MARGIN; m_cyViewTopMargin = CY_VIEW_DEFAULT_TOP_MARGIN; m_cyViewBottomMargin = CY_VIEW_DEFAULT_BOTTOM_MARGIN; GetViewerFont(m_font, CY_TAB_FONT, FW_NORMAL); m_pViewStack = new CViewStack(this); m_pTitleBar = new CTitleBar; m_pview = new CPolyView(this); m_pdlgHelpBox = new CDlgHelpBox(this); m_bDeadObject = FALSE; // An object is dead when a user chooses not to save it } ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl::~CWBEMViewContainerCtrl - Destructor CWBEMViewContainerCtrl::~CWBEMViewContainerCtrl() { // These objects should have been freed in CWBEMViewContainerCtrl::OnDestroy ASSERT(m_pview == NULL); ASSERT(m_pViewStack == NULL); ASSERT(m_pTitleBar == NULL); #ifdef USE_HTML_HELP if(m_htmlHelpInst) { FreeLibrary(m_htmlHelpInst); m_htmlHelpInst = NULL; } #endif //USE_HTML_HELP } void CWBEMViewContainerCtrl::DrawBackground(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { CBrush brBACKGROUND(GetSysColor(COLOR_BACKGROUND)); CBrush br3DFACE(GetSysColor(COLOR_3DFACE)); pdc->FillRect(rcBounds, &br3DFACE); } void CWBEMViewContainerCtrl::CalcViewRect(CRect& rcView) { CRect rcClient; GetClientRect(&rcClient); rcView.top = rcClient.top + m_pTitleBar->GetDesiredBarHeight() + m_cyViewTopMargin; rcView.left = rcClient.left + m_cxViewLeftMargin; rcView.right = rcClient.right - m_cxViewRightMargin; rcView.bottom = rcClient.bottom - m_cyViewBottomMargin; } void CWBEMViewContainerCtrl::CalcTitleRect(CRect& rcTitle) { CRect rcClient; GetClientRect(&rcClient); rcTitle.top = rcClient.top + CY_TITLE_DEFAULT_TOP_MARGIN; rcTitle.left = rcClient.left + m_cxViewLeftMargin; rcTitle.right = rcClient.right - m_cxViewRightMargin; rcTitle.bottom = rcClient.top + m_pTitleBar->GetDesiredBarHeight(); } void CWBEMViewContainerCtrl::OnDrawPreCreate( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { CBrush brBackground; brBackground.CreateSolidBrush(::GetSysColor(COLOR_WINDOW)); CBrush brBlack; brBlack.CreateSolidBrush(::GetSysColor(COLOR_ACTIVEBORDER)); pdc->FillRect(rcInvalid, &brBackground); CRect rcFrame = rcBounds; rcFrame.InflateRect(-1, -1); pdc->FrameRect(rcFrame, &brBlack); return; #if 0 // I attempted to draw a small image of the object view so that // you would see something interesting at design time. However, // people didn't like it, so I've commented out the code here. CDC dcMem; BOOL bDidCreate; BOOL bDidLoad; bDidCreate = dcMem.CreateCompatibleDC(pdc); if (!bDidCreate) { return; } CBitmap bm; bDidLoad = bm.LoadBitmap(IDB_DESIGN_TIME); BITMAP bitmap; bm.GetBitmap(&bitmap); CBitmap* pbmSave = dcMem.SelectObject(&bm); int ixDst = 0; int iyDst = 0; if (bitmap.bmWidth < rcBounds.Width()) { ixDst = (rcBounds.Width() - bitmap.bmWidth) / 2; } if (bitmap.bmHeight < rcBounds.Height()) { iyDst = (rcBounds.Height() - bitmap.bmHeight) / 2; } pdc->BitBlt(ixDst, iyDst, rcBounds.Width(), rcBounds.Height(), &dcMem, 0, 0, SRCCOPY); dcMem.SelectObject(pbmSave); #endif //0 } ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl::OnDraw - Drawing function void CWBEMViewContainerCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { if (!::IsWindow(m_hWnd)) { OnDrawPreCreate(pdc, rcBounds, rcInvalid); return; } COLORREF clrBack = RGB(0x0ff, 0, 0); pdc->SetBkColor(clrBack); DrawBackground(pdc, rcBounds, rcInvalid); if (!m_bDidInitialDraw) { m_bDidInitialDraw = TRUE; if (m_pview->DidCreateWindow()) { m_pview->ShowSingleView(); m_pTitleBar->NotifyObjectChanged(); } } // Redraw the portion of the titlebar that is invalid. CRect rcTitleBar; m_pTitleBar->GetWindowRect(rcTitleBar); ScreenToClient(rcTitleBar); BOOL bFixTitleBar = rcTitleBar.IntersectRect(&rcInvalid, &rcTitleBar); if (bFixTitleBar) { ClientToScreen(rcTitleBar); m_pTitleBar->ScreenToClient(rcTitleBar); m_pTitleBar->InvalidateRect(rcTitleBar); } CRect rcText = rcBounds; rcText.bottom = rcText.top + 32; rcText.top = rcText.top + 6; rcText.left = rcText.left + 32 + 8 + 5 + 4; rcText.right = rcText.right - 8; if (m_pview->DidCreateWindow()) { BOOL IsShowingMultiview = m_pview->IsShowingMultiview(); BOOL bMultiviewVisible = m_pview->GetMultiView()->IsWindowVisible(); BOOL bSingleviewVisible = m_pview->GetSingleView()->IsWindowVisible(); CRect rcView; BOOL bFixView; if (bMultiviewVisible) { CMultiView* pmv = m_pview->GetMultiView(); pmv->GetWindowRect(rcView); ScreenToClient(rcView); bFixView = rcView.IntersectRect(&rcInvalid, &rcView); if (bFixView) { ClientToScreen(rcView); pmv->ScreenToClient(rcView); pmv->InvalidateRect(rcView); } } if (bSingleviewVisible) { CSingleView* psv = m_pview->GetSingleView(); psv->GetWindowRect(rcView); ScreenToClient(rcView); bFixView = rcView.IntersectRect(&rcInvalid, &rcView); if (bFixView) { ClientToScreen(rcView); psv->ScreenToClient(rcView); psv->InvalidateRect(rcView); } } // m_pview->RedrawWindow(); } if (!m_bFiredReadyStateChange) { m_bFiredReadyStateChange = TRUE; FireReadyStateChange(); } } ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl::DoPropExchange - Persistence support void CWBEMViewContainerCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: Call PX_ functions for each persistent custom property. CString sObjectPath; PX_String(pPX, _T("ObjectPath"), sObjectPath, CString(_T(""))); m_varObjectPath = (const CString&) sObjectPath; PX_String(pPX, _T("NameSpace"), m_sNameSpace, CString(_T(""))); PX_Bool(pPX, _T("StudioModeEnabled"), m_bInStudioMode, TRUE); m_pview->SetStudioModeEnabled(m_bInStudioMode); } ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl::OnResetState - Reset control to default state void CWBEMViewContainerCtrl::OnResetState() { COleControl::OnResetState(); // Resets defaults found in DoPropExchange } ///////////////////////////////////////////////////////////////////////////// // CWBEMViewContainerCtrl message handlers void CWBEMViewContainerCtrl::DoDataExchange(CDataExchange* pDX) { COleControl::DoDataExchange(pDX); } LRESULT CWBEMViewContainerCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { return COleControl::WindowProc(message, wParam, lParam); } void CWBEMViewContainerCtrl::SetObjectPath(const VARIANT FAR& varObjectPath) { BOOL bDelayToolbarUpdateT = m_bDelayToolbarUpdate; m_bDelayToolbarUpdate = TRUE; if (!::IsWindow(m_hWnd)) { m_varObjectPath = varObjectPath; return; } if (!m_pview->DidCreateWindow()) { return; } m_bEmptyContainer = ::IsEmptyString(varObjectPath.bstrVal); m_pViewStack->UpdateView(); ShowMultiView(FALSE, FALSE); JumpToObjectPath(varObjectPath.bstrVal, TRUE); m_bDelayToolbarUpdate = bDelayToolbarUpdateT; if (!m_bDelayToolbarUpdate) { m_pTitleBar->Refresh(); } } VARIANT CWBEMViewContainerCtrl::GetObjectPath() { CSingleView* psv = m_pview->GetSingleView(); long lPos; lPos = psv->StartObjectEnumeration(OBJECT_CURRENT); if (lPos >= 0) { m_varObjectPath = psv->GetObjectPath(lPos); } return m_varObjectPath; } void CWBEMViewContainerCtrl::Clear(BOOL bRedrawWindow) { m_bDeadObject = FALSE; // An object is dead when a user chooses not to save it if (m_pTitleBar != NULL) { m_pTitleBar->EnableButton(ID_CMD_SAVE_DATA, FALSE); m_pTitleBar->EnableButton(ID_CMD_FILTERS, FALSE); } m_bObjectIsNewlyCreated = FALSE; m_sNewInstClassPath.Empty(); if (m_hWnd != NULL) { m_pview->RefreshView(); SetModifiedFlag(FALSE); RedrawWindow(); } else { SetModifiedFlag(FALSE); } } //************************************************************** // CWBEMViewContainerCtrl::UpdateCreateDeleteButtonState // // Update the "enabled" state of the create and delete buttons to // reflect the state of the underlying data and selection state. // // Parameters: // None. // // Returns: // Nothing. // //************************************************************** void CWBEMViewContainerCtrl::UpdateCreateDeleteButtonState() { if (m_hWnd == NULL || m_pTitleBar==NULL) { return; } BOOL bCanCreateInstance = FALSE; BOOL bCanDeleteInstance = FALSE; if (InStudioMode()) { CSingleView* psv = m_pview->GetSingleView(); bCanCreateInstance = psv->QueryCanCreateInstance(); bCanDeleteInstance = m_pview->QueryCanDeleteInstance(); } m_pTitleBar->EnableButton(ID_CMD_CREATE_INSTANCE, bCanCreateInstance); m_pTitleBar->EnableButton(ID_CMD_DELETE_INSTANCE, bCanDeleteInstance); } //*********************************************************** // CWBEMViewContainerCtrl::ShowMultiView // // Switch to either the multiple instance view or to the current // single object view depending on the parameter. // // Parameters: // [in] BOOL bShowMultiView // TRUE to select the MultiView, otherwise FALSE // // [in] BOOL bAddToHistory // TRUE to add any view change to the view history. // // // Returns: // TRUE if the view switch was OK, FALSE if the user aborted the // view switch by cancelling a data save, etc. // //*********************************************************** BOOL CWBEMViewContainerCtrl::ShowMultiView(BOOL bShowMultiView, BOOL bAddToHistory) { if (!::IsWindow(m_hWnd)) { return FALSE; } BOOL bWasShowingMultiView = m_pview->IsShowingMultiview(); if (IsBoolEqual(bShowMultiView, bWasShowingMultiView)) { // The view is the same, but we may want to add it to the history. if (bAddToHistory) { m_pViewStack->PushView(); } return TRUE; } // Show the desired view. if (bShowMultiView) { m_pview->ShowMultiView(); } else { // If we are flipping from the multiview to an instance, we should check to // see if the currently selected instance in the multiview matches the // currently selected instance in the singleview, if not then use the // path for the currently selected instance in the multiview to select an // instance in the singleview. CSingleView* psv = m_pview->GetSingleView(); CMultiView* pmv = m_pview->GetMultiView(); BOOL bIsShowingInstance = psv->IsShowingInstance(); if (!bIsShowingInstance) { CString sPathSingleview; SCODE sc = psv->GetCurrentObjectPath(sPathSingleview); if (!m_bObjectIsNewlyCreated && sPathSingleview.IsEmpty()) { CString sPathMultiview; sc = pmv->GetCurrentObjectPath(sPathMultiview); if (SUCCEEDED(sc)) { psv->SelectObjectByPath(sPathMultiview); m_pViewStack->UpdateView(); } } } m_pview->ShowSingleView(); } BOOL bIsShowingMultiView = m_pview->IsShowingMultiview(); BOOL bDidSwitchView = !IsBoolEqual(bWasShowingMultiView, bIsShowingMultiView); // If the view was switched, update the toolbar, etc. if (bDidSwitchView) { if (bAddToHistory) { m_pViewStack->PushView(); } UpdateWindow(); } return TRUE; } //****************************************************************** // CWBEMViewContainerCtrl::JumpToObjectPathFromMultiview // // // Parameters: // LPCTSTR szPath // The HMOM object path. // // BOOL bSetMultiviewClass // TRUE to change the class of the instances displayed in // the multiview. // // BOOL bAddToHistory // TRUE to add this jump to the view history. // // Returns: // SCODE // S_OK if the jump was completed, a failure code otherwise. // //****************************************************************** SCODE CWBEMViewContainerCtrl::JumpToObjectPathFromMultiview(LPCTSTR szPath, BOOL bSetMultiviewClass, BOOL bAddToHistory) { SCODE sc; m_pViewStack->UpdateView(); CBSTR bsPath(szPath); sc = JumpToObjectPath((BSTR) bsPath, bSetMultiviewClass, bAddToHistory); if (FAILED(sc)) { ShowMultiView(TRUE, FALSE); } return sc; } //****************************************************************** // CWBEMViewContainerCtrl::JumpToObjectPath // // // Parameters: // BSTR bstrObjectPath // The HMOM object path. // // BOOL bSetMultiviewClass // TRUE to change the class of the instances displayed in // the multiview. // // BOOL bAddToHistory // TRUE to add this jump to the view history. // // Returns: // SCODE // S_OK if the jump was completed, a failure code otherwise. // //****************************************************************** SCODE CWBEMViewContainerCtrl::JumpToObjectPath(BSTR bstrObjectPath, BOOL bSetMultiviewClass, BOOL bAddToHistory) { SCODE sc; CString sCurPath; CSingleView* psv = m_pview->GetSingleView(); long lPos = psv->StartObjectEnumeration(OBJECT_CURRENT); if (lPos != -1) { sCurPath = psv->GetObjectPath(lPos); CBSTR bsCurPath(sCurPath); if (IsEqualNoCase(bstrObjectPath, (BSTR) bsCurPath)) { bAddToHistory = FALSE; } } // First check to see if there are any changes and, if so, // ask the user whether or not he or she wants to save them. if (!m_bDeadObject) { // An object is dead when a user chooses not to save it sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { return sc; } } sCurPath = bstrObjectPath; sc = psv->SelectObjectByPath(sCurPath); if (FAILED(sc)) { return sc; } if (bSetMultiviewClass) { CMultiView* pmv = m_pview->GetMultiView(); if (::IsEmptyString(bstrObjectPath)) { pmv->ViewClassInstances((LPCTSTR) ""); } else { COleVariant varClass; sc = ClassFromPath(varClass, bstrObjectPath); if (SUCCEEDED(sc)) { CString sClass; sClass = varClass.bstrVal; pmv->ViewClassInstances((LPCTSTR) sClass); } } } m_varObjectPath = bstrObjectPath; if (bAddToHistory) { if (*bstrObjectPath != 0) { m_pViewStack->PushView(); } } ShowMultiView(FALSE, FALSE); UpdateToolbar(); m_bDeadObject = FALSE; return S_OK; } //******************************************************** // CWBEMViewContainerCtrl::OnSize // // Handle the WM_SIZE message. This is the main window for // the control and thus the child windows of this control // must be resized accordingly. // // Parameters: // See the MFC documentation for OnSize. // // Returns: // Nothing. // //********************************************************* void CWBEMViewContainerCtrl::OnSize(UINT nType, int cx, int cy) { COleControl::OnSize(nType, cx, cy); // If the window size is one pixel or less, IExplore locks up // if we resize the child windows. CRect rcView; CalcViewRect(rcView); if (!rcView.IsRectEmpty()) { m_pview->MoveWindow(rcView); } if (m_pTitleBar && m_pTitleBar->m_hWnd) { CRect rcTitle; CalcTitleRect(rcTitle); if (!rcTitle.IsRectEmpty()) { m_pTitleBar->MoveWindow(rcTitle); } } } //************************************************************** // CWBEMViewContainerCtrl::SaveState // // Save the sate of the generic view. // // Parameters: // [in] long bPromptUser // TRUE if the user should be prompted as to whether or // not the state should be saved. // // [in] long bUserCanCancel // // // Returns: // SCODE // S_OK if the state was saved, WBEM_S_FALSE if the user chose not to // save the object, and WBEM_S E_FAIL if something went // wrong or if the user canceled the save. // //************************************************************** long CWBEMViewContainerCtrl::SaveState(long bPromptUser, long bUserCanCancel) { UINT nType = bUserCanCancel ? MB_YESNOCANCEL : MB_YESNO; long lResult; lResult = PublicSaveState(bPromptUser, nType); return lResult; } long CWBEMViewContainerCtrl::PublicSaveState(BOOL bPromptUser, UINT nType) { ASSERT((nType == MB_YESNOCANCEL) || (nType == MB_YESNO) || (nType == MB_OKCANCEL)); // If the current object is not modified, there is nothing to do. CSingleView* psv = m_pview->GetSingleView(); BOOL bNeedsSave = psv->QueryNeedsSave(); if (!bNeedsSave) { // Control should never come here. m_pTitleBar->EnableButton(ID_CMD_SAVE_DATA, FALSE); return S_OK; } if (bPromptUser) { // Ask the user if a save should be done. CString sFormat; sFormat.LoadString(IDS_QUERY_SAVE_CHANGES); CString sTitle; sTitle = m_pview->GetObjectTitle(OBJECT_CURRENT); _stprintf(m_szMessageBuffer, (LPCTSTR) sFormat, (LPCTSTR) sTitle); nType |= MB_SETFOREGROUND; int iPromptResult = HmmvMessageBox(this, m_szMessageBuffer, nType); UpdateWindow(); CBSTR bsEmptyPath(_T("")); CString sPath; switch(iPromptResult) { case IDYES: break; case IDNO: // When an object save is canceled, the user is switching // to a different object and the current version of the // object must be discarded in the event that the user // clicks the "go back" button or flips back to the // singleview from the multiview. if (m_pview->IsShowingSingleview()) { m_bSingleViewNeedsRefresh = TRUE; } m_pViewStack->UpdateView(); m_bSingleViewNeedsRefresh = FALSE; m_bDeadObject = TRUE; // An object is dead when a user chooses not to save it // If the user says no to a save, discard the object. m_pview->RefreshView(); // bug#55978 m_pTitleBar->EnableButton(ID_CMD_SAVE_DATA, FALSE);// bug#55978 return WBEM_S_FALSE; break; case IDCANCEL: return E_FAIL; } } SCODE sc; sc = m_pview->SaveData(); if (FAILED(sc)) { return sc; } // After a successful save, it is necessary to update the // multiple instance view so that it shows the current property // values for the object. This is done by telling the multiview // that the object has been deleted and then created. CString sObjectPath; CMultiView* pmv = m_pview->GetMultiView(); sc = psv->GetCurrentObjectPath(sObjectPath); if (SUCCEEDED(sc)) { pmv->ExternInstanceDeleted(sObjectPath); pmv->ExternInstanceCreated(sObjectPath); } m_bObjectIsNewlyCreated = FALSE; m_sNewInstClassPath.Empty(); // m_notify.SendEvent(NOTIFY_OBJECT_SAVE_SUCCESSFUL); UpdateToolbar(); m_pViewStack->UpdateView(); return S_OK; } void CWBEMViewContainerCtrl::UpdateToolbar() { if (!m_bDelayToolbarUpdate) { BOOL bNeedsSave = m_pview->QueryNeedsSave(); SetModifiedFlag(bNeedsSave); m_pTitleBar->Refresh(); } } void CWBEMViewContainerCtrl::NotifyDataChange() { BOOL bNeedsSave = m_pview->QueryNeedsSave(); SetModifiedFlag(bNeedsSave); m_pTitleBar->EnableButton(ID_CMD_SAVE_DATA, bNeedsSave); } int CWBEMViewContainerCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here if (m_hWnd) { CRect rcTitleBar; rcTitleBar.SetRectEmpty(); m_pTitleBar->Create(this, WS_VISIBLE | WS_CHILD, rcTitleBar, GenerateWindowID()); m_pTitleBar->EnableButton(ID_CMD_SAVE_DATA, FALSE); m_pTitleBar->CheckButton(ID_CMD_SWITCH_VIEW, FALSE); } CRect rcView; CalcViewRect(rcView); BOOL bDidCreate; bDidCreate = m_pview->Create(rcView); if (!bDidCreate) { return FALSE; } m_pview->SetFont(m_font); ShowMultiView(FALSE, FALSE); if (!m_sNameSpace.IsEmpty()) { m_pview->SetNamespace(m_sNameSpace); } CString sPath; sPath = m_varObjectPath.bstrVal; if (!sPath.IsEmpty()) { JumpToObjectPath(m_varObjectPath.bstrVal, TRUE); } m_pTitleBar->EnableButton(ID_CMD_CONTEXT_FORWARD, FALSE); m_pTitleBar->EnableButton(ID_CMD_CONTEXT_BACK, FALSE); m_pTitleBar->EnableButton(ID_CMD_CREATE_INSTANCE, FALSE); m_pTitleBar->EnableButton(ID_CMD_DELETE_INSTANCE, FALSE); m_pTitleBar->EnableButton(ID_CMD_FILTERS, FALSE); m_pTitleBar->EnableButton(ID_CMD_SWITCH_VIEW, FALSE); m_pTitleBar->EnableButton(ID_CMD_QUERY, FALSE); m_pview->SetEditMode(m_bInStudioMode); m_bCreationFinished = TRUE; return 0; } void CWBEMViewContainerCtrl::OnDestroy() { delete m_pViewStack; delete m_pview; delete m_pTitleBar; delete m_pdlgHelpBox; m_pViewStack = NULL; m_pview = NULL; m_pTitleBar = NULL; COleControl::OnDestroy(); } //************************************************************ // CWBEMViewContainerCtrl::MultiViewButtonClicked // // This method is called when the multiple-instance view button // is clicked. When this occurs, switch to the multiple instance // view. // // Parameters: // None. // // Returns: // Nothing. // //************************************************************* void CWBEMViewContainerCtrl::MultiViewButtonClicked() { CWaitCursor wait; BOOL bSwitchViewChecked = m_pTitleBar->IsButtonChecked(ID_CMD_SWITCH_VIEW); BOOL bWasShowingSingleView = m_pview->IsShowingSingleview(); BOOL bWasNewlyCreatedInst = FALSE; CString sClassPath; CSingleView* psv = m_pview->GetSingleView(); SCODE sc = S_OK; if (m_pview->IsShowingSingleview()) { // Save the state only if we are flipping from the // singleview to the multiview. This prevents a // the save from being done when a new object is // pre-selected into the singleview prior to displaying // it so that things appear quickly. sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { m_pTitleBar->CheckButton(ID_CMD_SWITCH_VIEW, FALSE); return; } else if (sc == WBEM_S_FALSE) { // The user chose not to save changes when flipping to the // multiview. This means that we need to reselect the // current path into the singleview so that we revert back // to the initial state of the object. CString sObjectPath; sObjectPath = m_varObjectPath.bstrVal; psv->SelectObjectByPath(sObjectPath); } if (m_bObjectIsNewlyCreated) { bWasNewlyCreatedInst = TRUE; sClassPath = m_sNewInstClassPath; } } ShowMultiView(bSwitchViewChecked, FALSE); if (bWasShowingSingleView && bWasNewlyCreatedInst) { if (sc == WBEM_S_FALSE && !sClassPath.IsEmpty()) { // The user chose not to save the newly created instance, so // we need to select the class so that when the user sees the // multiview, the create instance button will be enabled // if appropriate. psv->SelectObjectByPath(m_sNewInstClassPath); m_pViewStack->UpdateView(); m_bObjectIsNewlyCreated = FALSE; m_sNewInstClassPath.Empty(); } } else { m_pViewStack->PushView(); } m_pTitleBar->Refresh(); UpdateWindow(); return; } //************************************************************** // CWBEMViewContainerCtrl::ShowInstances // // This is the automation interface for specifying a set of instances // to view. Call this interface to select the multiple instance view // and load it with a set of instances. // // Parameters: // [in] LPCTSTR pszTitle // The view title. // // const VARIANT FAR& varPathArray // An variant array containing the HMOM paths to the instances. // // Returns: // Nothing. // //**************************************************************** void CWBEMViewContainerCtrl::ShowInstances(LPCTSTR pszTitle, const VARIANT FAR& varPathArray) { m_bEmptyContainer = FALSE; CMultiView* pmv = m_pview->GetMultiView(); try { // TODO: Add your dispatch handler code here if (pmv == NULL) { // If the multi-view control isn't available, there is nothing // that can be done here. ASSERT(FALSE); } // Show the MultiView CWaitCursor wait; pmv->ViewInstances(pszTitle, varPathArray); m_pview->ShowMultiView(); if (m_bInStudioMode) { m_pTitleBar->EnableButton(ID_CMD_SWITCH_VIEW, FALSE); // We are switching to the multiple instance view, so set the button // check state to appear as if it is pressed. m_pTitleBar->CheckButton(ID_CMD_SWITCH_VIEW, TRUE); } m_pTitleBar->EnableButton(ID_CMD_FILTERS, FALSE); m_pTitleBar->NotifyObjectChanged(); m_pview->RedrawWindow(); InvalidateControl(); m_pViewStack->PushView(); } catch(CException* ) { } } //******************************************************************** // CWBEMViewContainerCtrl::QueryViewInstances // // // Parameters: // LPCTSTR pszLabel // // LPCTSTR pszQueryType // // LPCTSTR pszQuery // // LPCTSTR pszClass // // Returns: // Nothing. // //******************************************************************** void CWBEMViewContainerCtrl::QueryViewInstances( LPCTSTR pszLabel, LPCTSTR pszQueryType, LPCTSTR pszQuery, LPCTSTR pszClass) { try { CMultiView* pmv = m_pview->GetMultiView(); if (pmv == NULL || pmv->m_hWnd==NULL) { // If the multi-view control isn't available, there is nothing // that can be done here. ASSERT(FALSE); } m_pViewStack->UpdateView(); // First check to see if there are any changes and, if so, // ask the user whether or not he or she wants to save them. SCODE sc; sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { return; } if (m_pview->IsShowingSingleview() && (sc == WBEM_S_FALSE)) { m_pview->GetSingleView()->SelectObjectByPath(_T("")); } CWaitCursor wait; COleVariant varTitle; varTitle = pszLabel; ASSERT(varTitle.vt == VT_BSTR); pmv->QueryViewInstances(pszLabel, pszQueryType, pszQuery, pszClass); m_pview->ShowMultiView(); if (m_bInStudioMode) { m_pTitleBar->EnableButton(ID_CMD_SWITCH_VIEW, FALSE); // We are switching to the multiple instance view, so set the button // check state to appear as if it is pressed. m_pTitleBar->CheckButton(ID_CMD_SWITCH_VIEW, TRUE); } else { CSingleView* psv = m_pview->GetSingleView(); psv->SelectObjectByPath(_T("")); } m_pTitleBar->EnableButton(ID_CMD_FILTERS, FALSE); m_pTitleBar->NotifyObjectChanged(); // Somehow the singleview is becoming visible when it shouldn't, so show the // multiview again. m_pview->ShowMultiView(); // InvalidateControl(); } catch(CException* ) { } } #if 0 // Disable global context menu per bug #4222 //*************************************************************** // CWBEMViewContainerCtrl::OnContextMenu // // This method displays the context menu. It is called from // PretranslateMessage. // // Parameters: // CWnd* pwnd // Pointer to the window that the event that triggered the // menu occurred in. // // CPoint ptScreen // The point, in screen coordinates, where the context menu // should be displayed. // // Returns: // Nothing. // //***************************************************************** void CWBEMViewContainerCtrl::OnContextMenu(CWnd* pwnd, CPoint ptScreen) { // CG: This function was added by the Pop-up Menu component CPoint ptClient = ptScreen; ScreenToClient(&ptClient); // If the mouse was right-clicked outside the client rectangle do nothing. CRect rcClient; GetClientRect(rcClient); if (!rcClient.PtInRect(ptClient)) { return; } // If the mouse was right-clicked over the toolbar buttons, do nothing. CRect rcTools; m_pTitleBar->GetToolBarRect(rcTools); m_pTitleBar->ClientToScreen(rcTools); if (rcTools.PtInRect(ptScreen)) { return; } CMenu menu; VERIFY(menu.LoadMenu(CG_IDR_POPUP_HMMV_CTRL)); CMenu* pPopup = menu.GetSubMenu(0); ASSERT(pPopup != NULL); pPopup->EnableMenuItem(ID_CMD_SHOW_OBJECT_ATTRIBUTES, MF_ENABLED); CWnd* pWndPopupOwner = this; pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, pWndPopupOwner); } BOOL CWBEMViewContainerCtrl::PreTranslateMessage(MSG* pMsg) { BOOL bInvokeContextMenu = FALSE; // Shift+F10: show pop-up menu. switch(pMsg->message) { case WM_KEYDOWN: case WM_SYSKEYDOWN: switch(pMsg->wParam) { case VK_F10: if ((GetKeyState(VK_SHIFT) & ~1) != 0) { bInvokeContextMenu = TRUE; } break; case VK_TAB: // When you see the tab key in your control's pretranslate // message you know that IE is telling you to go ui active // and allowing you to give your control focus because the // user just tabbed into your control. A vb form // behaves the same way. SetFocus(); break; } break; case WM_CONTEXTMENU: bInvokeContextMenu = TRUE; break; } if (bInvokeContextMenu) { CRect rect; GetClientRect(rect); ClientToScreen(rect); CPoint point = rect.TopLeft(); point.Offset(5, 5); OnContextMenu(NULL, point); return TRUE; } return COleControl::PreTranslateMessage(pMsg); } // End of context menu disabling #endif //0 void CWBEMViewContainerCtrl::OnCmdShowObjectAttributes() { ASSERT(FALSE); // ShowObjectAttributes(); } void CWBEMViewContainerCtrl::OnStatusCodeChanged() { // TODO: Add notification handler code SetModifiedFlag(); } BSTR CWBEMViewContainerCtrl::GetNameSpace() { return m_sNameSpace.AllocSysString(); } void CWBEMViewContainerCtrl::SetNameSpace(LPCTSTR lpszNameSpace) { //return; // VBSCRIPT_ERROR BOOL bDelayToolbarUpdateSave = m_bDelayToolbarUpdate; m_bDelayToolbarUpdate = TRUE; m_sNameSpace = lpszNameSpace; if (!::IsWindow(m_hWnd)) { return; } if (!m_bEmptyContainer) { m_pViewStack->PushView(); } delete m_pViewStack; m_pViewStack = new CViewStack(this); CDisableViewStack DisableViewStack(m_pViewStack); m_pview->SetNamespace(lpszNameSpace); m_varObjectPath = ""; m_bEmptyContainer = TRUE; ShowMultiView(FALSE, FALSE); m_pTitleBar->Refresh(); m_bDelayToolbarUpdate = bDelayToolbarUpdateSave; } void CWBEMViewContainerCtrl::InvalidateControlRect(CRect* prc) { InvalidateControl(prc); } DWORD CWBEMViewContainerCtrl::GetActivationPolicy( ) { return POINTERINACTIVE_ACTIVATEONENTRY | POINTERINACTIVE_DEACTIVATEONLEAVE | POINTERINACTIVE_ACTIVATEONDRAG; } //*********************************************************** // CWBEMViewContainerCtrl::GetCurrentClass // // Get a path to the current class. This is used when // we need to know what the class is when creating a // new instance. // // Parameters: // COleVariant& varClass // // Returns: // SCODE // S_OK if successful, E_FAIL if there is no current class. // //************************************************************** SCODE CWBEMViewContainerCtrl::GetCurrentClass(COleVariant& varClass) { CString sPath = m_pview->GetObjectPath(OBJECT_CURRENT); if (sPath.IsEmpty()) { return E_FAIL; } CBSTR bsPath(sPath); BSTR bstrPath = (BSTR) bsPath; SCODE sc = ClassFromPath(varClass, bstrPath); return sc; } //************************************************************ // CWBEMViewContainerCtrl::CreateInstance // // Create an instance of the current class. // // Parameters: // None. // // Returns: // Nothing. // //************************************************************* void CWBEMViewContainerCtrl::CreateInstance() { if (!InStudioMode()) { ASSERT(FALSE); // Control should never come here. return; } SCODE sc; // Save the state of the current object before attempting to // create a new one. Do nothing if the user cancels the save. sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { return; } CSingleView* psv = m_pview->GetSingleView(); BOOL bCanCreateInstance = psv->QueryCanCreateInstance(); if (!bCanCreateInstance) { ASSERT(FALSE); return; } // When an instance is created, the multiple instance and the custom // view should be notified so that they can display the correct information. // // Maybe I should set a flag to indicate whether or not the new instance // needs to be passed to the multiple instance view or custom view when // switching views. CString sClassPathSave; sClassPathSave = m_sNewInstClassPath; sc = psv->GetClassPath(m_sNewInstClassPath); ASSERT(SUCCEEDED(sc)); sc = psv->CreateInstance(m_sNewInstClassPath); if (SUCCEEDED(sc)) { // !!!CR: We need to notify the multiple instance view when // !!!CR: a new instance has been created, but since the // !!!CR: instance hasn't been written to the database yet // !!!CR: there is nothing to notify them of yet. m_bObjectIsNewlyCreated = TRUE; ShowMultiView(FALSE, FALSE); SetModifiedFlag(TRUE); m_pTitleBar->EnableButton(ID_CMD_SAVE_DATA, TRUE); m_pTitleBar->Refresh(); UpdateCreateDeleteButtonState(); m_pViewStack->PushView(); } else { m_sNewInstClassPath = sClassPathSave; } psv->SetFocus(); UpdateWindow(); } //**************************************************************** // CWBEMViewContainerCtrl::DeleteInstance // // Delete the currently selected instance amd coordinate the deletion with // the child views. // // Parameters: // None. // // Returns: // Nothing. // //**************************************************************** void CWBEMViewContainerCtrl::DeleteInstance() { if (!InStudioMode()) { ASSERT(FALSE); // Control should never come here. return; } CMultiView* pmv = m_pview->GetMultiView(); CSingleView* psv = m_pview->GetSingleView(); SCODE sc; CString sClassPath; sc = psv->GetClassPath(sClassPath); if (FAILED(sc)) { sClassPath.Empty(); } long lPos; lPos = pmv->StartObjectEnumeration(OBJECT_CURRENT); CString sPath; sPath = m_pview->GetObjectPath(lPos); CString sTitle; sTitle = m_pview->GetObjectTitle(lPos); // Prompt the user to verify that it is OK to delete the // current object. CString sFormat; sFormat.LoadString(IDS_QUERY_DELETE_OBJECT); CString sCaption; if (::PathIsClass(sPath)) { sCaption = _T("Deleting a Class"); } else { sCaption = _T("Deleting an Instance"); } _stprintf(m_szMessageBuffer, (LPCTSTR) sFormat, (LPCTSTR) sTitle); PreModalDialog( ); CWnd* pwndFocus = GetFocus(); int iMsgBoxStatus = ::MessageBox(m_hWnd, m_szMessageBuffer, (LPCTSTR) _T("Deleting an Instance"), MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION); if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) { pwndFocus->SetFocus(); } PostModalDialog(); UpdateWindow(); if (iMsgBoxStatus != IDYES) { return; } sc = m_pview->DeleteInstance(); if (FAILED(sc)) { return; } BOOL bDeletedCurrentView = m_pViewStack->PurgeView(sPath); // Get the current view's concept of the currently selected instance. // It may be the case that the current view doesn't have any instance // selected - for example, a class might be selected. // // Note that when switching to a view, the single container should enable // or disable the "delete instance" button depending on whether or not // that view has a selected instance to delete. // // Views should notify the container when the current selection // changes. if (bDeletedCurrentView) { m_pViewStack->RefreshView(); } else { if (!m_pview->IsShowingMultiview()) { if (m_bObjectIsNewlyCreated) { if (m_pViewStack->CanGoBack()) { Clear(FALSE); m_pViewStack->GoBack(); } else { Clear(); } m_pViewStack->TrimStack(); return; } } } if (SUCCEEDED(sc)) { // NotifyInstanceDeleted does not work, so instead we just tell // the multiview control to refresh all of its data. COleVariant varObjectPath; varObjectPath = sPath; NotifyInstanceDeleted(varObjectPath); if (m_pview->IsShowingMultiview()) { CSingleView* psv = m_pview->GetSingleView(); sPath = m_pview->GetObjectPath(OBJECT_CURRENT); psv->SelectObjectByPath(sPath); m_pViewStack->UpdateView(); } else { if (m_pViewStack->CanGoBack()) { Clear(FALSE); m_pViewStack->GoBack(); } else { Clear(); } m_pViewStack->TrimStack(); } } if (m_pview->IsShowingMultiview()) { long lPos = pmv->StartObjectEnumeration(OBJECT_FIRST); if (lPos < 0 && !sClassPath.IsEmpty()) { // The multiview is empty because we deleted the last item. // We need to select the class into the singleview so that // we can still create an instance. psv->SelectObjectByPath(sClassPath); ShowMultiView(TRUE, FALSE); m_pViewStack->UpdateView(); } } UpdateToolbar(); } //***************************************************************************** // CWBEMViewContainerCtrl::NotifyContainerOfSelectionChange // // This method is called when the selection is changed in one of the child views // and the child view fires this event. // // This method is necessary to allow the container to enable or disable the // "delete instance" button. // // Parameters: // int idView // The view id so that the container knows whether or not the selection // changed in the currently active view. // // Returns: // Nothing. // //***************************************************************************** void CWBEMViewContainerCtrl::NotifyContainerOfSelectionChange() { } SCODE CWBEMViewContainerCtrl::ContextForward() { if (m_pViewStack->CanGoForward()) { m_pViewStack->GoForward(); return S_OK; } else { return E_FAIL; } } SCODE CWBEMViewContainerCtrl::ContextBack() { if (m_pViewStack->CanGoBack()) { BOOL bObjectWasNewlyCreated = m_bObjectIsNewlyCreated; m_pViewStack->GoBack(); if (bObjectWasNewlyCreated) { // If the object was newly created and the user opted not // to save it, trim the context stack so that the user // can't attempt to go back to the object that was discarded. m_pViewStack->TrimStack(); } return S_OK; } else { return E_FAIL; } } //*********************************************************************** // CWBEMViewContainerCtrl::QueryCanContextForward // // Check to see if it is OK to go forward a step on the view context stack. // If the current object is modified, an attempt is made to save its state // before approving the change in view context. // // Parameters: // None. // // Returns: // BOOL // TRUE if it is OK to go forward to the "next" entry on the view // stack. FALSE if there is no next entry or the user cancels saving // the current object if it was modified. // // //************************************************************************ BOOL CWBEMViewContainerCtrl::QueryCanContextForward() { SCODE sc; sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { // The user canceled the save, so abort the change of view context. return FALSE; } return m_pViewStack->CanGoForward(); } //*********************************************************************** // CWBEMViewContainerCtrl::QueryCanContextBack // // Check to see if it is OK to go back a step on the view context stack. // If the current object is modified, an attempt is made to save its state // before approving the change in view context. // // Parameters: // None. // // Returns: // BOOL // TRUE if it is OK to go back to the "previous" entry on the view // stack. FALSE if there is no next entry or the user cancels saving // the current object if it was modified. // // //************************************************************************ BOOL CWBEMViewContainerCtrl::QueryCanContextBack() { SCODE sc; sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { // The user canceled the save, so abort the change of view context. return FALSE; } return m_pViewStack->CanGoBack(); } long CWBEMViewContainerCtrl::GetStudioModeEnabled() { // TODO: Add your property handler here return m_bInStudioMode; } void CWBEMViewContainerCtrl::SetStudioModeEnabled(long bInStudioMode) { // SetNotSupported BOOL bWasInStudioMode = m_bInStudioMode; m_bInStudioMode = bInStudioMode; if ((bInStudioMode && !bWasInStudioMode) || (!bInStudioMode && bWasInStudioMode)) { delete m_pViewStack; m_pViewStack = new CViewStack(this); delete m_pview; m_pview = new CPolyView(this); m_pview->SetStudioModeEnabled(bInStudioMode); CRect rcView; CalcViewRect(rcView); BOOL bDidCreate; bDidCreate = m_pview->Create(rcView); if (!bDidCreate) { InvalidateControl(); // Must do this! return; } m_pview->SetFont(m_font); ShowMultiView(FALSE, FALSE); if (!m_sNameSpace.IsEmpty()) { m_pview->SetNamespace(m_sNameSpace); } if (::IsWindow(m_pTitleBar->m_hWnd)) { m_pTitleBar->LoadToolBar(); } } SetModifiedFlag(); InvalidateControl(); // Must do this! } void CWBEMViewContainerCtrl::GetContainerContext(CContainerContext& ctx) { ctx.m_bIsShowingMultiView = m_pview->IsShowingMultiview(); ctx.m_bObjectIsNewlyCreated = m_bObjectIsNewlyCreated; ctx.m_bEmptyContainer = m_bEmptyContainer; ctx.m_hwndFocus = ::GetFocus(); } //*********************************************************** // CWBEMViewContainerCtrl::SetContainerContextPrologue // // This method is called to begin the restoration of the // container's view context. It is the first call that is // made to restore the context. // // Parameters: // [in] CContainerContext& ctx // The container context that was saved previously. // // Returns: // SCODE // S_OK if successful, E_FAIL if there was an attempt to // restore the container to an invalid state. When E_FAIL // is returned, the CViewStack will remove this context entry // from the stack. // //************************************************************ SCODE CWBEMViewContainerCtrl::SetContainerContextPrologue(CContainerContext& ctx) { return S_OK; } //*********************************************************** // CWBEMViewContainerCtrl::SetContainerContextEpilogue // // This method is called to complete the restoration of the // container's view context. It is called after SetContainerPrologue // and the context for the generic view and multiview have been // restored. // // Parameters: // [in] CContainerContext& ctx // The container context that was saved previously. // // Returns: // SCODE // S_OK if successful, E_FAIL if there was an attempt to // restore the container to an invalid state. When E_FAIL // is returned, the CViewStack will remove this context entry // from the stack. // //************************************************************ SCODE CWBEMViewContainerCtrl::SetContainerContextEpilogue(CContainerContext& ctx) { m_bObjectIsNewlyCreated = ctx.m_bObjectIsNewlyCreated; m_bEmptyContainer = ctx.m_bEmptyContainer; m_pTitleBar->Refresh(); if (::IsWindow(ctx.m_hwndFocus) && ::IsWindowVisible(ctx.m_hwndFocus)) { ::SetFocus(ctx.m_hwndFocus); } return S_OK; } void CWBEMViewContainerCtrl::PushView() { m_pViewStack->PushView(); } void CWBEMViewContainerCtrl::UpdateViewContext() { m_pViewStack->UpdateView(); } DWORD CWBEMViewContainerCtrl::GetControlFlags( ) { return clipPaintDC; } //************************************************************ // CWBEMViewContainerCtrl::SelectView // // Select a sub-view. // // Parameters: // long lView // The view position returned from the view enumerator. // // Returns: // Nothing. // //************************************************************ void CWBEMViewContainerCtrl::SelectView(long lPosition) { SCODE sc; long lPositionCurrent = m_pview->StartViewEnumeration(VIEW_CURRENT); if (lPosition == lPositionCurrent) { return; } sc = m_pview->SelectView(lPosition); ASSERT(SUCCEEDED(sc)); m_pViewStack->PushView(); UpdateWindow(); } void CWBEMViewContainerCtrl::PassThroughGetIHmmServices (LPCTSTR lpctstrNamespace, VARIANT FAR* pvarUpdatePointer, VARIANT FAR* pvarServices, VARIANT FAR* pvarSC, VARIANT FAR* pvarUserCancel) { // TODO: Add your dispatch handler code here FireGetIWbemServices(lpctstrNamespace, pvarUpdatePointer, pvarServices, pvarSC, pvarUserCancel); } void CWBEMViewContainerCtrl::RequestUIActive() { // TODO: Add your control notification handler code here if(m_bCreationFinished) OnActivateInPlace(TRUE,NULL); FireRequestUIActive(); } void CWBEMViewContainerCtrl::OnSetFocus(CWnd* pOldWnd) { COleControl::OnSetFocus(pOldWnd); // Next statements are only logic I need to know how to draw myself // when I lose focus. Your logic may be more complicated. // You want to activate yourself. if (!m_bUIActive) { m_bUIActive = TRUE; RequestUIActive(); } InvalidateControl(); // Must do this! } void CWBEMViewContainerCtrl::OnKillFocus(CWnd* pNewWnd) { COleControl::OnKillFocus(pNewWnd); // TODO: Add your message handler code here // Next statements are only logic I need to know how to draw myself // when I lose focus. Your logic may be more complicated. // You want to deactivate yourself. m_bUIActive = FALSE; OnActivateInPlace(FALSE,NULL); // Must do this! InvalidateControl(); } //********************************************************** // CWBEMViewContainerCtrl::InvokeHelp // // Invoke help for the currently selected object. // // Parameters: // None. // // Returns: // Nothing. // //********************************************************** void CWBEMViewContainerCtrl::OnHelp() { COleVariant varObjectPath; CString sObjectPath; long lPos; if (m_pview->IsShowingSingleview()) { CSingleView* psv = m_pview->GetSingleView(); lPos = psv->StartObjectEnumeration(OBJECT_CURRENT); if (lPos >= 0) { varObjectPath = psv->GetObjectPath(lPos); sObjectPath = varObjectPath.bstrVal; } else { sObjectPath = m_varObjectPath.bstrVal; } } else { CMultiView* pmv = m_pview->GetMultiView(); lPos = pmv->StartObjectEnumeration(OBJECT_CURRENT); if (lPos >= 0) { varObjectPath = pmv->GetObjectPath(lPos); sObjectPath = varObjectPath.bstrVal; } else { sObjectPath = m_varObjectPath.bstrVal; } } m_pdlgHelpBox->ShowHelpForClass(this, sObjectPath); } void CWBEMViewContainerCtrl::InvokeHelp() { OnHelp(); return; } BOOL CWBEMViewContainerCtrl::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class dwStyle |= WS_CLIPCHILDREN; return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } BOOL CWBEMViewContainerCtrl::OnEraseBkgnd(CDC* pDC) { CRect rcClient; GetClientRect(rcClient); CBrush br(GetSysColor(COLOR_3DFACE)); pDC->FillRect(rcClient, &br); return TRUE; // return COleControl::OnEraseBkgnd(pDC); } BOOL CWBEMViewContainerCtrl::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class switch(pMsg->message) { case WM_KEYDOWN: case WM_SYSKEYDOWN: switch(pMsg->wParam) { case VK_TAB: // When you see the tab key in your control's pretranslate // message you know that IE is telling you to go ui active // and allowing you to give your control focus because the // user just tabbed into your control. A vb form // behaves the same way. SetFocus(); return FALSE; break; } break; } BOOL bDidTranslate; bDidTranslate = COleControl::PreTranslateMessage(pMsg); if (bDidTranslate) { return bDidTranslate; } // bug #51022 - Should call PreTranslateMessage, not PreTranslateInput return COleControl::PreTranslateMessage (pMsg); } long CWBEMViewContainerCtrl::GetPropertyFilter() { return m_lPropFilters; } //********************************************************** // CWBEMViewContainerCtrl::SetPropertyFilters // // Invoke help for the currently selected object. // // Parameters: // [in] lPropFilters // PROPFILTER_SYSTEM 1 // PROPFILTER_INHERITED 2 // PROPFILTER_LOCAL 4 // // // Returns: // Nothing. // //********************************************************** void CWBEMViewContainerCtrl::SetPropertyFilter(long nNewValue) { m_lPropFilters = nNewValue; if (m_pview != NULL) { m_pview->SetPropertyFilters(nNewValue); } } CWnd* CWBEMViewContainerCtrl::ReestablishFocus() { if (m_pview != NULL) { CWnd* pwndFocusPrev = m_pview->SetFocus(); return pwndFocusPrev; } return NULL; } void CWBEMViewContainerCtrl::GetWbemServices(LPCTSTR szNamespace, VARIANT FAR* pvarUpdatePointer, VARIANT FAR* pvarServices, VARIANT FAR* pvarSc, VARIANT FAR* pvarUserCancel) { FireGetIWbemServices(szNamespace, pvarUpdatePointer, pvarServices, pvarSc, pvarUserCancel); } //********************************************************** // CWBEMViewContainerCtrl::Query // // Display query dialog and run query // // //********************************************************** void CWBEMViewContainerCtrl::Query() { // Save the state of the current object before attempting to // run the query. CWaitCursor wait; BOOL bSwitchViewChecked = m_pTitleBar->IsButtonChecked(ID_CMD_SWITCH_VIEW); BOOL bWasShowingSingleView = m_pview->IsShowingSingleview(); BOOL bWasNewlyCreatedInst = FALSE; CString sClassPath; CSingleView* psv = m_pview->GetSingleView(); SCODE sc = S_OK; if (m_pview->IsShowingSingleview()) { // Save the state only if we are flipping from the // singleview to the multiview. This prevents a // the save from being done when a new object is // pre-selected into the singleview prior to displaying // it so that things appear quickly. sc = SaveState(TRUE, TRUE); if (FAILED(sc)) { m_pTitleBar->CheckButton(ID_CMD_SWITCH_VIEW, FALSE); return; } else if (sc == WBEM_S_FALSE) { // The user chose not to save changes when flipping to the // multiview. This means that we need to reselect the // current path into the singleview so that we revert back // to the initial state of the object. CString sObjectPath; sObjectPath = m_varObjectPath.bstrVal; psv->SelectObjectByPath(sObjectPath); } if (m_bObjectIsNewlyCreated) { bWasNewlyCreatedInst = TRUE; sClassPath = m_sNewInstClassPath; } } //Now, execute the query CDlgExecQuery dlg(this); int iResult = (int) dlg.DoModal(); if (iResult == IDOK) { CMultiView* pmv = m_pview->GetMultiView(); pmv->QueryViewInstances(dlg.m_sQueryName, _T("WQL"), dlg.m_sQueryString, _T("")); ShowMultiView(TRUE, TRUE); } if (bWasShowingSingleView && bWasNewlyCreatedInst) { if (sc == WBEM_S_FALSE && !sClassPath.IsEmpty()) { // The user chose not to save the newly created instance, so // we need to select the class so that when the user sees the // multiview, the create instance button will be enabled // if appropriate. psv->SelectObjectByPath(m_sNewInstClassPath); m_pViewStack->UpdateView(); m_bObjectIsNewlyCreated = FALSE; m_sNewInstClassPath.Empty(); } } else { m_pViewStack->PushView(); } m_pTitleBar->Refresh(); UpdateWindow(); }