Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
9.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: mmcctrl.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // MMCCtrl.cpp : Implementation of CMMCCtrl
  11. #include "stdafx.h"
  12. #include "cic.h"
  13. #include "MMCCtrl.h"
  14. #include "MMCTask.h"
  15. #include "DispObj.h"
  16. #include "MMClpi.h"
  17. #include "amcmsgid.h"
  18. #include "findview.h"
  19. #include "strings.h"
  20. void CMMCCtrl::DoConnect ()
  21. {
  22. // if we're not connected...
  23. if (m_spTaskPadHost == NULL) {
  24. HWND hwnd = FindMMCView(*dynamic_cast<CComControlBase*>(this));
  25. if (hwnd)
  26. Connect (hwnd);
  27. }
  28. }
  29. void CMMCCtrl::Connect (HWND wndCurrent)
  30. {
  31. HWND hwndView = FindMMCView(wndCurrent);
  32. if (hwndView)
  33. {
  34. // get the control's IUnknown
  35. IUnknownPtr spunk;
  36. ControlQueryInterface (IID_IUnknown, (void **)&spunk);
  37. if (spunk != NULL)
  38. {
  39. IUnknownPtr spunkMMC;
  40. ::SendMessage (hwndView, MMC_MSG_CONNECT_TO_CIC, (WPARAM)&spunkMMC, (LPARAM)(spunk.GetInterfacePtr()));
  41. if (spunkMMC != NULL)
  42. m_spTaskPadHost = spunkMMC;
  43. }
  44. }
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CMMCCtrl
  48. HRESULT CMMCCtrl::OnDraw(ATL_DRAWINFO& di)
  49. {
  50. if (m_spTaskPadHost == NULL) {
  51. // get window from di and find console window
  52. HWND wndCurrent = WindowFromDC (di.hdcDraw);
  53. if (wndCurrent)
  54. Connect (wndCurrent);
  55. }
  56. return S_OK;
  57. }
  58. HRESULT CMMCCtrl::OnDrawAdvanced(ATL_DRAWINFO & di)
  59. {
  60. return OnDraw (di);
  61. }
  62. STDMETHODIMP CMMCCtrl::TaskNotify(BSTR szClsid, VARIANT * pvArg, VARIANT * pvParam)
  63. {
  64. DoConnect(); // connect, if not already connected
  65. if(m_spTaskPadHost != NULL)
  66. return m_spTaskPadHost->TaskNotify (szClsid, pvArg, pvParam);
  67. return E_FAIL;
  68. }
  69. STDMETHODIMP CMMCCtrl::GetFirstTask(BSTR szTaskGroup, IDispatch** retval)
  70. { // called by script, when it wants buttons, etc.
  71. // validate parameters
  72. _ASSERT (retval);
  73. _ASSERT (!IsBadWritePtr(retval, sizeof(IDispatch*)));
  74. // TODO: how do I validate a BSTR?
  75. if (retval == NULL || IsBadWritePtr(retval, sizeof(IDispatch*)))
  76. return E_INVALIDARG;
  77. // should be initialized to this already (see note below)
  78. *retval = NULL;
  79. DoConnect(); // connect, if not already connected
  80. if (m_spTaskPadHost == NULL) // from note above:
  81. return S_OK; // any error, pops up ugly script message box....
  82. // "reset": if we have an old enumerator, blitz it.
  83. if (m_spEnumTASK != NULL)
  84. m_spEnumTASK = NULL;
  85. // get new enumerator
  86. m_spTaskPadHost->GetTaskEnumerator (szTaskGroup, &m_spEnumTASK);
  87. if(m_spEnumTASK != NULL)
  88. return GetNextTask (retval);
  89. return S_OK;
  90. }
  91. STDMETHODIMP CMMCCtrl::GetNextTask(IDispatch** retval)
  92. {
  93. // validate parameters
  94. _ASSERT (retval);
  95. _ASSERT (!IsBadWritePtr(retval, sizeof(IDispatch*)));
  96. if (retval == NULL || IsBadWritePtr(retval, sizeof(IDispatch*)))
  97. return E_INVALIDARG;
  98. if (m_spEnumTASK == NULL)
  99. return S_OK; // all outa enumerators
  100. MMC_ITASK task;
  101. ZeroMemory (&task, sizeof(MMC_ITASK));
  102. HRESULT hresult = m_spEnumTASK->Next (1, (MMC_TASK *)&task, NULL);
  103. if (hresult != S_OK) {
  104. // out of tasks (and enumerators): no need to hang onto this any more.
  105. m_spEnumTASK = NULL;
  106. return S_OK;
  107. } else {
  108. // convert MMC_ITASK to ITask object
  109. CComObject<class CMMCTask>* ctask = NULL;
  110. hresult = CComObject<CMMCTask>::CreateInstance(&ctask);
  111. if (ctask) {
  112. ctask->SetText (task.task.szText);
  113. ctask->SetHelp (task.task.szHelpString);
  114. ctask->SetClsid(task.szClsid);
  115. hresult = ctask->SetDisplayObject (&task.task.sDisplayObject);
  116. if (hresult == S_OK) {
  117. switch (task.task.eActionType) {
  118. case MMC_ACTION_ID:
  119. hresult = ctask->SetCommandID (task.task.nCommandID);
  120. break;
  121. case MMC_ACTION_LINK:
  122. hresult = ctask->SetActionURL (task.task.szActionURL);
  123. break;
  124. case MMC_ACTION_SCRIPT:
  125. hresult = ctask->SetScript (task.task.szScript);
  126. break;
  127. default:
  128. _ASSERT (FALSE); // bad task
  129. hresult = E_UNEXPECTED;
  130. break;
  131. }
  132. }
  133. if (SUCCEEDED(hresult))
  134. ctask->QueryInterface (IID_IDispatch, (void **)retval);
  135. else
  136. delete ctask;
  137. }
  138. }
  139. FreeDisplayData (&task.task.sDisplayObject);
  140. if (task.task.szText) CoTaskMemFree (task.task.szText);
  141. if (task.task.szHelpString) CoTaskMemFree (task.task.szHelpString);
  142. if (task.szClsid) CoTaskMemFree (task.szClsid);
  143. if (task.task.eActionType != MMC_ACTION_ID)
  144. if (task.task.szScript)
  145. CoTaskMemFree (task.task.szScript);
  146. return S_OK;
  147. }
  148. STDMETHODIMP CMMCCtrl::GetTitle(BSTR szTaskGroup, BSTR * retval)
  149. {
  150. DoConnect(); // connect, if not already connected
  151. if (m_spTaskPadHost)
  152. m_spTaskPadHost->GetTitle (szTaskGroup, retval);
  153. return S_OK;
  154. }
  155. STDMETHODIMP CMMCCtrl::GetDescriptiveText(BSTR szTaskGroup, BSTR * retval)
  156. {
  157. DoConnect(); // connect, if not already connected
  158. if (m_spTaskPadHost)
  159. m_spTaskPadHost->GetDescriptiveText (szTaskGroup, retval);
  160. return S_OK;
  161. }
  162. STDMETHODIMP CMMCCtrl::GetBackground(BSTR szTaskGroup, IDispatch** retval)
  163. {
  164. DoConnect(); // connect, if not already connected
  165. *retval = NULL;
  166. if (m_spTaskPadHost) {
  167. MMC_TASK_DISPLAY_OBJECT tdo;
  168. ZeroMemory (&tdo, sizeof(tdo));
  169. // pass struct to host (which will pass to snapin)
  170. m_spTaskPadHost->GetBackground (szTaskGroup, &tdo);
  171. // convert struct to IDispatch object
  172. CComObject<class CMMCDisplayObject>* cdo = NULL;
  173. CComObject<CMMCDisplayObject>::CreateInstance(&cdo);
  174. if (cdo) {
  175. cdo->Init (&tdo);
  176. IDispatchPtr spIDispatch = cdo;
  177. if (*retval = spIDispatch)
  178. spIDispatch.Detach();
  179. }
  180. FreeDisplayData (&tdo);
  181. }
  182. return S_OK;
  183. }
  184. /*
  185. STDMETHODIMP CMMCCtrl::GetBranding(BSTR szTaskGroup, IDispatch** retval)
  186. {
  187. DoConnect(); // connect, if not already connected
  188. *retval = NULL;
  189. if (m_spTaskPadHost) {
  190. MMC_TASK_DISPLAY_OBJECT tdo;
  191. ZeroMemory (&tdo, sizeof(tdo));
  192. // pass struct to host (which will pass to snapin)
  193. m_spTaskPadHost->GetBranding (szTaskGroup, &tdo);
  194. // convert struct to IDispatch object
  195. CComObject<class CMMCDisplayObject>* cdo = NULL;
  196. CComObject<CMMCDisplayObject>::CreateInstance(&cdo);
  197. if (cdo) {
  198. cdo->AddRef();
  199. cdo->Init (&tdo);
  200. cdo->QueryInterface (IID_IDispatch, (void **)retval);
  201. cdo->Release();
  202. }
  203. FreeDisplayData (&tdo);
  204. }
  205. return S_OK;
  206. }
  207. */
  208. STDMETHODIMP CMMCCtrl::GetListPadInfo (BSTR szGroup, IDispatch** retval)
  209. {
  210. *retval = NULL;
  211. DoConnect(); // connect, if not already connected
  212. if (m_spTaskPadHost == NULL)
  213. return S_OK;
  214. MMC_ILISTPAD_INFO ilpi;
  215. ZeroMemory (&ilpi, sizeof(MMC_ILISTPAD_INFO));
  216. m_spTaskPadHost->GetListPadInfo (szGroup, &ilpi);
  217. // convert struct to IDispatch
  218. CComObject<class CMMCListPadInfo>* clpi = NULL;
  219. HRESULT hr = CComObject<CMMCListPadInfo>::CreateInstance(&clpi);
  220. if (clpi) {
  221. // always set clsid, title, button text, even if NULL or empty strings
  222. if (ilpi.szClsid)
  223. hr = clpi->SetClsid (ilpi.szClsid);
  224. if (hr == S_OK && ilpi.info.szTitle)
  225. hr = clpi->SetTitle (ilpi.info.szTitle);
  226. if (hr == S_OK)
  227. hr = clpi->SetNotifyID (ilpi.info.nCommandID);
  228. if (hr == S_OK && ilpi.info.szButtonText)
  229. hr = clpi->SetText (ilpi.info.szButtonText);
  230. // NULL button text => no button
  231. // empty button text => button without any text
  232. if (hr == S_OK)
  233. hr = clpi->SetHasButton (ilpi.info.szButtonText != NULL);
  234. if (SUCCEEDED(hr))
  235. clpi->QueryInterface (IID_IDispatch, (void **)retval);
  236. else
  237. delete clpi;
  238. }
  239. // free resources
  240. if (ilpi.szClsid) CoTaskMemFree (ilpi.szClsid);
  241. if (ilpi.info.szTitle) CoTaskMemFree (ilpi.info.szTitle);
  242. if (ilpi.info.szButtonText) CoTaskMemFree (ilpi.info.szButtonText);
  243. return S_OK;
  244. }
  245. void CMMCCtrl::FreeDisplayData (MMC_TASK_DISPLAY_OBJECT* pdo)
  246. {
  247. switch (pdo->eDisplayType) {
  248. default:
  249. break;
  250. case MMC_TASK_DISPLAY_TYPE_SYMBOL:
  251. if (pdo->uSymbol.szFontFamilyName) CoTaskMemFree (pdo->uSymbol.szFontFamilyName);
  252. if (pdo->uSymbol.szURLtoEOT) CoTaskMemFree (pdo->uSymbol.szURLtoEOT);
  253. if (pdo->uSymbol.szSymbolString) CoTaskMemFree (pdo->uSymbol.szSymbolString);
  254. break;
  255. case MMC_TASK_DISPLAY_TYPE_BITMAP:
  256. case MMC_TASK_DISPLAY_TYPE_VANILLA_GIF:
  257. case MMC_TASK_DISPLAY_TYPE_CHOCOLATE_GIF:
  258. if (pdo->uBitmap.szMouseOverBitmap) CoTaskMemFree (pdo->uBitmap.szMouseOverBitmap);
  259. if (pdo->uBitmap.szMouseOffBitmap) CoTaskMemFree (pdo->uBitmap.szMouseOffBitmap);
  260. break;
  261. }
  262. }