ATLBUTTON.H
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // AtlButton.h : Declaration of the CAtlButton
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12. #include "resource.h"       // main symbols
  13. #include "dibapi.h"
  14. #include "cpatlbutn.h"
  15. //////////////////////////////////////////////////////////////////////////////////////////////////
  16. // CTimer
  17. template <class Derived, class T, const IID* piid>
  18. class CTimer
  19. {
  20. public:
  21. CTimer()
  22. {
  23. m_bTimerOn = FALSE;
  24. }
  25. HRESULT TimerOn(DWORD dwTimerInterval)
  26. {
  27. Derived* pDerived = ((Derived*)this);
  28. m_dwTimerInterval = dwTimerInterval;
  29. if (m_bTimerOn) // already on, just change interval
  30. return S_OK;
  31. m_bTimerOn = TRUE;
  32. m_dwTimerInterval = dwTimerInterval;
  33. m_pStream = NULL;
  34. HRESULT hRes;
  35. hRes = CoMarshalInterThreadInterfaceInStream(*piid, (T*)pDerived, &m_pStream);
  36. // Create thread and pass the thread proc the this ptr
  37. m_hThread = CreateThread(NULL, 0, &_Apartment, (void*)this, 0, &m_dwThreadID);
  38. return S_OK;
  39. }
  40. void TimerOff()
  41. {
  42. if (m_bTimerOn)
  43. {
  44. m_bTimerOn = FALSE;
  45. AtlWaitWithMessageLoop(m_hThread);
  46. }
  47. }
  48. // Implementation
  49. private:
  50. static DWORD WINAPI _Apartment(void* pv)
  51. {
  52. CTimer<Derived, T, piid>* pThis = (CTimer<Derived, T, piid>*) pv;
  53. pThis->Apartment();
  54. return 0;
  55. }
  56. DWORD Apartment()
  57. {
  58. CoInitialize(NULL);
  59. HRESULT hRes;
  60. m_spT.Release();
  61. if (m_pStream)
  62. hRes = CoGetInterfaceAndReleaseStream(m_pStream, *piid, (void**)&m_spT);
  63. while(m_bTimerOn)
  64. {
  65. Sleep(m_dwTimerInterval);
  66. if (!m_bTimerOn)
  67. break;
  68. m_spT->_OnTimer();
  69. }
  70. m_spT.Release();
  71. CoUninitialize();
  72. return 0;
  73. }
  74. // Attributes
  75. public:
  76. DWORD m_dwTimerInterval;
  77. // Implementation
  78. private:
  79. HANDLE m_hThread;
  80. DWORD m_dwThreadID;
  81. LPSTREAM m_pStream;
  82. CComPtr<T> m_spT;
  83. BOOL m_bTimerOn;
  84. };
  85. /////////////////////////////////////////////////////////////////////////////
  86. // CAtlButton
  87. class CAtlButton :
  88. public CComObjectRoot,
  89. public CTimer<CAtlButton, IAtlButton, &IID_IAtlButton>,
  90. public CComCoClass<CAtlButton,&CLSID_CAtlButton>,
  91. public CComControl<CAtlButton>,
  92. public IDispatchImpl<IAtlButton, &IID_IAtlButton, &LIBID_ATLBUTNLib>,
  93. public IPersistStreamInitImpl<CAtlButton>,
  94. public IOleControlImpl<CAtlButton>,
  95. public IOleObjectImpl<CAtlButton>,
  96. public IOleInPlaceActiveObjectImpl<CAtlButton>,
  97. public IViewObjectExImpl<CAtlButton>,
  98. public IOleInPlaceObjectWindowlessImpl<CAtlButton>,
  99. public IProvideClassInfo2Impl<&CLSID_CAtlButton, &DIID__ATLButton, &LIBID_ATLBUTNLib>,
  100. public IPersistPropertyBagImpl<CAtlButton>,
  101. public IConnectionPointContainerImpl<CAtlButton>,
  102. public CProxy_ATLButton<CAtlButton>,
  103. public IObjectSafetyImpl<CAtlButton, INTERFACESAFE_FOR_UNTRUSTED_CALLER>
  104. {
  105. public:
  106. CAtlButton()
  107. {
  108. m_nEntry = 0;
  109. m_hDIB[0] = NULL;
  110. m_hDIB[1] = NULL;
  111. m_hDIB[2] = NULL;
  112. m_hPal[0] = NULL;
  113. m_hPal[1] = NULL;
  114. m_hPal[2] = NULL;
  115. }
  116. DECLARE_REGISTRY_RESOURCEID(IDR_AtlButton)
  117. BEGIN_COM_MAP(CAtlButton)
  118. COM_INTERFACE_ENTRY(IDispatch)
  119. COM_INTERFACE_ENTRY(IAtlButton)
  120. COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  121. COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  122. COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  123. COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  124. COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
  125. COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
  126. COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  127. COM_INTERFACE_ENTRY_IMPL(IOleControl)
  128. COM_INTERFACE_ENTRY_IMPL(IOleObject)
  129. COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
  130. COM_INTERFACE_ENTRY(IProvideClassInfo)
  131. COM_INTERFACE_ENTRY(IProvideClassInfo2)
  132. COM_INTERFACE_ENTRY_IMPL_IID(IID_IPersist, IPersistPropertyBag)
  133. COM_INTERFACE_ENTRY_IMPL(IPersistPropertyBag)
  134. COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
  135. COM_INTERFACE_ENTRY(IObjectSafety)
  136. END_COM_MAP()
  137. BEGIN_PROPERTY_MAP(CAtlButton)
  138. PROP_ENTRY("Static_Image", 0, CLSID_NULL)
  139. PROP_ENTRY("Hover_Image", 1, CLSID_NULL)
  140. PROP_ENTRY("Push_Image", 2, CLSID_NULL)
  141. END_PROPERTY_MAP()
  142. BEGIN_CONNECTION_POINT_MAP(CAtlButton)
  143. CONNECTION_POINT_ENTRY(DIID__ATLButton)
  144. END_CONNECTION_POINT_MAP()
  145. BEGIN_MSG_MAP(CAtlButton)
  146. MESSAGE_HANDLER(WM_ERASEBKGND, OnErase)
  147. MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
  148. MESSAGE_HANDLER(WM_LBUTTONDOWN, OnButtonDown)
  149. MESSAGE_HANDLER(WM_LBUTTONUP, OnButtonUp)
  150. MESSAGE_HANDLER(WM_PAINT, OnPaint)
  151. END_MSG_MAP()
  152. LRESULT OnErase(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  153. {
  154. return 0;
  155. }
  156. LRESULT OnButtonDown(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  157. {
  158. m_nEntry = 2;
  159. FireViewChange();
  160. OnClick();
  161. return 0;
  162. }
  163. LRESULT OnButtonUp(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  164. {
  165. m_nEntry = 1;
  166. FireViewChange();
  167. OnClick();
  168. return 0;
  169. }
  170. LRESULT OnMouseMove(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  171. {
  172. if (m_nEntry == 0)
  173. {
  174. m_nEntry = 1;
  175. FireViewChange();
  176. }
  177. return 0;
  178. }
  179. // IAtlButton
  180. public:
  181. CComBSTR m_bstrFilename[3];
  182. RECT m_rcDIB[3];
  183. HDIB m_hDIB[3];
  184. HPALETTE m_hPal[3];
  185. int m_nEntry;
  186. void PutImage(BSTR strFilename, int nEntry)
  187. {
  188. USES_CONVERSION;
  189. m_bstrFilename[nEntry] = strFilename;
  190. if (m_hDIB[nEntry])
  191. GlobalFree(m_hDIB[nEntry]);
  192. if (m_hPal[nEntry])
  193. GlobalFree(m_hPal[nEntry]);
  194. m_hDIB[nEntry] = NULL;
  195. m_hPal[nEntry] = NULL;
  196. m_hDIB[nEntry] = ReadDIBFile(OLE2T(strFilename));
  197. if (m_hDIB[nEntry])
  198. {
  199. CreateDIBPalette(m_hDIB[nEntry], &m_hPal[nEntry]);
  200. LPSTR pDIB = (LPSTR)GlobalLock(m_hDIB[nEntry]);
  201. m_rcDIB[nEntry].left = 0;
  202. m_rcDIB[nEntry].top = 0;
  203. m_rcDIB[nEntry].right = DIBWidth(pDIB);
  204. m_rcDIB[nEntry].bottom = DIBHeight(pDIB);
  205. GlobalUnlock((HGLOBAL)m_hDIB[nEntry]);
  206. }
  207. }
  208. STDMETHOD(put_ImageStatic)(BSTR strFilename)
  209. {
  210. PutImage(strFilename, 0);
  211. return S_OK;
  212. }
  213. STDMETHOD(get_ImageStatic)(BSTR* pstrFilename)
  214. {
  215. *pstrFilename = m_bstrFilename[0].Copy();
  216. return S_OK;
  217. }
  218. STDMETHOD(put_ImageHover)(BSTR strFilename)
  219. {
  220. PutImage(strFilename, 1);
  221. return S_OK;
  222. }
  223. STDMETHOD(get_ImageHover)(BSTR* pstrFilename)
  224. {
  225. *pstrFilename = m_bstrFilename[1].Copy();
  226. return S_OK;
  227. }
  228. STDMETHOD(put_ImagePush)(BSTR strFilename)
  229. {
  230. PutImage(strFilename, 2);
  231. return S_OK;
  232. }
  233. STDMETHOD(get_ImagePush)(BSTR* pstrFilename)
  234. {
  235. *pstrFilename = m_bstrFilename[2].Copy();
  236. return S_OK;
  237. }
  238. STDMETHOD(_OnTimer)()
  239. {
  240. POINT pos;
  241. GetCursorPos(&pos);
  242. if (m_bInPlaceActive)
  243. {
  244. HWND hwnd;
  245. m_spInPlaceSite->GetWindow(&hwnd);
  246. ::ScreenToClient(hwnd, &pos);
  247. if (!PtInRect(&m_rcPos, pos))
  248. {
  249. if (m_nEntry > 0)
  250. {
  251. m_nEntry = 0;
  252. FireViewChange();
  253. }
  254. }
  255. }
  256. return S_OK;
  257. }
  258. HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL)
  259. {
  260. HRESULT hr;
  261. hr = CComControl<CAtlButton>::InPlaceActivate(iVerb, prcPosRect);
  262. TimerOn(250);
  263. return hr;
  264. }
  265. STDMETHOD(InPlaceDeactivate)(void)
  266. {
  267. TimerOff();
  268. return IOleInPlaceObjectWindowlessImpl<CAtlButton>::InPlaceDeactivate();
  269. }
  270. HRESULT OnDraw(ATL_DRAWINFO& di)
  271. {
  272. USES_CONVERSION;
  273. if (m_hDIB[m_nEntry])
  274. {
  275. HPALETTE hPal = SelectPalette(di.hdcDraw, m_hPal[m_nEntry], TRUE);
  276. RealizePalette(di.hdcDraw);
  277. PaintDIB(di.hdcDraw, (LPRECT) di.prcBounds, m_hDIB[m_nEntry], &m_rcDIB[m_nEntry], m_hPal[m_nEntry]);
  278. SelectPalette(di.hdcDraw, hPal, TRUE);
  279. }
  280. return 0;
  281. }
  282. STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
  283. {
  284. if (dwAspect == DVASPECT_CONTENT)
  285. {
  286. *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  287. if (m_nEntry == 0)
  288. {
  289. m_nEntry = 1;
  290. FireViewChange();
  291. }
  292. return S_OK;
  293. }
  294. ATLTRACE(_T("Wrong DVASPECTn"));
  295. return E_FAIL;
  296. }
  297. };