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.

212 lines
6.1 KiB

  1. #if !defined(CTRL__SmGadget_h__INCLUDED)
  2. #define CTRL__SmGadget_h__INCLUDED
  3. #pragma once
  4. #include <SmObject.h>
  5. namespace Gdiplus
  6. {
  7. class Graphics;
  8. };
  9. /***************************************************************************\
  10. *
  11. * class SmGadget
  12. *
  13. * SmGadget provides a core implementation of a simple gadget and is used as
  14. * as base for all of the simple gadget controls in DUser.
  15. *
  16. \***************************************************************************/
  17. class SmGadget
  18. {
  19. // Construction
  20. protected:
  21. SmGadget();
  22. virtual ~SmGadget();
  23. BOOL PostBuild();
  24. public:
  25. // Operations
  26. public:
  27. __declspec(property(get=RawGetHandle)) HGADGET h;
  28. HGADGET RawGetHandle() const { return m_hgad; }
  29. virtual HRESULT GadgetProc(EventMsg * pmsg);
  30. virtual void OnDraw(HDC hdc, GMSG_PAINTRENDERI * pmsgR)
  31. { UNREFERENCED_PARAMETER(hdc); UNREFERENCED_PARAMETER(pmsgR); }
  32. #ifdef GADGET_ENABLE_GDIPLUS
  33. virtual void OnDraw(Gdiplus::Graphics * pgpgr, GMSG_PAINTRENDERF * pmsgR)
  34. { UNREFERENCED_PARAMETER(pgpgr); UNREFERENCED_PARAMETER(pmsgR); }
  35. #endif // GADGET_ENABLE_GDIPLUS
  36. void Invalidate();
  37. // Data
  38. protected:
  39. HGADGET m_hgad;
  40. };
  41. #define GBEGIN_COM_MAP(x) \
  42. STDMETHODIMP \
  43. QueryInterface(REFIID riid, void ** ppv) \
  44. { \
  45. if (ppv == NULL) { \
  46. return E_POINTER; \
  47. } \
  48. if (IsEqualIID(riid, __uuidof(IUnknown)) || \
  49. #define GCOM_INTERFACE_ENTRY(x) \
  50. IsEqualIID(riid, __uuidof(x))) { \
  51. \
  52. x * p = (x *) this; \
  53. p->AddRef(); \
  54. *ppv = p; \
  55. return S_OK; \
  56. } \
  57. \
  58. if ( \
  59. #define GEND_COM_MAP() \
  60. 0) { } \
  61. return E_NOINTERFACE; \
  62. } \
  63. /***************************************************************************\
  64. *
  65. * class SmGadgetFull
  66. *
  67. * SmGadgetFull is a "Mix-in" (see Design Patterns) class designed for
  68. * providing SmGadget's with a standard COM-class implementation. Creation
  69. * of SmGadget instances should derive from this class at the point of
  70. * creation.
  71. *
  72. \***************************************************************************/
  73. template <class base, class iface>
  74. class SmGadgetFull : public base
  75. {
  76. public:
  77. static SmGadgetFull<base, iface> *
  78. Build(HGADGET hgadParent, REFIID riid = __uuidof(IUnknown), void ** ppvUnk = NULL)
  79. {
  80. return CommonBuild(new SmGadgetFull<base, iface>, hgadParent, riid, ppvUnk);
  81. }
  82. static SmGadgetFull<base, iface> *
  83. CommonBuild(SmGadgetFull<base, iface> * pgadNew, HGADGET hgadParent, REFIID riid, void ** ppvUnk)
  84. {
  85. if (pgadNew == NULL) {
  86. return NULL;
  87. }
  88. pgadNew->m_cRef = 1;
  89. HGADGET hgad = CreateGadget(hgadParent, GC_SIMPLE, SmGadgetFull<base, iface>::RawGadgetProc, pgadNew);
  90. if (hgad == NULL) {
  91. pgadNew->Release();
  92. return NULL;
  93. }
  94. pgadNew->m_hgad = hgad;
  95. if (!pgadNew->PostBuild()) {
  96. // Delete from parent and destroy
  97. ::DeleteHandle(hgad);
  98. pgadNew->Release();
  99. return NULL;
  100. }
  101. if (ppvUnk != NULL) {
  102. pgadNew->QueryInterface(riid, ppvUnk);
  103. }
  104. return pgadNew;
  105. }
  106. // Implementation
  107. protected:
  108. inline
  109. SmGadgetFull()
  110. {
  111. }
  112. static HRESULT CALLBACK
  113. RawGadgetProc(HGADGET hgadCur, void * pvCur, EventMsg * pmsg)
  114. {
  115. UNREFERENCED_PARAMETER(hgadCur);
  116. AssertReadPtrSize(pmsg, pmsg->cbSize);
  117. SmGadgetFull<base, iface> * p = (SmGadgetFull<base, iface> *) pvCur;
  118. AssertMsg(hgadCur == p->m_hgad, "Ensure correct gadget");
  119. if (p->m_hgad == pmsg->hgadMsg) {
  120. switch (pmsg->nMsg)
  121. {
  122. case GM_DESTROY:
  123. {
  124. GMSG_DESTROY * pmsgD = (GMSG_DESTROY *) pmsg;
  125. if (pmsgD->nCode == GDESTROY_FINAL) {
  126. //
  127. // When getting a GM_DESTROY message, Release() and return
  128. // immediately. The base class should put its cleanup code in
  129. // its destructor.
  130. //
  131. p->Release();
  132. return DU_S_PARTIAL;
  133. }
  134. }
  135. break;
  136. case GM_QUERY:
  137. {
  138. GMSG_QUERY * pmsgQ = (GMSG_QUERY *) pmsg;
  139. if (pmsgQ->nCode == GQUERY_INTERFACE) {
  140. GMSG_QUERYINTERFACE * pmsgQI = (GMSG_QUERYINTERFACE *) pmsg;
  141. pmsgQI->punk = (iface *) p;
  142. return DU_S_COMPLETE;
  143. }
  144. }
  145. break;
  146. }
  147. }
  148. return p->GadgetProc(pmsg);
  149. }
  150. STDMETHODIMP_(ULONG)
  151. AddRef()
  152. {
  153. return ++m_cRef;
  154. }
  155. STDMETHODIMP_(ULONG)
  156. Release()
  157. {
  158. ULONG ul = --m_cRef;
  159. if (ul == 0) {
  160. delete this;
  161. }
  162. return ul;
  163. }
  164. STDMETHODIMP_(HGADGET)
  165. GetHandle() const
  166. {
  167. return m_hgad;
  168. }
  169. // Data
  170. protected:
  171. ULONG m_cRef;
  172. };
  173. #include "SmGadget.inl"
  174. #endif // CTRL__SmGadget_h__INCLUDED