oledoctg.cpp 6.6 KB

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