// This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif #define new DEBUG_NEW ///////////////////////////////////////////////////////////////////////////// // COleCmdUI class COleCmdUI::COleCmdUI(OLECMD* rgCmds, ULONG cCmds, const GUID* pGroup) { m_rgCmds = rgCmds; m_nIndexMax = cCmds; m_pguidCmdGroup = pGroup; } void COleCmdUI::Enable(BOOL bOn) { if (m_rgCmds != NULL) { ASSERT(m_nIndex < m_nIndexMax); if (bOn) m_rgCmds[m_nIndex].cmdf |= OLECMDF_ENABLED; else m_rgCmds[m_nIndex].cmdf &= ~OLECMDF_ENABLED; m_bEnableChanged = TRUE; } } void COleCmdUI::SetCheck(int nCheck) { if (m_rgCmds != NULL) { ASSERT(m_nIndex < m_nIndexMax); m_rgCmds[m_nIndex].cmdf &= ~(OLECMDF_LATCHED|OLECMDF_NINCHED); if (nCheck == 1) m_rgCmds[m_nIndex].cmdf |= OLECMDF_LATCHED; else if (nCheck == 2) m_rgCmds[m_nIndex].cmdf |= OLECMDF_NINCHED; } } void COleCmdUI::SetText(LPCTSTR lpszText) { m_strText = lpszText; } BOOL COleCmdUI::DoUpdate(CCmdTarget* pTarget, BOOL bDisableIfNoHandler) { BOOL bResult; ASSERT_VALID(pTarget); // fire off an OLECOMMNAD message to translate the OLECMD ID // to a real WM_COMMAND ID via the message maps // if we find a translation, fire a UPDATE_COMMAND_UI request to // see if the command should be enabled or not m_bEnableChanged = FALSE; bResult = pTarget->OnCmdMsg(m_nID, CN_OLECOMMAND, this, NULL); if (!bResult) ASSERT(!m_bEnableChanged); else bResult = pTarget->OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI, this, NULL); if (bDisableIfNoHandler && !m_bEnableChanged) { AFX_CMDHANDLERINFO info; info.pTarget = NULL; bResult = pTarget->OnCmdMsg(m_nID, CN_COMMAND, this, &info); if (bResult || m_bEnableChanged) m_rgCmds[m_nIndex].cmdf |= OLECMDF_SUPPORTED; else m_rgCmds[m_nIndex].cmdf &= ~OLECMDF_SUPPORTED; Enable(bResult); } else { if (m_bEnableChanged) m_rgCmds[m_nIndex].cmdf |= OLECMDF_SUPPORTED; else m_rgCmds[m_nIndex].cmdf &= ~OLECMDF_SUPPORTED; } return bResult; } ///////////////////////////////////////////////////////////////////////////// // IOleCommandTarget implementation STDMETHODIMP_(ULONG) CDocObjectServer::XOleCommandTarget::AddRef() { METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget) return pThis->m_pOwner->ExternalAddRef(); } STDMETHODIMP_(ULONG) CDocObjectServer::XOleCommandTarget::Release() { METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget) return pThis->m_pOwner->ExternalRelease(); } STDMETHODIMP CDocObjectServer::XOleCommandTarget::QueryInterface( REFIID iid, LPVOID* ppvObj) { METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget) return pThis->m_pOwner->ExternalQueryInterface(&iid, ppvObj); } HRESULT AFXAPI _AfxQueryStatusOleCommandHelper(CCmdTarget* pTarget, const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT* pcmdtext) { HRESULT hr = E_POINTER; if (rgCmds != NULL) { hr = NOERROR; if (pTarget == NULL) { ULONG nIndex; for (nIndex = 0; nIndex < cCmds; nIndex++) rgCmds[nIndex].cmdf = 0; } else { COleCmdUI state(rgCmds, cCmds, pguidCmdGroup); if (pcmdtext == NULL) state.m_nCmdTextFlag = 0; else state.m_nCmdTextFlag = pcmdtext->cmdtextf; for (state.m_nIndex = 0; state.m_nIndex < cCmds; state.m_nIndex++) { state.m_nID = rgCmds[state.m_nIndex].cmdID; state.DoUpdate(pTarget, TRUE); } if (pcmdtext != NULL && pcmdtext->rgwz != NULL && (pcmdtext->cmdtextf != OLECMDTEXTF_NONE)) { USES_CONVERSION; ASSERT(cCmds == 1); state.m_strText = state.m_strText.Right(pcmdtext->cwBuf-1); pcmdtext->cwActual = state.m_strText.GetLength(); #ifdef _UNICODE lstrcpyW(pcmdtext->rgwz, (LPCTSTR) state.m_strText); #elif defined(OLE2ANSI) lstrcpy(pcmdtext->rgwz, state.m_strText); #else lstrcpyW(pcmdtext->rgwz, T2W((LPCTSTR) state.m_strText)); #endif } } } return hr; } STDMETHODIMP CDocObjectServer::XOleCommandTarget::QueryStatus( const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT* pcmdtext) { METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget) ASSERT_VALID(pThis); COleDocIPFrameWnd* pFrame = pThis->GetControllingFrame(); return _AfxQueryStatusOleCommandHelper(pFrame, pguidCmdGroup, cCmds, rgCmds, pcmdtext); } HRESULT AFXAPI _AfxExecOleCommandHelper(CCmdTarget* pTarget, const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG* pvarargIn, VARIANTARG* pvarargOut) { HRESULT hr = OLECMDERR_E_NOHELP; UNUSED(pvarargIn); UNUSED(pvarargOut); #ifdef _DEBUG // MFC doesn't support commands with arguments // You must handle argument commands by overriding OnExecOleCmd() if (pvarargIn != NULL || pvarargOut != NULL) TRACE1("Warning: IOleCommandTarget::Exec() received parameterized command #%d\n", nCmdID); #endif if (pTarget != NULL) { OLECMD cmd; COleCmdUI state(&cmd, 1, pguidCmdGroup); state.m_nIndex = 0; cmd.cmdf = 0; cmd.cmdID = nCmdID; state.m_nID = nCmdID; // help via Doc Object targeting is not supported if (nCmdExecOpt == OLECMDEXECOPT_SHOWHELP) hr = OLECMDERR_E_DISABLED; else { // is the command supported? if (!state.DoUpdate(pTarget, TRUE)) hr = OLECMDERR_E_NOTSUPPORTED; else { if (cmd.cmdf & OLECMDF_ENABLED) { if (pTarget->OnCmdMsg(state.m_nID, CN_COMMAND, NULL, NULL)) hr = S_OK; else hr = E_FAIL; } else hr = OLECMDERR_E_DISABLED; } } } return hr; } STDMETHODIMP CDocObjectServer::XOleCommandTarget::Exec( const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG* pvarargIn, VARIANTARG* pvarargOut) { METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget) ASSERT_VALID(pThis); // Offer the command to the document, first HRESULT hr = pThis->OnExecOleCmd(pguidCmdGroup, nCmdID, nCmdExecOpt, pvarargIn, pvarargOut); if (hr == E_NOTIMPL) { COleDocIPFrameWnd* pFrame = pThis->GetControllingFrame(); hr = _AfxExecOleCommandHelper(pFrame, pguidCmdGroup, nCmdID, nCmdExecOpt, pvarargIn, pvarargOut); } return hr; }