Leaked source code of windows server 2003
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.

303 lines
8.3 KiB

  1. #include "stdafx.h"
  2. #include "Ctrl.h"
  3. #include "Extension.h"
  4. #if ENABLE_MSGTABLE_API
  5. /***************************************************************************\
  6. *****************************************************************************
  7. *
  8. * class DuExtension
  9. *
  10. *****************************************************************************
  11. \***************************************************************************/
  12. static const GUID guidAysncDestroy = { 0xbfe02331, 0xc17d, 0x45ea, { 0x96, 0x35, 0xa0, 0x7a, 0x90, 0x37, 0xfe, 0x34 } }; // {BFE02331-C17D-45ea-9635-A07A9037FE34}
  13. MSGID DuExtension::s_msgidAsyncDestroy = 0;
  14. /***************************************************************************\
  15. *
  16. * DuExtension::~DuExtension
  17. *
  18. * ~DuExtension() checks that resources were properly cleaned up before the
  19. * DuExtension was destroyed.
  20. *
  21. \***************************************************************************/
  22. DuExtension::~DuExtension()
  23. {
  24. //
  25. // Ensure proper destruction
  26. //
  27. }
  28. //------------------------------------------------------------------------------
  29. HRESULT
  30. DuExtension::InitClass()
  31. {
  32. s_msgidAsyncDestroy = RegisterGadgetMessage(&guidAysncDestroy);
  33. return s_msgidAsyncDestroy != 0 ? S_OK : (HRESULT) GetLastError();
  34. }
  35. /***************************************************************************\
  36. *
  37. * DuExtension::Create
  38. *
  39. * Create() initializes a new DuExtension and attaches it to the subject Gadget
  40. * being modified.
  41. *
  42. \***************************************************************************/
  43. HRESULT
  44. DuExtension::Create(
  45. IN Visual * pgvSubject, // Gadget being "extended"
  46. IN PRID pridExtension, // Short ID for DuExtension
  47. IN UINT nOptions) // Options
  48. {
  49. AssertMsg(pridExtension > 0, "Must have valid PRID");
  50. //
  51. // Do not allow attaching a DuExtension to a Gadget that has already started
  52. // the destruction process.
  53. //
  54. HGADGET hgadSubject = DUserCastHandle(pgvSubject);
  55. BOOL fStartDelete;
  56. if ((!IsStartDelete(hgadSubject, &fStartDelete)) || fStartDelete) {
  57. return DU_E_STARTDESTROY;
  58. }
  59. //
  60. // Setup options
  61. //
  62. m_fAsyncDestroy = TestFlag(nOptions, oAsyncDestroy);
  63. //
  64. // Determine if this DuExtension is already attached to the Gadget being
  65. // extended.
  66. //
  67. DuExtension * pbExist;
  68. if (SUCCEEDED(pgvSubject->GetProperty(pridExtension, (void **) &pbExist))) {
  69. AssertMsg(pbExist != NULL, "Existing Extension must not be NULL");
  70. if (TestFlag(nOptions, oUseExisting)) {
  71. return DU_S_ALREADYEXISTS;
  72. } else {
  73. //
  74. // Already attached, but can't use the existing one. We need to
  75. // remove the existing DuExtension before attaching the new one.
  76. // After calling RemoveExisting(), the DuExtension should no longer
  77. // be attached to the Gadget.
  78. //
  79. pbExist->GetStub()->OnRemoveExisting();
  80. Assert(FAILED(pgvSubject->GetProperty(pridExtension, (void **) &pbExist)));
  81. }
  82. }
  83. //
  84. // Setup a listener to be notifyed when the RootGadget is destroyed.
  85. //
  86. HRESULT hr = S_OK;
  87. m_pgvSubject = pgvSubject;
  88. m_pridListen = pridExtension;
  89. if (FAILED(pgvSubject->SetProperty(pridExtension, this)) ||
  90. FAILED(pgvSubject->AddHandlerG(GM_DESTROY, GetStub()))) {
  91. hr = E_OUTOFMEMORY;
  92. goto Error;
  93. }
  94. //
  95. // Successfully created the DuExtension
  96. //
  97. return S_OK;
  98. Error:
  99. return hr;
  100. }
  101. /***************************************************************************\
  102. *
  103. * DuExtension::Destroy
  104. *
  105. * Destroy() is called from the derived class to cleanup resources associated
  106. * with the DuExtension.
  107. *
  108. \***************************************************************************/
  109. void
  110. DuExtension::Destroy()
  111. {
  112. //
  113. // Since the DuExtension is being destroyed, need to ensure that it is no
  114. // longer "attached" to the Gadget being extended
  115. //
  116. if ((m_pridListen != 0) && (m_pgvSubject != NULL)) {
  117. DuExtension * pb;
  118. if (SUCCEEDED(m_pgvSubject->GetProperty(m_pridListen, (void **) &pb))) {
  119. if (pb == this) {
  120. m_pgvSubject->RemoveProperty(m_pridListen);
  121. }
  122. }
  123. }
  124. Delete();
  125. }
  126. /***************************************************************************\
  127. *
  128. * DuExtension::DeleteHandle
  129. *
  130. * DeleteHandle() starts the destruction process for the DuExtension.
  131. *
  132. \***************************************************************************/
  133. void
  134. DuExtension::DeleteHandle()
  135. {
  136. Delete();
  137. }
  138. //------------------------------------------------------------------------------
  139. HRESULT
  140. DuExtension::ApiOnEvent(EventMsg * pmsg)
  141. {
  142. switch (GET_EVENT_DEST(pmsg))
  143. {
  144. case GMF_DIRECT:
  145. if (m_fAsyncDestroy && (pmsg->nMsg == s_msgidAsyncDestroy)) {
  146. GetStub()->OnAsyncDestroy();
  147. return DU_S_PARTIAL;
  148. }
  149. break;
  150. case GMF_EVENT:
  151. if (pmsg->nMsg == GM_DESTROY) {
  152. if (((GMSG_DESTROY *) pmsg)->nCode == GDESTROY_FINAL) {
  153. GetStub()->OnDestroySubject();
  154. return DU_S_PARTIAL;
  155. }
  156. }
  157. break;
  158. }
  159. return SListener::ApiOnEvent(pmsg);
  160. }
  161. /***************************************************************************\
  162. *
  163. * DuExtension::ApiOnRemoveExisting
  164. *
  165. * ApiOnRemoveExisting() is called when creating a new DuExtension to remove
  166. * an existing DuExtension already attached to the subject Gadget.
  167. *
  168. \***************************************************************************/
  169. HRESULT
  170. DuExtension::ApiOnRemoveExisting(Extension::OnRemoveExistingMsg *)
  171. {
  172. return S_OK;
  173. }
  174. /***************************************************************************\
  175. *
  176. * DuExtension::ApiOnDestroySubject
  177. *
  178. * ApiOnDestroySubject() notifies the derived DuExtension that the subject
  179. * Gadget being modified has been destroyed.
  180. *
  181. \***************************************************************************/
  182. HRESULT
  183. DuExtension::ApiOnDestroySubject(Extension::OnDestroySubjectMsg *)
  184. {
  185. return S_OK;
  186. }
  187. /***************************************************************************\
  188. *
  189. * DuExtension::ApiOnAsyncDestroy
  190. *
  191. * ApiOnAsyncDestroy() is called when the DuExtension receives an asynchronous
  192. * destruction message that was previously posted. This provides the derived
  193. * DuExtension an opportunity to start the destruction process without being
  194. * nested several levels.
  195. *
  196. \***************************************************************************/
  197. HRESULT
  198. DuExtension::ApiOnAsyncDestroy(Extension::OnAsyncDestroyMsg *)
  199. {
  200. return S_OK;
  201. }
  202. /***************************************************************************\
  203. *
  204. * DuExtension::PostAsyncDestroy
  205. *
  206. * PostAsyncDestroy() queues an asynchronous destruction message. This
  207. * provides the derived DuExtension an opportunity to start the destruction
  208. * process without being nested several levels.
  209. *
  210. \***************************************************************************/
  211. void
  212. DuExtension::PostAsyncDestroy()
  213. {
  214. AssertMsg(m_fAsyncDestroy,
  215. "Must create DuExtension with oAsyncDestroy if want to destroy asynchronously");
  216. Assert(s_msgidAsyncDestroy != 0);
  217. EventMsg msg;
  218. ZeroMemory(&msg, sizeof(msg));
  219. msg.cbSize = sizeof(msg);
  220. msg.hgadMsg = GetHandle();
  221. msg.nMsg = s_msgidAsyncDestroy;
  222. DUserPostEvent(&msg, 0);
  223. }
  224. /***************************************************************************\
  225. *
  226. * DuExtension::GetExtension
  227. *
  228. * GetExtension() retrieves the DuExtension of a specific type currently
  229. * attached to the subject Gadget.
  230. *
  231. \***************************************************************************/
  232. DuExtension *
  233. DuExtension::GetExtension(Visual * pgvSubject, PRID prid)
  234. {
  235. DuExtension * pbExist;
  236. if (SUCCEEDED(pgvSubject->GetProperty(prid, (void **) &pbExist))) {
  237. AssertMsg(pbExist != NULL, "Attached DuExtension must be valid");
  238. return pbExist;
  239. }
  240. return NULL;
  241. }
  242. #endif // ENABLE_MSGTABLE_API