home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / oledoctg.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  7KB  |  260 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef _DEBUG
  14. #undef THIS_FILE
  15. static char BASED_CODE THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. #define new DEBUG_NEW
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // COleCmdUI class
  22.  
  23. COleCmdUI::COleCmdUI(OLECMD* rgCmds, ULONG cCmds, const GUID* pGroup)
  24. {
  25.     m_rgCmds = rgCmds;
  26.     m_nIndexMax = cCmds;
  27.     m_pguidCmdGroup = pGroup;
  28. }
  29.  
  30. void COleCmdUI::Enable(BOOL bOn)
  31. {
  32.    if (m_rgCmds != NULL)
  33.    {
  34.       ASSERT(m_nIndex < m_nIndexMax);
  35.  
  36.       if (bOn)
  37.          m_rgCmds[m_nIndex].cmdf |= OLECMDF_ENABLED;
  38.       else
  39.          m_rgCmds[m_nIndex].cmdf &= ~OLECMDF_ENABLED;
  40.       m_bEnableChanged = TRUE;
  41.    }
  42. }
  43.  
  44. void COleCmdUI::SetCheck(int nCheck)
  45. {
  46.    if (m_rgCmds != NULL)
  47.    {
  48.       ASSERT(m_nIndex < m_nIndexMax);
  49.  
  50.       m_rgCmds[m_nIndex].cmdf &= ~(OLECMDF_LATCHED|OLECMDF_NINCHED);
  51.       if (nCheck == 1)
  52.          m_rgCmds[m_nIndex].cmdf |= OLECMDF_LATCHED;
  53.       else if (nCheck == 2)
  54.          m_rgCmds[m_nIndex].cmdf |= OLECMDF_NINCHED;
  55.    }
  56. }
  57.  
  58. void COleCmdUI::SetText(LPCTSTR lpszText)
  59. {
  60.     m_strText = lpszText;
  61. }
  62.  
  63. BOOL COleCmdUI::DoUpdate(CCmdTarget* pTarget, BOOL bDisableIfNoHandler)
  64. {
  65.    BOOL bResult;
  66.    ASSERT_VALID(pTarget);
  67.  
  68.     // fire off an OLECOMMNAD message to translate the OLECMD ID
  69.     // to a real WM_COMMAND ID via the message maps
  70.     // if we find a translation, fire a UPDATE_COMMAND_UI request to
  71.     // see if the command should be enabled or not
  72.  
  73.    m_bEnableChanged = FALSE;
  74.    bResult = pTarget->OnCmdMsg(m_nID, CN_OLECOMMAND, this, NULL);
  75.    if (!bResult)
  76.       ASSERT(!m_bEnableChanged);
  77.    else
  78.       bResult = pTarget->OnCmdMsg(m_nID, CN_UPDATE_COMMAND_UI, this, NULL);
  79.  
  80.    if (bDisableIfNoHandler && !m_bEnableChanged)
  81.    {
  82.       AFX_CMDHANDLERINFO info;
  83.       info.pTarget = NULL;
  84.       bResult = pTarget->OnCmdMsg(m_nID, CN_COMMAND, this, &info);
  85.  
  86.       if (bResult || m_bEnableChanged)
  87.          m_rgCmds[m_nIndex].cmdf |= OLECMDF_SUPPORTED;
  88.       else
  89.          m_rgCmds[m_nIndex].cmdf &= ~OLECMDF_SUPPORTED;
  90.       Enable(bResult);
  91.    }
  92.    else
  93.    {
  94.       if (m_bEnableChanged)
  95.          m_rgCmds[m_nIndex].cmdf |= OLECMDF_SUPPORTED;
  96.       else
  97.          m_rgCmds[m_nIndex].cmdf &= ~OLECMDF_SUPPORTED;
  98.    }
  99.    return bResult;
  100. }
  101.  
  102. /////////////////////////////////////////////////////////////////////////////
  103. // IOleCommandTarget implementation
  104.  
  105. STDMETHODIMP_(ULONG) CDocObjectServer::XOleCommandTarget::AddRef()
  106. {
  107.     METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget)
  108.     return pThis->m_pOwner->ExternalAddRef();
  109. }
  110.  
  111. STDMETHODIMP_(ULONG) CDocObjectServer::XOleCommandTarget::Release()
  112. {
  113.     METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget)
  114.     return pThis->m_pOwner->ExternalRelease();
  115. }
  116.  
  117. STDMETHODIMP CDocObjectServer::XOleCommandTarget::QueryInterface(
  118.     REFIID iid, LPVOID* ppvObj)
  119. {
  120.     METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget)
  121.     return pThis->m_pOwner->ExternalQueryInterface(&iid, ppvObj);
  122. }
  123.  
  124. HRESULT AFXAPI _AfxQueryStatusOleCommandHelper(CCmdTarget* pTarget,
  125.    const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[],
  126.    OLECMDTEXT* pcmdtext)
  127. {
  128.     HRESULT hr = E_POINTER;
  129.  
  130.     if (rgCmds != NULL)
  131.     {
  132.         hr = NOERROR;
  133.         if (pTarget == NULL)
  134.         {
  135.             ULONG nIndex;
  136.             for (nIndex = 0; nIndex < cCmds; nIndex++)
  137.                 rgCmds[nIndex].cmdf = 0;
  138.         }
  139.         else
  140.         {
  141.             COleCmdUI state(rgCmds, cCmds, pguidCmdGroup);
  142.             if (pcmdtext == NULL)
  143.                 state.m_nCmdTextFlag = 0;
  144.             else
  145.                 state.m_nCmdTextFlag = pcmdtext->cmdtextf;
  146.             for (state.m_nIndex = 0; state.m_nIndex < cCmds; state.m_nIndex++)
  147.             {
  148.                 state.m_nID = rgCmds[state.m_nIndex].cmdID;
  149.                 state.DoUpdate(pTarget, TRUE);
  150.             }
  151.  
  152.             if (pcmdtext != NULL && pcmdtext->rgwz != NULL &&
  153.                 (pcmdtext->cmdtextf != OLECMDTEXTF_NONE))
  154.             {
  155.                 USES_CONVERSION;
  156.                 ASSERT(cCmds == 1);
  157.                 state.m_strText = state.m_strText.Right(pcmdtext->cwBuf-1);
  158.                 pcmdtext->cwActual = state.m_strText.GetLength();
  159.  
  160. #ifdef _UNICODE
  161.                 lstrcpyW(pcmdtext->rgwz, (LPCTSTR) state.m_strText);
  162. #elif defined(OLE2ANSI)
  163.                 lstrcpy(pcmdtext->rgwz, state.m_strText);
  164. #else
  165.                 lstrcpyW(pcmdtext->rgwz, T2W((LPCTSTR) state.m_strText));
  166. #endif
  167.             }
  168.         }
  169.     }
  170.  
  171.     return hr;
  172. }
  173.  
  174. STDMETHODIMP CDocObjectServer::XOleCommandTarget::QueryStatus(
  175.    const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[],
  176.    OLECMDTEXT* pcmdtext)
  177. {
  178.     METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget)
  179.     ASSERT_VALID(pThis);
  180.  
  181.     COleDocIPFrameWnd* pFrame = pThis->GetControllingFrame();
  182.     return _AfxQueryStatusOleCommandHelper(pFrame,
  183.         pguidCmdGroup, cCmds, rgCmds, pcmdtext);
  184. }
  185.  
  186. HRESULT AFXAPI _AfxExecOleCommandHelper(CCmdTarget* pTarget,
  187.    const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
  188.    VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
  189. {
  190.     HRESULT hr = OLECMDERR_E_NOHELP;
  191.  
  192.     UNUSED(pvarargIn);
  193.     UNUSED(pvarargOut);
  194. #ifdef _DEBUG
  195.     // MFC doesn't support commands with arguments
  196.     // You must handle argument commands by overriding OnExecOleCmd()
  197.  
  198.     if (pvarargIn != NULL || pvarargOut != NULL)
  199.         TRACE1("Warning: IOleCommandTarget::Exec() received parameterized command #%d\n", nCmdID);
  200. #endif
  201.  
  202.     if (pTarget != NULL)
  203.     {
  204.         OLECMD cmd;
  205.  
  206.         COleCmdUI state(&cmd, 1, pguidCmdGroup);
  207.         state.m_nIndex = 0;
  208.         cmd.cmdf = 0;
  209.         cmd.cmdID = nCmdID;
  210.         state.m_nID = nCmdID;
  211.  
  212.         // help via Doc Object targeting is not supported
  213.  
  214.         if (nCmdExecOpt == OLECMDEXECOPT_SHOWHELP)
  215.             hr = OLECMDERR_E_DISABLED;
  216.         else
  217.         {
  218.             // is the command supported?
  219.  
  220.             if (!state.DoUpdate(pTarget, TRUE))
  221.                 hr = OLECMDERR_E_NOTSUPPORTED;
  222.             else
  223.             {
  224.                 if (cmd.cmdf & OLECMDF_ENABLED)
  225.                 {
  226.                     if (pTarget->OnCmdMsg(state.m_nID, CN_COMMAND, NULL, NULL))
  227.                         hr = S_OK;
  228.                     else
  229.                         hr = E_FAIL;
  230.                 }
  231.                 else
  232.                     hr = OLECMDERR_E_DISABLED;
  233.             }
  234.         }
  235.     }
  236.  
  237.     return hr;
  238. }
  239.  
  240. STDMETHODIMP CDocObjectServer::XOleCommandTarget::Exec(
  241.    const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
  242.    VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
  243. {
  244.     METHOD_PROLOGUE_EX(CDocObjectServer, OleCommandTarget)
  245.     ASSERT_VALID(pThis);
  246.  
  247.     // Offer the command to the document, first
  248.  
  249.     HRESULT hr = pThis->OnExecOleCmd(pguidCmdGroup, nCmdID,
  250.             nCmdExecOpt, pvarargIn, pvarargOut);
  251.     if (hr == E_NOTIMPL)
  252.     {
  253.         COleDocIPFrameWnd* pFrame = pThis->GetControllingFrame();
  254.         hr = _AfxExecOleCommandHelper(pFrame,
  255.             pguidCmdGroup, nCmdID, nCmdExecOpt, pvarargIn, pvarargOut);
  256.     }
  257.  
  258.     return hr;
  259. }
  260.